xref: /trunk/main/forms/source/component/imgprod.cxx (revision 24acc546)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_forms.hxx"
26 
27 #include "imgprod.hxx"
28 
29 #include <vcl/bmpacc.hxx>
30 #include <vcl/cvtgrf.hxx>
31 #include <vcl/svapp.hxx>
32 #include <unotools/ucbstreamhelper.hxx>
33 #include <svtools/filter.hxx>
34 #include <com/sun/star/io/XInputStream.hpp>
35 
36 #ifndef SVTOOLS_SOURCE_MISC_IMAGERESOURCEACCESS_HXX
37 #include "svtools/imageresourceaccess.hxx"
38 #endif
39 #include <comphelper/processfactory.hxx>
40 
41 // --------------------
42 // - ImgProdLockBytes -
43 // --------------------
44 
45 class ImgProdLockBytes : public SvLockBytes
46 {
47 	::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > 		xStmRef;
48 	::com::sun::star::uno::Sequence<sal_Int8>		maSeq;
49 
ImgProdLockBytes()50 						ImgProdLockBytes() {};
51 
52 public:
53 
54 						ImgProdLockBytes( SvStream* pStm, sal_Bool bOwner );
55 						ImgProdLockBytes( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & rStreamRef );
56 	virtual				~ImgProdLockBytes();
57 
58 	virtual ErrCode		ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const;
59 	virtual ErrCode		WriteAt( sal_Size nPos, const void* pBuffer, sal_Size nCount, sal_Size* pWritten );
60 	virtual ErrCode		Flush() const;
61 	virtual ErrCode		SetSize( sal_Size nSize );
62 	virtual ErrCode		Stat( SvLockBytesStat*, SvLockBytesStatFlag ) const;
63 };
64 
65 // ------------------------------------------------------------------------
66 
ImgProdLockBytes(SvStream * pStm,sal_Bool bOwner)67 ImgProdLockBytes::ImgProdLockBytes( SvStream* pStm, sal_Bool bOwner ) :
68 		SvLockBytes( pStm, bOwner )
69 {
70 }
71 
72 // ------------------------------------------------------------------------
73 
ImgProdLockBytes(::com::sun::star::uno::Reference<::com::sun::star::io::XInputStream> & rStmRef)74 ImgProdLockBytes::ImgProdLockBytes( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & rStmRef ) :
75 		xStmRef( rStmRef )
76 {
77 	if( xStmRef.is() )
78 	{
79 		const sal_uInt32	nBytesToRead = 65535;
80 		sal_uInt32			nRead;
81 
82 		do
83 		{
84 			::com::sun::star::uno::Sequence< sal_Int8 > aReadSeq;
85 
86 			nRead = xStmRef->readSomeBytes( aReadSeq, nBytesToRead );
87 
88 			if( nRead )
89 			{
90 				const sal_uInt32 nOldLength = maSeq.getLength();
91 				maSeq.realloc( nOldLength + nRead );
92 				rtl_copyMemory( maSeq.getArray() + nOldLength, aReadSeq.getConstArray(), aReadSeq.getLength() );
93 			}
94 		}
95 		while( nBytesToRead == nRead );
96 	}
97 }
98 
99 // ------------------------------------------------------------------------
100 
~ImgProdLockBytes()101 ImgProdLockBytes::~ImgProdLockBytes()
102 {
103 }
104 
105 // ------------------------------------------------------------------------
106 
ReadAt(sal_Size nPos,void * pBuffer,sal_Size nCount,sal_Size * pRead) const107 ErrCode ImgProdLockBytes::ReadAt( sal_Size nPos, void* pBuffer, sal_Size nCount, sal_Size* pRead ) const
108 {
109 	if( GetStream() )
110 	{
111 		( (SvStream*) GetStream() )->ResetError();
112 		const ErrCode nErr = SvLockBytes::ReadAt( nPos, pBuffer, nCount, pRead );
113 		( (SvStream*) GetStream() )->ResetError();
114 		return nErr;
115 	}
116 	else
117 	{
118 		const sal_Size nSeqLen = maSeq.getLength();
119 		ErrCode nErr = ERRCODE_NONE;
120 
121 		if( nPos < nSeqLen )
122 		{
123 			if( ( nPos + nCount ) > nSeqLen )
124 				nCount = nSeqLen - nPos;
125 
126 			memcpy( pBuffer, maSeq.getConstArray() + nPos, nCount );
127 			*pRead = nCount;
128 		}
129 		else
130 			*pRead = 0UL;
131 
132 		return nErr;
133 	}
134 }
135 
136 // ------------------------------------------------------------------------
137 
WriteAt(sal_Size nPos,const void * pBuffer,sal_Size nCount,sal_Size * pWritten)138 ErrCode ImgProdLockBytes::WriteAt( sal_Size nPos, const void* pBuffer, sal_Size nCount, sal_Size* pWritten )
139 {
140 	if( GetStream() )
141 		return SvLockBytes::WriteAt( nPos, pBuffer, nCount, pWritten );
142 	else
143 	{
144 		DBG_ASSERT( xStmRef.is(), "ImgProdLockBytes::WriteAt: xInputStream has no reference..." );
145 		return ERRCODE_IO_CANTWRITE;
146 	}
147 }
148 
149 // ------------------------------------------------------------------------
150 
Flush() const151 ErrCode ImgProdLockBytes::Flush() const
152 {
153 	return ERRCODE_NONE;
154 }
155 
156 // ------------------------------------------------------------------------
157 
SetSize(sal_Size nSize)158 ErrCode ImgProdLockBytes::SetSize( sal_Size nSize )
159 {
160 	if( GetStream() )
161 		return SvLockBytes::SetSize( nSize );
162 	else
163 	{
164 		DBG_ERROR( "ImgProdLockBytes::SetSize not supported for xInputStream..." );
165 		return ERRCODE_IO_CANTWRITE;
166 	}
167 }
168 
169 // ------------------------------------------------------------------------
170 
Stat(SvLockBytesStat * pStat,SvLockBytesStatFlag eFlag) const171 ErrCode ImgProdLockBytes::Stat( SvLockBytesStat* pStat, SvLockBytesStatFlag eFlag ) const
172 {
173 	if( GetStream() )
174 		return SvLockBytes::Stat( pStat, eFlag );
175 	else
176 	{
177 		DBG_ASSERT( xStmRef.is(), "ImgProdLockBytes::Stat: xInputStream has no reference..." );
178 		pStat->nSize = maSeq.getLength();
179 		return ERRCODE_NONE;
180 	}
181 }
182 
183 // -----------------
184 // - ImageProducer -
185 // -----------------
186 
ImageProducer()187 ImageProducer::ImageProducer() :
188 	mpStm		( NULL ),
189 	mbConsInit	( sal_False )
190 {
191 	mpGraphic = new Graphic;
192 	DBG_ASSERT( Application::GetFilterHdl().IsSet(), "ImageProducer::ImageProducer(): No filter handler set" );
193 }
194 
195 // ------------------------------------------------------------
196 
~ImageProducer()197 ImageProducer::~ImageProducer()
198 {
199 	delete mpGraphic;
200 	mpGraphic = NULL;
201 
202 	delete mpStm;
203 	mpStm = NULL;
204 
205 	for( void* pCons = maConsList.First(); pCons; pCons = maConsList.Next() )
206 		delete (::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons;
207 }
208 
209 // ------------------------------------------------------------
210 
211 // ::com::sun::star::uno::XInterface
queryInterface(const::com::sun::star::uno::Type & rType)212 ::com::sun::star::uno::Any ImageProducer::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
213 {
214 	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
215 										SAL_STATIC_CAST( ::com::sun::star::lang::XInitialization*, this ),
216 										SAL_STATIC_CAST( ::com::sun::star::awt::XImageProducer*, this ) );
217 	return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
218 }
219 
220 // ------------------------------------------------------------
221 
addConsumer(const::com::sun::star::uno::Reference<::com::sun::star::awt::XImageConsumer> & rxConsumer)222 void ImageProducer::addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& rxConsumer ) throw(::com::sun::star::uno::RuntimeException)
223 {
224 	DBG_ASSERT( rxConsumer.is(), "::AddConsumer(...): No consumer referenced!" );
225 	if( rxConsumer.is() )
226 		maConsList.Insert( new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > ( rxConsumer ), LIST_APPEND );
227 }
228 
229 // ------------------------------------------------------------
230 
removeConsumer(const::com::sun::star::uno::Reference<::com::sun::star::awt::XImageConsumer> & rxConsumer)231 void ImageProducer::removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& rxConsumer ) throw(::com::sun::star::uno::RuntimeException)
232 {
233 	for( sal_uInt32 n = maConsList.Count(); n; )
234 	{
235 		::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > * pRef = (::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) maConsList.GetObject( --n );
236 
237 		if( *pRef == rxConsumer )
238 		{
239 			delete pRef;
240 			maConsList.Remove( n );
241 			break;
242 		}
243 	}
244 }
245 
246 // ------------------------------------------------------------
247 
SetImage(const::rtl::OUString & rPath)248 void ImageProducer::SetImage( const ::rtl::OUString& rPath )
249 {
250 	maURL = rPath;
251 	mpGraphic->Clear();
252 	mbConsInit = sal_False;
253 	delete mpStm;
254 
255     if ( ::svt::GraphicAccess::isSupportedURL( maURL ) )
256     {
257         mpStm = ::svt::GraphicAccess::getImageStream( ::comphelper::getProcessServiceFactory(), maURL );
258     }
259     else if( maURL.getLength() )
260 	{
261 		SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_STD_READ );
262 		mpStm = pIStm ? new SvStream( new ImgProdLockBytes( pIStm, sal_True ) ) : NULL;
263 	}
264 	else
265 		mpStm = NULL;
266 }
267 
268 // ------------------------------------------------------------
269 
SetImage(SvStream & rStm)270 void ImageProducer::SetImage( SvStream& rStm )
271 {
272 	maURL = ::rtl::OUString();
273 	mpGraphic->Clear();
274 	mbConsInit = sal_False;
275 
276 	delete mpStm;
277 	mpStm = new SvStream( new ImgProdLockBytes( &rStm, sal_False ) );
278 }
279 
280 // ------------------------------------------------------------
281 
setImage(::com::sun::star::uno::Reference<::com::sun::star::io::XInputStream> & rInputStmRef)282 void ImageProducer::setImage( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > & rInputStmRef )
283 {
284 	maURL = ::rtl::OUString();
285 	mpGraphic->Clear();
286 	mbConsInit = sal_False;
287 	delete mpStm;
288 
289 	if( rInputStmRef.is() )
290 		mpStm = new SvStream( new ImgProdLockBytes( rInputStmRef ) );
291 	else
292 		mpStm = NULL;
293 }
294 
295 // ------------------------------------------------------------
296 
NewDataAvailable()297 void ImageProducer::NewDataAvailable()
298 {
299 	if( ( GRAPHIC_NONE == mpGraphic->GetType() ) || mpGraphic->GetContext() )
300 		startProduction();
301 }
302 
303 // ------------------------------------------------------------
304 
startProduction()305 void ImageProducer::startProduction() throw(::com::sun::star::uno::RuntimeException)
306 {
307 	if( maConsList.Count() || maDoneHdl.IsSet() )
308 	{
309         bool bNotifyEmptyGraphics = false;
310 
311 		// valid stream or filled graphic? => update consumers
312 		if( mpStm || ( mpGraphic->GetType() != GRAPHIC_NONE ) )
313 		{
314 			// if we already have a graphic, we don't have to import again;
315 			// graphic is cleared if a new Stream is set
316 			if( ( mpGraphic->GetType() == GRAPHIC_NONE ) || mpGraphic->GetContext() )
317 			{
318 				if ( ImplImportGraphic( *mpGraphic ) && maDoneHdl.IsSet() )
319                     maDoneHdl.Call( mpGraphic );
320 			}
321 
322 			if( mpGraphic->GetType() != GRAPHIC_NONE )
323 				ImplUpdateData( *mpGraphic );
324             else
325                 bNotifyEmptyGraphics = true;
326 		}
327 		else
328             bNotifyEmptyGraphics = true;
329 
330         if ( bNotifyEmptyGraphics )
331 		{
332 			// reset image
333 			List	aTmp;
334 			void*	pCons;
335 
336 			// create temporary list to hold interfaces
337 			for( pCons = maConsList.First(); pCons; pCons = maConsList.Next() )
338 				aTmp.Insert( new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > ( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons ), LIST_APPEND );
339 
340 			// iterate through interfaces
341 			for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
342 			{
343 				( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->init( 0, 0 );
344 				( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->complete( ::com::sun::star::awt::ImageStatus::IMAGESTATUS_STATICIMAGEDONE, this );
345 			}
346 
347 			// delete interfaces in temporary list
348 			for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
349 				delete (::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons;
350 
351             if ( maDoneHdl.IsSet() )
352                 maDoneHdl.Call( NULL );
353 		}
354 	}
355 }
356 
357 // ------------------------------------------------------------
358 
ImplImportGraphic(Graphic & rGraphic)359 sal_Bool ImageProducer::ImplImportGraphic( Graphic& rGraphic )
360 {
361     if( ERRCODE_IO_PENDING == mpStm->GetError() )
362 		mpStm->ResetError();
363 
364 	mpStm->Seek( 0UL );
365 
366 	sal_Bool bRet = GraphicConverter::Import( *mpStm, rGraphic ) == ERRCODE_NONE;
367 
368 	if( ERRCODE_IO_PENDING == mpStm->GetError() )
369 		mpStm->ResetError();
370 
371 	return bRet;
372 }
373 
374 // ------------------------------------------------------------
375 
ImplUpdateData(const Graphic & rGraphic)376 void ImageProducer::ImplUpdateData( const Graphic& rGraphic )
377 {
378 	ImplInitConsumer( rGraphic );
379 
380 	if( mbConsInit && maConsList.Count() )
381 	{
382 		List	aTmp;
383 		void*	pCons;
384 
385 		ImplUpdateConsumer( rGraphic );
386 		mbConsInit = sal_False;
387 
388 		// create temporary list to hold interfaces
389 		for( pCons = maConsList.First(); pCons; pCons = maConsList.Next() )
390 			aTmp.Insert( new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > ( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons ), LIST_APPEND );
391 
392 		// iterate through interfaces
393 		for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
394 			( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->complete( ::com::sun::star::awt::ImageStatus::IMAGESTATUS_STATICIMAGEDONE, this );
395 
396 		// delete interfaces in temporary list
397 		for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
398 			delete (::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons;
399 	}
400 }
401 
402 // ------------------------------------------------------------
403 
ImplInitConsumer(const Graphic & rGraphic)404 void ImageProducer::ImplInitConsumer( const Graphic& rGraphic )
405 {
406 	Bitmap				aBmp( rGraphic.GetBitmapEx().GetBitmap() );
407 	BitmapReadAccess*	pBmpAcc = aBmp.AcquireReadAccess();
408 
409 	if(	pBmpAcc )
410 	{
411 		List             aTmp;
412 		void *           pCons;
413 		sal_uInt16       nPalCount = 0;
414 		sal_uInt32       nRMask = 0;
415 		sal_uInt32       nGMask = 0;
416 		sal_uInt32       nBMask = 0;
417 		sal_uInt32       nAMask = 0;
418 		::com::sun::star::uno::Sequence< sal_Int32 >	aRGBPal;
419 
420 		if( pBmpAcc->HasPalette() )
421 		{
422 			nPalCount = pBmpAcc->GetPaletteEntryCount();
423 
424 			if( nPalCount )
425 			{
426 				aRGBPal = ::com::sun::star::uno::Sequence< sal_Int32 >( nPalCount + 1 );
427 
428 				sal_Int32* pTmp = aRGBPal.getArray();
429 
430 				for( sal_uInt32 i = 0; i < nPalCount; i++, pTmp++ )
431 				{
432 					const BitmapColor& rCol = pBmpAcc->GetPaletteColor( (sal_uInt16) i );
433 
434 					*pTmp = ( (sal_Int32) rCol.GetRed() ) << (sal_Int32)(24L);
435 					*pTmp |= ( (sal_Int32) rCol.GetGreen() ) << (sal_Int32)(16L);
436 					*pTmp |= ( (sal_Int32) rCol.GetBlue() ) << (sal_Int32)(8L);
437 					*pTmp |= (sal_Int32)(0x000000ffL);
438 				}
439 
440 				if( rGraphic.IsTransparent() )
441 				{
442 					// append transparent entry
443 					*pTmp = (sal_Int32)(0xffffff00L);
444 					mnTransIndex = nPalCount;
445 					nPalCount++;
446 				}
447 				else
448 					mnTransIndex = 0;
449 
450 			}
451 		}
452 		else
453 		{
454 			nRMask = 0xff000000UL;
455 			nGMask = 0x00ff0000UL;
456 			nBMask = 0x0000ff00UL;
457 			nAMask = 0x000000ffUL;
458 		}
459 
460 		// create temporary list to hold interfaces
461 		for( pCons = maConsList.First(); pCons; pCons = maConsList.Next() )
462 			aTmp.Insert( new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > ( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons ), LIST_APPEND );
463 
464 		// iterate through interfaces
465 		for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
466 		{
467 			( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->init( pBmpAcc->Width(), pBmpAcc->Height() );
468 			( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->setColorModel( pBmpAcc->GetBitCount(),
469 													   aRGBPal, nRMask, nGMask, nBMask, nAMask );
470 		}
471 
472 		// delete interfaces in temporary list
473 		for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
474 			delete (::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons;
475 
476 		aBmp.ReleaseAccess( pBmpAcc );
477 		mbConsInit = sal_True;
478 	}
479 }
480 
481 // ------------------------------------------------------------
482 
ImplUpdateConsumer(const Graphic & rGraphic)483 void ImageProducer::ImplUpdateConsumer( const Graphic& rGraphic )
484 {
485 	BitmapEx			aBmpEx( rGraphic.GetBitmapEx() );
486 	Bitmap				aBmp( aBmpEx.GetBitmap() );
487 	BitmapReadAccess*	pBmpAcc = aBmp.AcquireReadAccess();
488 
489 	if( pBmpAcc )
490 	{
491 		List				aTmp;
492 		void*				pCons;
493 		Bitmap				aMask( aBmpEx.GetMask() );
494 		BitmapReadAccess*	pMskAcc = !!aMask ? aMask.AcquireReadAccess() : NULL;
495 		const long			nWidth = pBmpAcc->Width();
496 		const long			nHeight = pBmpAcc->Height();
497 		const long			nStartX = 0L;
498 		const long			nEndX = nWidth - 1L;
499 		const long			nStartY = 0L;
500 		const long			nEndY = nHeight - 1L;
501 		const long			nPartWidth = nEndX - nStartX + 1;
502 		const long			nPartHeight = nEndY - nStartY + 1;
503 
504 		if( !pMskAcc )
505 		{
506 			aMask = Bitmap( aBmp.GetSizePixel(), 1 );
507 			aMask.Erase( COL_BLACK );
508 			pMskAcc = aMask.AcquireReadAccess();
509 		}
510 
511 		// create temporary list to hold interfaces
512 		for( pCons = maConsList.First(); pCons; pCons = maConsList.Next() )
513 			aTmp.Insert( new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > ( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons ), LIST_APPEND );
514 
515 		if( pBmpAcc->HasPalette() )
516 		{
517 			const BitmapColor aWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
518 
519 			if( mnTransIndex < 256 )
520 			{
521 				::com::sun::star::uno::Sequence<sal_Int8>	aData( nPartWidth * nPartHeight );
522 				sal_Int8*									pTmp = aData.getArray();
523 
524 				for( long nY = nStartY; nY <= nEndY; nY++ )
525 				{
526 					for( long nX = nStartX; nX <= nEndX; nX++ )
527 					{
528 						if( pMskAcc->GetPixel( nY, nX ) == aWhite )
529 							*pTmp++ = sal::static_int_cast< sal_Int8 >(
530                                 mnTransIndex );
531 						else
532 							*pTmp++ = pBmpAcc->GetPixel( nY, nX ).GetIndex();
533 					}
534 				}
535 
536 				// iterate through interfaces
537 				for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
538 					( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->setPixelsByBytes( nStartX, nStartY, nPartWidth, nPartHeight,
539 																	   aData, 0UL, nPartWidth );
540 			}
541 			else
542 			{
543 				::com::sun::star::uno::Sequence<sal_Int32>	aData( nPartWidth * nPartHeight );
544 				sal_Int32*									pTmp = aData.getArray();
545 
546 				for( long nY = nStartY; nY <= nEndY; nY++ )
547 				{
548 					for( long nX = nStartX; nX <= nEndX; nX++ )
549 					{
550 						if( pMskAcc->GetPixel( nY, nX ) == aWhite )
551 							*pTmp++ = mnTransIndex;
552 						else
553 							*pTmp++ = pBmpAcc->GetPixel( nY, nX ).GetIndex();
554 					}
555 				}
556 
557 				// iterate through interfaces
558 				for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
559 					( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->setPixelsByLongs( nStartX, nStartY, nPartWidth, nPartHeight,
560 																	   aData, 0UL, nPartWidth );
561 			}
562 		}
563 		else
564 		{
565 			::com::sun::star::uno::Sequence<sal_Int32> 	aData( nPartWidth * nPartHeight );
566 			const BitmapColor							aWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
567 			sal_Int32*									pTmp = aData.getArray();
568 
569 			for( long nY = nStartY; nY <= nEndY; nY++ )
570 			{
571 				for( long nX = nStartX; nX <= nEndX; nX++, pTmp++ )
572 				{
573 					const BitmapColor aCol( pBmpAcc->GetPixel( nY, nX ) );
574 
575 					*pTmp = ( (sal_Int32) aCol.GetRed() ) << (sal_Int32)(24L);
576 					*pTmp |= ( (sal_Int32) aCol.GetGreen() ) << (sal_Int32)(16L);
577 					*pTmp |= ( (sal_Int32) aCol.GetBlue() ) << (sal_Int32)(8L);
578 
579 					if( pMskAcc->GetPixel( nY, nX ) != aWhite )
580 						*pTmp |= 0x000000ffUL;
581 				}
582 			}
583 
584 			// iterate through interfaces
585 			for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
586 				( *(::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons )->setPixelsByLongs( nStartX, nStartY, nPartWidth, nPartHeight,
587 																   aData, 0UL, nPartWidth );
588 		}
589 
590 		// delete interfaces in temporary list
591 		for( pCons = aTmp.First(); pCons; pCons = aTmp.Next() )
592 			delete (::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer > *) pCons;
593 
594 		aBmp.ReleaseAccess( pBmpAcc );
595 		aMask.ReleaseAccess( pMskAcc );
596 	}
597 }
598 
initialize(const::com::sun::star::uno::Sequence<::com::sun::star::uno::Any> & aArguments)599 void ImageProducer::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
600 {
601 	if ( aArguments.getLength() == 1 )
602 	{
603 		::com::sun::star::uno::Any aArg = aArguments.getConstArray()[0];
604 		rtl::OUString aURL;
605 		if ( aArg >>= aURL )
606 		{
607 			SetImage( aURL );
608 		}
609 	}
610 }
611 
612 namespace frm
613 {
614 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
ImageProducer_CreateInstance(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> &)615 SAL_CALL ImageProducer_CreateInstance(
616 	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& )
617 {
618 	return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >(
619 		( ::cppu::OWeakObject* ) new ImageProducer );
620 }
621 } // namespace frm
622