47 #include "config.h" |
47 #include "config.h" |
48 #include "AnimationDecoderWrapped.h" |
48 #include "AnimationDecoderWrapped.h" |
49 #include "MaskedBitmap.h" |
49 #include "MaskedBitmap.h" |
50 #include "ImageObserver.h" |
50 #include "ImageObserver.h" |
51 #include "SyncDecodeThread.h" |
51 #include "SyncDecodeThread.h" |
52 #include <Oma2Agent.h> |
52 #include "Oma2Agent.h" |
53 using namespace ContentAccess; |
53 using namespace ContentAccess; |
54 |
54 |
55 namespace TBidirectionalState { |
55 namespace TBidirectionalState { |
56 class TRunInfo; |
56 class TRunInfo; |
57 }; |
57 }; |
67 void Panic( TInt aPanicCode ) { User::Panic( _L("AnimationDecoder"), aPanicCode ); } |
67 void Panic( TInt aPanicCode ) { User::Panic( _L("AnimationDecoder"), aPanicCode ); } |
68 } |
68 } |
69 |
69 |
70 using namespace WebCore; |
70 using namespace WebCore; |
71 CSynDecodeThread *CAnimationDecoderWrapped::iSyncDecodeThread = NULL; |
71 CSynDecodeThread *CAnimationDecoderWrapped::iSyncDecodeThread = NULL; |
72 const TInt KDownScaleFactor = 2; // scaling is done by a factor of 2.For ex.2,4,8...( similar to ImageViewer ) |
|
73 const TInt KMaxDownScaleFactor = 8; // limit scaling to 8 |
|
74 |
72 |
75 // ============================ MEMBER FUNCTIONS =============================== |
73 // ============================ MEMBER FUNCTIONS =============================== |
76 // ----------------------------------------------------------------------------- |
74 // ----------------------------------------------------------------------------- |
77 // |
75 // |
78 // C++ default constructor can NOT contain any code, that |
76 // C++ default constructor can NOT contain any code, that |
81 CAnimationDecoderWrapped::CAnimationDecoderWrapped( ImageObserver* aObs ) |
79 CAnimationDecoderWrapped::CAnimationDecoderWrapped( ImageObserver* aObs ) |
82 :CActive( CActive::EPriorityIdle ) |
80 :CActive( CActive::EPriorityIdle ) |
83 , iObserver(aObs) |
81 , iObserver(aObs) |
84 , iLoopCount( -1 ) |
82 , iLoopCount( -1 ) |
85 , iCurLoopCount( -1 ) |
83 , iCurLoopCount( -1 ) |
86 , iSyncBitmapHandle(0) |
84 , iSyncBitmapHandle(-1) |
87 , iSyncMaskHandle(0) |
85 , iSyncMaskHandle(-1) |
88 , iDecodeInProgress(ETrue) |
86 , iDecodeInProgress(ETrue) |
89 , iIsInvalid(EFalse) |
87 , iIsInvalid(EFalse) |
90 , iCanBeDeleted(ETrue) |
88 , iCanBeDeleted(ETrue) |
91 { |
89 { |
92 if (CActiveScheduler::Current()) |
90 if (CActiveScheduler::Current()) |
173 { |
171 { |
174 if (iDestination) { |
172 if (iDestination) { |
175 return iDestination; |
173 return iDestination; |
176 } |
174 } |
177 |
175 |
178 if (iSyncBitmapHandle || iSyncMaskHandle) { |
176 if (iSyncBitmapHandle != -1 && iSyncMaskHandle != -1) { |
179 CFbsBitmap* bitmap = new CFbsBitmap(); |
177 CFbsBitmap* bitmap = new CFbsBitmap(); |
180 TInt errBmp = bitmap->Duplicate(iSyncBitmapHandle); |
178 bitmap->Duplicate(iSyncBitmapHandle); |
181 |
179 CFbsBitmap* mask = new CFbsBitmap(); |
182 CFbsBitmap* mask = NULL; |
180 mask->Duplicate(iSyncMaskHandle); |
183 TInt errMask = KErrNone; |
181 |
184 if(iSyncMaskHandle) { |
182 iDestination = new CMaskedBitmap(bitmap, mask); |
185 CFbsBitmap* mask = new CFbsBitmap(); |
183 iDestination->SetFrameIndex(0); |
186 errMask = mask->Duplicate(iSyncMaskHandle); |
184 iDestination->SetFrameDelay(0); |
187 } |
185 iSyncBitmapHandle = -1; |
188 |
186 iSyncMaskHandle = -1; |
189 if(errBmp==KErrNone && errMask==KErrNone) { |
|
190 iDestination = new CMaskedBitmap(bitmap, mask); |
|
191 iDestination->SetFrameIndex(0); |
|
192 iDestination->SetFrameDelay(0); |
|
193 } |
|
194 |
|
195 iSyncBitmapHandle = 0; |
|
196 iSyncMaskHandle = 0; |
|
197 } |
187 } |
198 |
188 |
199 return iDestination; |
189 return iDestination; |
200 } |
190 } |
201 //============================================================================= |
191 //============================================================================= |
377 // Check frame count |
367 // Check frame count |
378 iAnimationFrameCount = iDecoder->FrameCount(); |
368 iAnimationFrameCount = iDecoder->FrameCount(); |
379 iAnimation = iAnimationFrameCount > 1; |
369 iAnimation = iAnimationFrameCount > 1; |
380 iFrameInfo = iDecoder->FrameInfo( 0 ); |
370 iFrameInfo = iDecoder->FrameInfo( 0 ); |
381 iSizeAvailable = ETrue; |
371 iSizeAvailable = ETrue; |
|
372 |
382 if (iFrameInfo.iFlags & TFrameInfo::ETransparencyPossible){ |
373 if (iFrameInfo.iFlags & TFrameInfo::ETransparencyPossible){ |
383 // we only support gray2 and gray256 tiling |
374 // we only support gray2 and gray256 tiling |
384 TDisplayMode maskmode = ( (iFrameInfo.iFlags & TFrameInfo::EAlphaChannel) && (iFrameInfo.iFlags & TFrameInfo::ECanDither)) ? EGray256 : EGray2; |
375 TDisplayMode maskmode = ( (iFrameInfo.iFlags & TFrameInfo::EAlphaChannel) && (iFrameInfo.iFlags & TFrameInfo::ECanDither)) ? EGray256 : EGray2; |
385 TInt error = iDestination->Create( iFrameInfo.iOverallSizeInPixels, DisplayMode(), maskmode ); |
376 TInt error = iDestination->Create( iFrameInfo.iOverallSizeInPixels, DisplayMode(), maskmode ); |
386 |
377 |
388 LoadFrame(0); |
379 LoadFrame(0); |
389 else |
380 else |
390 RunError(KErrNoMemory); |
381 RunError(KErrNoMemory); |
391 } |
382 } |
392 else { |
383 else { |
393 TInt error = ScaleImageIfRequired(); |
384 TInt error = iDestination->Create( iFrameInfo.iOverallSizeInPixels, DisplayMode() ); |
394 if (!error) |
385 if (!error) |
395 { |
386 LoadFrame(0); |
396 LoadFrame(0); |
387 else |
397 } |
388 RunError(KErrNoMemory); |
398 else |
|
399 { |
|
400 RunError(error); |
|
401 } |
|
402 } |
389 } |
403 } |
390 } |
404 |
391 |
405 // ----------------------------------------------------------------------------- |
392 // ----------------------------------------------------------------------------- |
406 // CAnimationDecoderWrapped::MaskDisplayMode |
393 // CAnimationDecoderWrapped::MaskDisplayMode |
625 else { |
612 else { |
626 // Save source info destination |
613 // Save source info destination |
627 iDestination->SetFrameIndex( iFrameIndex ); |
614 iDestination->SetFrameIndex( iFrameIndex ); |
628 iDestination->SetFrameDelay( 0 ); |
615 iDestination->SetFrameDelay( 0 ); |
629 //Compress non-animated images via FBServ (losslessly, idle priority) |
616 //Compress non-animated images via FBServ (losslessly, idle priority) |
630 //the 1x1 image is directly fetched before decompressing it which results in a crash in fbsserv and therefore a white background is displayed. |
617 iDestination->CompressInBackground(); |
631 //If the Image is of pixel (1,1) do not compress. |
|
632 if( frameSize != TSize(1,1) ) |
|
633 iDestination->CompressInBackground(); |
|
634 |
618 |
635 // Normal image ready |
619 // Normal image ready |
636 //iDestination = NULL; |
620 //iDestination = NULL; |
637 iImageState = EInactive; |
621 iImageState = EInactive; |
638 iObserver->imageReady(sizeinBytes); |
622 iObserver->imageReady(sizeinBytes); |
773 iStatus = KRequestPending; |
757 iStatus = KRequestPending; |
774 TRequestStatus* status = &iStatus; |
758 TRequestStatus* status = &iStatus; |
775 User::RequestComplete( status, aError ); |
759 User::RequestComplete( status, aError ); |
776 } |
760 } |
777 |
761 |
778 // ----------------------------------------------------------------------------- |
762 |
779 // CAnimationDecoderWrapped::ScaleImageIfRequired |
|
780 // Images that are too large to be displayed are scaled down |
|
781 // @return error code |
|
782 // ----------------------------------------------------------------------------- |
|
783 TInt CAnimationDecoderWrapped::ScaleImageIfRequired() |
|
784 { |
|
785 TInt error = iDestination->Create( iFrameInfo.iOverallSizeInPixels, DisplayMode() ); |
|
786 // if the image is too large try scaling it down |
|
787 if ( error == KErrNoMemory ) |
|
788 { |
|
789 TBool fullyScalable(iFrameInfo.iFlags & TFrameInfo::EFullyScaleable); |
|
790 // check if scaling is possible |
|
791 if ( !fullyScalable ) |
|
792 { |
|
793 TInt scalingLevel(KDownScaleFactor); |
|
794 do |
|
795 { |
|
796 TSize scaledSize( iFrameInfo.iOverallSizeInPixels.iWidth / scalingLevel + ( iFrameInfo.iOverallSizeInPixels.iWidth % scalingLevel ? 1 : 0 ), |
|
797 iFrameInfo.iOverallSizeInPixels.iHeight / scalingLevel + ( iFrameInfo.iOverallSizeInPixels.iHeight % scalingLevel ? 1 : 0 ) ); |
|
798 error = iDestination->Create( scaledSize, DisplayMode() ); |
|
799 // retry only for KErrNoMemory condition |
|
800 if (error == KErrNoMemory) |
|
801 { |
|
802 // increase to next down scaling level |
|
803 scalingLevel *= KDownScaleFactor ; |
|
804 } |
|
805 else |
|
806 { |
|
807 // image scaled to appropriate level |
|
808 iFrameInfo.iOverallSizeInPixels = scaledSize; |
|
809 } |
|
810 }while (error == KErrNoMemory && scalingLevel <= KMaxDownScaleFactor);// loop until we can scale the image without any error |
|
811 } |
|
812 } |
|
813 return error; |
|
814 } |
|
815 |
763 |
816 // End of File |
764 // End of File |