Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / source / gdi / animate.cxx
blobb7f335628aef1fb671df1422386a1480838ab248
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/animate.hxx>
21 #include <tools/stream.hxx>
22 #include <rtl/crc.h>
23 #include <vcl/virdev.hxx>
24 #include <vcl/window.hxx>
25 #include <vcl/dibtools.hxx>
27 #include "impanmvw.hxx"
29 #define MIN_TIMEOUT 2
30 #define INC_TIMEOUT 0
32 sal_uLong Animation::mnAnimCount = 0UL;
34 BitmapChecksum AnimationBitmap::GetChecksum() const
36 BitmapChecksum nCrc = aBmpEx.GetChecksum();
37 SVBT32 aBT32;
39 UInt32ToSVBT32( aPosPix.X(), aBT32 );
40 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
42 UInt32ToSVBT32( aPosPix.Y(), aBT32 );
43 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
45 UInt32ToSVBT32( aSizePix.Width(), aBT32 );
46 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
48 UInt32ToSVBT32( aSizePix.Height(), aBT32 );
49 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
51 UInt32ToSVBT32( (long) nWait, aBT32 );
52 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
54 UInt32ToSVBT32( (long) eDisposal, aBT32 );
55 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
57 UInt32ToSVBT32( (long) bUserInput, aBT32 );
58 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
60 return nCrc;
63 Animation::Animation() :
64 mnLoopCount ( 0 ),
65 mnLoops ( 0 ),
66 mnPos ( 0 ),
67 mbIsInAnimation ( false ),
68 mbLoopTerminated ( false )
70 maTimer.SetInvokeHandler( LINK( this, Animation, ImplTimeoutHdl ) );
73 Animation::Animation( const Animation& rAnimation ) :
74 maBitmapEx ( rAnimation.maBitmapEx ),
75 maGlobalSize ( rAnimation.maGlobalSize ),
76 mnLoopCount ( rAnimation.mnLoopCount ),
77 mnPos ( rAnimation.mnPos ),
78 mbIsInAnimation ( false ),
79 mbLoopTerminated ( rAnimation.mbLoopTerminated )
82 for(const AnimationBitmap* i : rAnimation.maList)
83 maList.push_back( new AnimationBitmap( *i ) );
85 maTimer.SetInvokeHandler( LINK( this, Animation, ImplTimeoutHdl ) );
86 mnLoops = mbLoopTerminated ? 0 : mnLoopCount;
89 Animation::~Animation()
92 if( mbIsInAnimation )
93 Stop();
95 for(AnimationBitmap* i : maList)
96 delete i;
98 for(ImplAnimView* i : maViewList)
99 delete i;
102 Animation& Animation::operator=( const Animation& rAnimation )
104 Clear();
106 for(const AnimationBitmap* i : rAnimation.maList)
107 maList.push_back( new AnimationBitmap( *i ) );
109 maGlobalSize = rAnimation.maGlobalSize;
110 maBitmapEx = rAnimation.maBitmapEx;
111 mnLoopCount = rAnimation.mnLoopCount;
112 mnPos = rAnimation.mnPos;
113 mbLoopTerminated = rAnimation.mbLoopTerminated;
114 mnLoops = mbLoopTerminated ? 0 : mnLoopCount;
116 return *this;
119 bool Animation::operator==( const Animation& rAnimation ) const
121 const size_t nCount = maList.size();
122 bool bRet = false;
124 if( rAnimation.maList.size() == nCount
125 && rAnimation.maBitmapEx == maBitmapEx
126 && rAnimation.maGlobalSize == maGlobalSize
129 bRet = true;
131 for( size_t n = 0; n < nCount; n++ )
133 if( ( *maList[ n ] ) != ( *rAnimation.maList[ n ] ) )
135 bRet = false;
136 break;
141 return bRet;
144 void Animation::Clear()
146 maTimer.Stop();
147 mbIsInAnimation = false;
148 maGlobalSize = Size();
149 maBitmapEx.SetEmpty();
151 for(AnimationBitmap* i : maList)
152 delete i;
153 maList.clear();
155 for(ImplAnimView* i : maViewList)
156 delete i;
157 maViewList.clear();
160 bool Animation::IsTransparent() const
162 Point aPoint;
163 tools::Rectangle aRect( aPoint, maGlobalSize );
164 bool bRet = false;
166 // If some small bitmap needs to be replaced by the background,
167 // we need to be transparent, in order to be displayed correctly
168 // as the application (?) does not invalidate on non-transparent
169 // graphics due to performance reasons.
170 for(const AnimationBitmap* pAnimBmp : maList)
172 if( Disposal::Back == pAnimBmp->eDisposal
173 && tools::Rectangle( pAnimBmp->aPosPix, pAnimBmp->aSizePix ) != aRect
176 bRet = true;
177 break;
181 if( !bRet )
182 bRet = maBitmapEx.IsTransparent();
184 return bRet;
187 sal_uLong Animation::GetSizeBytes() const
189 sal_uLong nSizeBytes = GetBitmapEx().GetSizeBytes();
191 for(const AnimationBitmap* pAnimBmp : maList)
193 nSizeBytes += pAnimBmp->aBmpEx.GetSizeBytes();
196 return nSizeBytes;
199 BitmapChecksum Animation::GetChecksum() const
201 SVBT32 aBT32;
202 BitmapChecksumOctetArray aBCOA;
203 BitmapChecksum nCrc = GetBitmapEx().GetChecksum();
205 UInt32ToSVBT32( maList.size(), aBT32 );
206 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
208 UInt32ToSVBT32( maGlobalSize.Width(), aBT32 );
209 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
211 UInt32ToSVBT32( maGlobalSize.Height(), aBT32 );
212 nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
214 for(const AnimationBitmap* i : maList)
216 BCToBCOA( i->GetChecksum(), aBCOA );
217 nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
220 return nCrc;
223 bool Animation::Start( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz, long nExtraData,
224 OutputDevice* pFirstFrameOutDev )
226 bool bRet = false;
228 if( !maList.empty() )
230 if( ( pOut->GetOutDevType() == OUTDEV_WINDOW )
231 && !mbLoopTerminated
232 && ( ANIMATION_TIMEOUT_ON_CLICK != maList[ mnPos ]->nWait )
235 ImplAnimView* pView;
236 ImplAnimView* pMatch = nullptr;
238 for( size_t i = 0; i < maViewList.size(); ++i )
240 pView = maViewList[ i ];
241 if( pView->matches( pOut, nExtraData ) )
243 if( pView->getOutPos() == rDestPt &&
244 pView->getOutSizePix() == pOut->LogicToPixel( rDestSz ) )
246 pView->repaint();
247 pMatch = pView;
249 else
251 delete maViewList[ i ];
252 maViewList.erase( maViewList.begin() + i );
253 pView = nullptr;
256 break;
260 if( maViewList.empty() )
262 maTimer.Stop();
263 mbIsInAnimation = false;
264 mnPos = 0UL;
267 if( !pMatch )
268 maViewList.push_back( new ImplAnimView( this, pOut, rDestPt, rDestSz, nExtraData, pFirstFrameOutDev ) );
270 if( !mbIsInAnimation )
272 ImplRestartTimer( maList[ mnPos ]->nWait );
273 mbIsInAnimation = true;
276 else
277 Draw( pOut, rDestPt, rDestSz );
279 bRet = true;
282 return bRet;
285 void Animation::Stop( OutputDevice* pOut, long nExtraData )
287 for( size_t i = 0; i < maViewList.size(); )
290 ImplAnimView* pView = maViewList[ i ];
291 if( pView->matches( pOut, nExtraData ) )
293 delete pView;
294 maViewList.erase( maViewList.begin() + i );
296 else
297 i++;
300 if( maViewList.empty() )
302 maTimer.Stop();
303 mbIsInAnimation = false;
307 void Animation::Draw( OutputDevice* pOut, const Point& rDestPt ) const
309 Draw( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ) );
312 void Animation::Draw( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz ) const
314 const size_t nCount = maList.size();
316 if( nCount )
318 AnimationBitmap* pObj = maList[ std::min( mnPos, nCount - 1 ) ];
320 if( pOut->GetConnectMetaFile()
321 || ( pOut->GetOutDevType() == OUTDEV_PRINTER )
323 maList[ 0 ]->aBmpEx.Draw( pOut, rDestPt, rDestSz );
324 else if( ANIMATION_TIMEOUT_ON_CLICK == pObj->nWait )
325 pObj->aBmpEx.Draw( pOut, rDestPt, rDestSz );
326 else
328 const size_t nOldPos = mnPos;
329 const_cast<Animation*>(this)->mnPos = mbLoopTerminated ? ( nCount - 1UL ) : mnPos;
330 delete new ImplAnimView( const_cast<Animation*>(this), pOut, rDestPt, rDestSz, 0 );
331 const_cast<Animation*>(this)->mnPos = nOldPos;
336 void Animation::ImplRestartTimer( sal_uLong nTimeout )
338 maTimer.SetTimeout( std::max( nTimeout, (sal_uLong)(MIN_TIMEOUT + ( mnAnimCount - 1 ) * INC_TIMEOUT) ) * 10 );
339 maTimer.Start();
342 IMPL_LINK_NOARG(Animation, ImplTimeoutHdl, Timer *, void)
344 const size_t nAnimCount = maList.size();
345 std::vector< AInfo* > aAInfoList;
347 if( nAnimCount )
349 ImplAnimView* pView;
350 bool bGlobalPause = true;
352 if( maNotifyLink.IsSet() )
354 // create AInfo-List
355 for(ImplAnimView* i : maViewList)
356 aAInfoList.push_back( i->createAInfo() );
358 maNotifyLink.Call( this );
360 // set view state from AInfo structure
361 for(AInfo* pAInfo : aAInfoList)
363 if( !pAInfo->pViewData )
365 pView = new ImplAnimView( this, pAInfo->pOutDev,
366 pAInfo->aStartOrg, pAInfo->aStartSize, pAInfo->nExtraData );
368 maViewList.push_back( pView );
370 else
371 pView = static_cast<ImplAnimView*>(pAInfo->pViewData);
373 pView->pause( pAInfo->bPause );
374 pView->setMarked( true );
377 // delete AInfo structures
378 for(AInfo* i : aAInfoList)
379 delete i;
380 aAInfoList.clear();
382 // delete all unmarked views and reset marked state
383 for( size_t i = 0; i < maViewList.size(); )
385 pView = maViewList[ i ];
386 if( !pView->isMarked() )
388 delete pView;
389 maViewList.erase( maViewList.begin() + i );
391 else
393 if( !pView->isPause() )
394 bGlobalPause = false;
396 pView->setMarked( false );
397 i++;
401 else
402 bGlobalPause = false;
404 if( maViewList.empty() )
405 Stop();
406 else if( bGlobalPause )
407 ImplRestartTimer( 10 );
408 else
410 AnimationBitmap* pStepBmp = (++mnPos < maList.size()) ? maList[ mnPos ] : nullptr;
412 if( !pStepBmp )
414 if( mnLoops == 1 )
416 Stop();
417 mbLoopTerminated = true;
418 mnPos = nAnimCount - 1UL;
419 maBitmapEx = maList[ mnPos ]->aBmpEx;
420 return;
422 else
424 if( mnLoops )
425 mnLoops--;
427 mnPos = 0;
428 pStepBmp = maList[ mnPos ];
432 // Paint all views; after painting check, if view is
433 // marked; in this case remove view, because area of output
434 // lies out of display area of window; mark state is
435 // set from view itself
436 for( size_t i = 0; i < maViewList.size(); )
438 pView = maViewList[ i ];
439 pView->draw( mnPos );
441 if( pView->isMarked() )
443 delete pView;
444 maViewList.erase( maViewList.begin() + i );
446 else
447 i++;
450 // stop or restart timer
451 if( maViewList.empty() )
452 Stop();
453 else
454 ImplRestartTimer( pStepBmp->nWait );
457 else
458 Stop();
461 bool Animation::Insert( const AnimationBitmap& rStepBmp )
463 bool bRet = false;
465 if( !IsInAnimation() )
467 Point aPoint;
468 tools::Rectangle aGlobalRect( aPoint, maGlobalSize );
470 maGlobalSize = aGlobalRect.Union( tools::Rectangle( rStepBmp.aPosPix, rStepBmp.aSizePix ) ).GetSize();
471 maList.push_back( new AnimationBitmap( rStepBmp ) );
473 // As a start, we make the first BitmapEx the replacement BitmapEx
474 if( maList.size() == 1 )
475 maBitmapEx = rStepBmp.aBmpEx;
477 bRet = true;
480 return bRet;
483 const AnimationBitmap& Animation::Get( sal_uInt16 nAnimation ) const
485 SAL_WARN_IF( ( nAnimation >= maList.size() ), "vcl", "No object at this position" );
486 return *maList[ nAnimation ];
489 void Animation::Replace( const AnimationBitmap& rNewAnimationBitmap, sal_uInt16 nAnimation )
491 SAL_WARN_IF( ( nAnimation >= maList.size() ), "vcl", "No object at this position" );
493 delete maList[ nAnimation ];
494 maList[ nAnimation ] = new AnimationBitmap( rNewAnimationBitmap );
496 // If we insert at first position we also need to
497 // update the replacement BitmapEx
498 if ( ( !nAnimation
499 && ( !mbLoopTerminated
500 || ( maList.size() == 1 )
504 ( ( nAnimation == maList.size() - 1 )
505 && mbLoopTerminated
509 maBitmapEx = rNewAnimationBitmap.aBmpEx;
513 void Animation::SetLoopCount( const sal_uLong nLoopCount )
515 mnLoopCount = nLoopCount;
516 ResetLoopCount();
519 void Animation::ResetLoopCount()
521 mnLoops = mnLoopCount;
522 mbLoopTerminated = false;
525 bool Animation::Convert( BmpConversion eConversion )
527 SAL_WARN_IF( IsInAnimation(), "vcl", "Animation modified while it is animated" );
529 bool bRet;
531 if( !IsInAnimation() && !maList.empty() )
533 bRet = true;
535 for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
536 bRet = maList[ i ]->aBmpEx.Convert( eConversion );
538 maBitmapEx.Convert( eConversion );
540 else
541 bRet = false;
543 return bRet;
546 bool Animation::ReduceColors( sal_uInt16 nNewColorCount )
548 SAL_WARN_IF( IsInAnimation(), "vcl", "Animation modified while it is animated" );
550 bool bRet;
552 if( !IsInAnimation() && !maList.empty() )
554 bRet = true;
556 for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
557 bRet = maList[ i ]->aBmpEx.ReduceColors( nNewColorCount );
559 maBitmapEx.ReduceColors( nNewColorCount );
561 else
562 bRet = false;
564 return bRet;
567 bool Animation::Invert()
569 SAL_WARN_IF( IsInAnimation(), "vcl", "Animation modified while it is animated" );
571 bool bRet;
573 if( !IsInAnimation() && !maList.empty() )
575 bRet = true;
577 for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
578 bRet = maList[ i ]->aBmpEx.Invert();
580 maBitmapEx.Invert();
582 else
583 bRet = false;
585 return bRet;
588 bool Animation::Mirror( BmpMirrorFlags nMirrorFlags )
590 SAL_WARN_IF( IsInAnimation(), "vcl", "Animation modified while it is animated" );
592 bool bRet;
594 if( !IsInAnimation() && !maList.empty() )
596 bRet = true;
598 if( nMirrorFlags != BmpMirrorFlags::NONE )
600 for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
602 AnimationBitmap* pStepBmp = maList[ i ];
603 bRet = pStepBmp->aBmpEx.Mirror( nMirrorFlags );
604 if( bRet )
606 if( nMirrorFlags & BmpMirrorFlags::Horizontal )
607 pStepBmp->aPosPix.X() = maGlobalSize.Width() - pStepBmp->aPosPix.X() - pStepBmp->aSizePix.Width();
609 if( nMirrorFlags & BmpMirrorFlags::Vertical )
610 pStepBmp->aPosPix.Y() = maGlobalSize.Height() - pStepBmp->aPosPix.Y() - pStepBmp->aSizePix.Height();
614 maBitmapEx.Mirror( nMirrorFlags );
617 else
618 bRet = false;
620 return bRet;
623 bool Animation::Adjust( short nLuminancePercent, short nContrastPercent,
624 short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
625 double fGamma, bool bInvert )
627 SAL_WARN_IF( IsInAnimation(), "vcl", "Animation modified while it is animated" );
629 bool bRet;
631 if( !IsInAnimation() && !maList.empty() )
633 bRet = true;
635 for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
637 bRet = maList[ i ]->aBmpEx.Adjust( nLuminancePercent,
638 nContrastPercent,
639 nChannelRPercent,
640 nChannelGPercent,
641 nChannelBPercent,
642 fGamma, bInvert
646 maBitmapEx.Adjust( nLuminancePercent, nContrastPercent,
647 nChannelRPercent, nChannelGPercent, nChannelBPercent,
648 fGamma, bInvert );
650 else
651 bRet = false;
653 return bRet;
656 bool Animation::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam )
658 SAL_WARN_IF( IsInAnimation(), "vcl", "Animation modified while it is animated" );
660 bool bRet;
662 if( !IsInAnimation() && !maList.empty() )
664 bRet = true;
666 for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
667 bRet = maList[ i ]->aBmpEx.Filter( eFilter, pFilterParam );
669 (void)maBitmapEx.Filter(eFilter, pFilterParam);
671 else
672 bRet = false;
674 return bRet;
677 SvStream& WriteAnimation( SvStream& rOStm, const Animation& rAnimation )
679 const sal_uInt16 nCount = rAnimation.Count();
681 if( nCount )
683 const sal_uInt32 nDummy32 = 0UL;
685 // If no BitmapEx was set we write the first Bitmap of
686 // the Animation
687 if( !rAnimation.GetBitmapEx().GetBitmap() )
688 WriteDIBBitmapEx(rAnimation.Get( 0 ).aBmpEx, rOStm);
689 else
690 WriteDIBBitmapEx(rAnimation.GetBitmapEx(), rOStm);
692 // Write identifier ( SDANIMA1 )
693 rOStm.WriteUInt32( 0x5344414e ).WriteUInt32( 0x494d4931 );
695 for( sal_uInt16 i = 0; i < nCount; i++ )
697 const AnimationBitmap& rAnimBmp = rAnimation.Get( i );
698 const sal_uInt16 nRest = nCount - i - 1;
700 // Write AnimationBitmap
701 WriteDIBBitmapEx(rAnimBmp.aBmpEx, rOStm);
702 WritePair( rOStm, rAnimBmp.aPosPix );
703 WritePair( rOStm, rAnimBmp.aSizePix );
704 WritePair( rOStm, rAnimation.maGlobalSize );
705 rOStm.WriteUInt16( ( ANIMATION_TIMEOUT_ON_CLICK == rAnimBmp.nWait ) ? 65535 : rAnimBmp.nWait );
706 rOStm.WriteUInt16( (sal_uInt16)rAnimBmp.eDisposal );
707 rOStm.WriteBool( rAnimBmp.bUserInput );
708 rOStm.WriteUInt32( rAnimation.mnLoopCount );
709 rOStm.WriteUInt32( nDummy32 ); // Unused
710 rOStm.WriteUInt32( nDummy32 ); // Unused
711 rOStm.WriteUInt32( nDummy32 ); // Unused
712 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, OString()); // dummy
713 rOStm.WriteUInt16( nRest ); // Count of remaining structures
717 return rOStm;
720 SvStream& ReadAnimation( SvStream& rIStm, Animation& rAnimation )
722 Bitmap aBmp;
723 sal_uLong nStmPos;
724 sal_uInt32 nAnimMagic1, nAnimMagic2;
725 SvStreamEndian nOldFormat = rIStm.GetEndian();
726 bool bReadAnimations = false;
728 rIStm.SetEndian( SvStreamEndian::LITTLE );
729 nStmPos = rIStm.Tell();
730 rIStm.ReadUInt32( nAnimMagic1 ).ReadUInt32( nAnimMagic2 );
732 rAnimation.Clear();
734 // If the BitmapEx at the beginning have already been read (by Graphic)
735 // we can start reading the AnimationBitmaps right away
736 if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() )
737 bReadAnimations = true;
738 // Else, we try reading the Bitmap(-Ex)
739 else
741 rIStm.Seek( nStmPos );
742 ReadDIBBitmapEx(rAnimation.maBitmapEx, rIStm);
743 nStmPos = rIStm.Tell();
744 rIStm.ReadUInt32( nAnimMagic1 ).ReadUInt32( nAnimMagic2 );
746 if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() )
747 bReadAnimations = true;
748 else
749 rIStm.Seek( nStmPos );
752 // Read AnimationBitmaps
753 if( bReadAnimations )
755 AnimationBitmap aAnimBmp;
756 BitmapEx aBmpEx;
757 sal_uInt32 nTmp32;
758 sal_uInt16 nTmp16;
759 bool cTmp;
763 ReadDIBBitmapEx(aAnimBmp.aBmpEx, rIStm);
764 ReadPair( rIStm, aAnimBmp.aPosPix );
765 ReadPair( rIStm, aAnimBmp.aSizePix );
766 ReadPair( rIStm, rAnimation.maGlobalSize );
767 rIStm.ReadUInt16( nTmp16 ); aAnimBmp.nWait = ( ( 65535 == nTmp16 ) ? ANIMATION_TIMEOUT_ON_CLICK : nTmp16 );
768 rIStm.ReadUInt16( nTmp16 ); aAnimBmp.eDisposal = ( Disposal) nTmp16;
769 rIStm.ReadCharAsBool( cTmp ); aAnimBmp.bUserInput = cTmp;
770 rIStm.ReadUInt32( nTmp32 ); rAnimation.mnLoopCount = (sal_uInt16) nTmp32;
771 rIStm.ReadUInt32( nTmp32 ); // Unused
772 rIStm.ReadUInt32( nTmp32 ); // Unused
773 rIStm.ReadUInt32( nTmp32 ); // Unused
774 read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm); // Unused
775 rIStm.ReadUInt16( nTmp16 ); // The rest to read
777 rAnimation.Insert( aAnimBmp );
779 while( nTmp16 && !rIStm.GetError() );
781 rAnimation.ResetLoopCount();
784 rIStm.SetEndian( nOldFormat );
786 return rIStm;
789 AInfo::AInfo() : pOutDev( nullptr ),
790 pViewData( nullptr ),
791 nExtraData( 0L ),
792 bPause( false ) {}
794 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */