xref: /AOO41X/main/forms/source/component/imgprod.cxx (revision 24acc54625a85f778a4f966495e8f4cd9d7b247c)
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