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