webengine/osswebengine/WebCore/platform/symbian/bitmap/AnimationDecoderWrapped.cpp
changeset 65 5bfc169077b2
parent 38 6297cdf66332
child 66 cacf6ee57968
equal deleted inserted replaced
42:d39add9822e2 65:5bfc169077b2
    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