xref: /trunk/main/forms/source/component/imgprod.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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