photosgallery/viewframework/dataprovider/src/glxdrmgiftexturecreator.cpp
branchRCL_3
changeset 26 5b3385a43d68
child 27 34937ec34dac
equal deleted inserted replaced
25:8e5f6eea9c9f 26:5b3385a43d68
       
     1 /*
       
     2  * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description:    DRM Gif Texture creator implementation
       
    15  *
       
    16  */
       
    17 
       
    18 #include <e32math.h>
       
    19 #include <imageconversion.h> 
       
    20 #include <glxtracer.h>
       
    21 #include <glxlog.h>
       
    22 #include <alf/ialfwidgeteventhandler.h>     //  The interface for event handlers used by widget controls
       
    23 #include <mul/imulmodel.h>                  // An interface for the data model
       
    24 #include <alf/alfutil.h>                        // AlfUtil
       
    25 #include <glxmedia.h>
       
    26 
       
    27 #include "glxtexturemanager.h"
       
    28 #include "glxbinding.h"
       
    29 #include "glxuiutility.h"
       
    30 #include "glxdrmgiftexturecreator.h"
       
    31 #include "glxdrmgifactivedecoder.h"
       
    32 
       
    33 // Default frame interval for animation, in microseconds
       
    34 const TInt KDefaultFrameInterval = 100000;
       
    35 
       
    36 // -----------------------------------------------------------------------------
       
    37 // NewLC
       
    38 // -----------------------------------------------------------------------------
       
    39 CGlxDrmGifTextureCreator* CGlxDrmGifTextureCreator::NewL(
       
    40         const CGlxBinding& aBinding, const TGlxMedia& aMedia,
       
    41         TInt aItemIndex, Alf::IMulModel* aModel)
       
    42     {
       
    43     TRACER("CGlxDrmGifTextureCreator* CGlxDrmGifTextureCreator::NewL()");
       
    44     CGlxDrmGifTextureCreator* self = new (ELeave) CGlxDrmGifTextureCreator(
       
    45             aBinding, aMedia, aItemIndex, aModel);
       
    46     CleanupStack::PushL(self);
       
    47     self->ConstructL();
       
    48     CleanupStack::Pop(self);
       
    49     return self;
       
    50     }
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // Destructor 
       
    54 // -----------------------------------------------------------------------------
       
    55 CGlxDrmGifTextureCreator::~CGlxDrmGifTextureCreator()
       
    56     {
       
    57     TRACER("CGlxDrmGifTextureCreator::~CGlxDrmGifTextureCreator()");
       
    58     ReleaseContent();
       
    59 
       
    60     // Delete the animation timer
       
    61     if (iAnimationTimer)
       
    62         {
       
    63         iAnimationTimer->Cancel();
       
    64         delete iAnimationTimer;
       
    65         }
       
    66 
       
    67     iUiUtility->Close();
       
    68 
       
    69     delete iGlxDecoderAO;
       
    70 
       
    71     iFsSession.Close();
       
    72     }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // ReleaseContent 
       
    76 // -----------------------------------------------------------------------------
       
    77 void CGlxDrmGifTextureCreator::ReleaseContent()
       
    78     {
       
    79     TRACER("void CGlxDrmGifTextureCreator::ReleaseContent()");
       
    80     iBitmapReady = EFalse;
       
    81     iAnimCount = 0;
       
    82     iAnimateFlag = EFalse;
       
    83     iTransparencyPossible = EFalse;
       
    84     iFrameShift = EFalse;
       
    85 
       
    86     if (iGlxDecoderAO)
       
    87         {
       
    88         iGlxDecoderAO->Cancel();
       
    89         }
       
    90 
       
    91     if (iAnimationTimer)
       
    92         {
       
    93         iAnimationTimer->Cancel();
       
    94         }
       
    95 
       
    96     for (TInt i = 0; i < iFrameCount; i++)
       
    97         {
       
    98         GLX_LOG_INFO1("DrmGif: ReleaseContent() Releasing AnimBitmaps %d", i);
       
    99         delete (iDecodedBitmap[i]);
       
   100         iDecodedBitmap[i] = NULL;
       
   101         delete (iDecodedMask[i]);
       
   102         iDecodedMask[i] = NULL;
       
   103         }
       
   104 
       
   105     if (iUiUtility && iMedia)
       
   106         {
       
   107         iUiUtility->GlxTextureManager().RemoveTexture(iMedia->Id());
       
   108         }
       
   109 
       
   110     if (iImageDecoder)
       
   111         {
       
   112         delete iImageDecoder;
       
   113         iImageDecoder = NULL;
       
   114         }
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // Constructor
       
   119 // -----------------------------------------------------------------------------
       
   120 CGlxDrmGifTextureCreator::CGlxDrmGifTextureCreator(
       
   121         const CGlxBinding& aBinding, const TGlxMedia& aMedia,
       
   122         TInt aItemIndex, Alf::IMulModel* aModel) :
       
   123     iBinding(&aBinding), iMedia(&aMedia), iModel(aModel), iItemIndex(
       
   124             aItemIndex)
       
   125     {
       
   126     TRACER("CGlxDrmGifTextureCreator::CGlxDrmGifTextureCreator()");
       
   127     // Implement nothing here
       
   128     }
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // ConstructL 
       
   132 // -----------------------------------------------------------------------------
       
   133 void CGlxDrmGifTextureCreator::ConstructL()
       
   134     {
       
   135     TRACER("CGlxDrmGifTextureCreator::ConstructL()");
       
   136     iUiUtility = CGlxUiUtility::UtilityL();
       
   137     User::LeaveIfError(iFsSession.Connect());
       
   138     iBitmapReady = EFalse;
       
   139     iAnimCount = 0;
       
   140     iAnimateFlag = EFalse;
       
   141     iTransparencyPossible = EFalse;
       
   142     iFrameShift = EFalse;
       
   143 
       
   144     //Set the initial texture, it could be default or the FS texture
       
   145     SetTexture();
       
   146     // Create the active object
       
   147     iGlxDecoderAO = CGlxDRMgifDecoderAO::NewL(this);
       
   148 #ifdef _DEBUG
       
   149     iStartTime.HomeTime();
       
   150 #endif	
       
   151     CreateImageDecoderL(iMedia->Uri());
       
   152     CreateBitmapAndStartDecodingL();
       
   153     }
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 // UpdateNewImageL 
       
   157 // -----------------------------------------------------------------------------
       
   158 void CGlxDrmGifTextureCreator::UpdateNewImageL(const TGlxMedia& aMedia,
       
   159         TInt aItemIndex)
       
   160     {
       
   161     TRACER("CGlxDrmGifTextureCreator::UpdateNewImageL()");
       
   162     GLX_LOG_INFO1("DrmGif: UpdateNewImageL() aItemIndex=%d", aItemIndex);
       
   163     if (aItemIndex == iItemIndex)
       
   164         {
       
   165         return;
       
   166         }
       
   167 
       
   168     // First release the contents before proceeding further
       
   169     ReleaseContent();
       
   170 
       
   171     iItemIndex = aItemIndex;
       
   172     iMedia = &aMedia;
       
   173 
       
   174     iBitmapReady = EFalse;
       
   175     iAnimCount = 0;
       
   176     iAnimateFlag = EFalse;
       
   177     iTransparencyPossible = EFalse;
       
   178     iFrameShift = EFalse;
       
   179 
       
   180     //Set the initial texture, it could be default or the FS texture
       
   181     SetTexture();
       
   182 #ifdef _DEBUG
       
   183     iStartTime.HomeTime();
       
   184 #endif
       
   185     CreateImageDecoderL(iMedia->Uri());
       
   186     CreateBitmapAndStartDecodingL();
       
   187     }
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 // AnimateDRMGifItem 
       
   191 // -----------------------------------------------------------------------------
       
   192 void CGlxDrmGifTextureCreator::AnimateDRMGifItem(TBool aAnimate)
       
   193     {
       
   194     TRACER("CGlxDrmGifTextureCreator::AnimateDRMGifItem()");
       
   195     if (!iAnimationTimer)
       
   196         {
       
   197         return;
       
   198         }
       
   199 
       
   200     if (aAnimate && iBitmapReady)
       
   201         {
       
   202         if (!iAnimationTimer->IsActive())
       
   203             {
       
   204             GLX_LOG_INFO1("DrmGif: AnimateDRMGifItem() - iAnimCount=%d", iAnimCount);
       
   205             GLX_LOG_INFO1("DrmGif: AnimateDRMGifItem() - Frame Interval <%d> us",
       
   206                     (TInt)iFrameInfo.iDelay.Int64());
       
   207             TInt interval =((TInt)iFrameInfo.iDelay.Int64()) ? 
       
   208                 ((TInt)iFrameInfo.iDelay.Int64()) : KDefaultFrameInterval;
       
   209             GLX_LOG_INFO1("DrmGif: AnimateDRMGifItem() interval=<%d> us", interval);
       
   210             iAnimationTimer->Start(interval, interval, TCallBack(TimerCallbackL, this));
       
   211             }
       
   212         iAnimateFlag = ETrue;
       
   213         }
       
   214     else
       
   215         {
       
   216         if (iAnimationTimer->IsActive())
       
   217             {
       
   218             iAnimationTimer->Cancel();
       
   219             iAnimateFlag = EFalse;
       
   220             }
       
   221         }
       
   222     }
       
   223 
       
   224 // -----------------------------------------------------------------------------
       
   225 // RefreshL 
       
   226 // -----------------------------------------------------------------------------
       
   227 void CGlxDrmGifTextureCreator::RefreshL()
       
   228     {
       
   229     TRACER("CGlxDrmGifTextureCreator::RefreshL()");
       
   230     GLX_LOG_INFO2("DrmGif: RefreshL() iAnimCount=%d, iFrameShift=%d",
       
   231             iAnimCount, iFrameShift);
       
   232     TInt textureId = KErrNotFound;
       
   233     if (iTransparencyPossible && !iFrameShift)
       
   234         {
       
   235         textureId
       
   236                 = (iUiUtility->GlxTextureManager().CreateDRMAnimatedGifTextureL(
       
   237                         *iMedia, iMedia->IdSpaceId(), iAnimCount,
       
   238                         iDecodedBitmap[iAnimCount], iDecodedMask[iAnimCount])).Id();
       
   239         }
       
   240     else
       
   241         {
       
   242         textureId
       
   243                 = (iUiUtility->GlxTextureManager().CreateDRMAnimatedGifTextureL(
       
   244                         *iMedia, iMedia->IdSpaceId(), iAnimCount,
       
   245                         iDecodedBitmap[iAnimCount], NULL)).Id();
       
   246         }
       
   247 
       
   248     SetTexture(textureId);
       
   249     // Advance animation
       
   250     iAnimCount++;
       
   251     // if animation count is becoming maximum, then reset to animate again 
       
   252     if (iAnimCount >= iFrameCount)
       
   253         {
       
   254         GLX_LOG_INFO("DrmGif: RefreshL() Reset iAnimCount");
       
   255         iAnimCount = 0;
       
   256         }
       
   257     }
       
   258 
       
   259 // -----------------------------------------------------------------------------
       
   260 // CreateBitmapAndStartDecodingL 
       
   261 // -----------------------------------------------------------------------------
       
   262 void CGlxDrmGifTextureCreator::CreateBitmapAndStartDecodingL()
       
   263     {
       
   264     TRACER("CGlxDrmGifTextureCreator::CreateBitmapAndStartDecodingL()");
       
   265     GLX_LOG_INFO1("CreateBitmapAndDecodingL() iAnimCount=%d", iAnimCount);
       
   266     // Create the bitmap and mask as of original image size, and let the 
       
   267     // coverflow widget do the scaling, if required.
       
   268     // This is needed for the transparent gifs frames as the
       
   269     // frame co-ordinates would mismatch if downscaling is applied.
       
   270     TSize frameSize = iImageDecoder->FrameInfo(iAnimCount).iFrameSizeInPixels;
       
   271     GLX_LOG_INFO3("DrmGif: CreateBitmapAndStartDecodingL() - Frame[%d] size=%d,%d",
       
   272             iAnimCount, frameSize.iWidth, frameSize.iHeight);
       
   273 
       
   274     iDecodedBitmap[iAnimCount] = new (ELeave) CFbsBitmap();
       
   275     iDecodedBitmap[iAnimCount]->Create(frameSize,
       
   276             iFrameInfo.iFrameDisplayMode);
       
   277     User::LeaveIfNull(iDecodedBitmap[iAnimCount]);
       
   278 
       
   279     if (iFrameInfo.iFlags & TFrameInfo::ETransparencyPossible)
       
   280         {
       
   281         iDecodedMask[iAnimCount] = new (ELeave) CFbsBitmap();
       
   282         iDecodedMask[iAnimCount]->Create(frameSize, iFrameInfo.iFlags
       
   283                 & TFrameInfo::EAlphaChannel ? EGray256 : EGray2);
       
   284         User::LeaveIfNull(iDecodedMask[iAnimCount]);
       
   285 
       
   286         // decoding the image
       
   287         iGlxDecoderAO->ConvertImageL(iDecodedBitmap[iAnimCount],
       
   288                 iDecodedMask[iAnimCount], iAnimCount, iImageDecoder);
       
   289         iTransparencyPossible = ETrue;
       
   290         }
       
   291     else
       
   292         {
       
   293         // decoding the image
       
   294         iGlxDecoderAO->ConvertImageL(iDecodedBitmap[iAnimCount], NULL,
       
   295                 iAnimCount, iImageDecoder);
       
   296         }
       
   297     }
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // HandleRunL 
       
   301 // -----------------------------------------------------------------------------
       
   302 void CGlxDrmGifTextureCreator::HandleRunL(TRequestStatus& aStatus)
       
   303     {
       
   304     TRACER("CGlxDrmGifTextureCreator::HandleRunL()");
       
   305     TInt err = aStatus.Int();
       
   306     GLX_LOG_INFO1("DrmGif: HandleRunL : err=%d", err);
       
   307     if (err != KErrNone)
       
   308         {
       
   309         ReleaseContent();
       
   310         return;
       
   311         }
       
   312 
       
   313     GLX_LOG_INFO2("DrmGif: HandleRunL() - Frame=%d/%d",
       
   314             iAnimCount, iFrameCount-1);
       
   315     if (iAnimCount > 0 && iAnimCount < iFrameCount)
       
   316         {
       
   317         TPoint point =
       
   318                 iImageDecoder->FrameInfo(iAnimCount).iFrameCoordsInPixels.iTl;
       
   319         GLX_LOG_INFO2("DrmGif: HandleRunL() point=(%d, %d)",
       
   320                 point.iX, point.iY );
       
   321         TSize frameSize = iImageDecoder->FrameInfo(iAnimCount).iFrameSizeInPixels;
       
   322         GLX_LOG_INFO2("DrmGif: HandleRunL() - frameSize(%d, %d)",
       
   323                 frameSize.iWidth, frameSize.iHeight);
       
   324         // Frame shift is checked,
       
   325         // 1) If the subsequent frame sizes differ from the first frame (or)
       
   326         // 2) If the subsequent frame co-ordinates differ from the first frame
       
   327         if (point != iFrameInfo.iFrameCoordsInPixels.iTl
       
   328                 || iFrameInfo.iFrameSizeInPixels != frameSize)
       
   329             {
       
   330             iFrameShift = ETrue;
       
   331             }
       
   332 
       
   333         if (iFrameShift)
       
   334             {
       
   335             TSize firstFrameSize = iDecodedBitmap[0]->SizeInPixels();
       
   336             GLX_LOG_INFO2("DrmGif: HandleRunL() - first bitmap size (%d, %d)",
       
   337                     firstFrameSize.iWidth, firstFrameSize.iHeight);
       
   338 
       
   339             TDisplayMode dispMode = iDecodedBitmap[0]->DisplayMode();
       
   340             TInt scanLineLength = CFbsBitmap::ScanLineLength(
       
   341                     firstFrameSize.iWidth, dispMode);
       
   342 
       
   343             CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
       
   344             CleanupStack::PushL(bitmap);
       
   345             User::LeaveIfError(bitmap->Create(firstFrameSize, dispMode));
       
   346             bitmap->LockHeap();
       
   347             iDecodedBitmap[0]->LockHeap();
       
   348             if (bitmap && bitmap->DataAddress())
       
   349                 {
       
   350                 memcpy((void*) bitmap->DataAddress(),
       
   351                         (void*) iDecodedBitmap[0]->DataAddress(),
       
   352                         scanLineLength * firstFrameSize.iHeight);
       
   353                 }
       
   354             iDecodedBitmap[0]->UnlockHeap();
       
   355             bitmap->UnlockHeap();
       
   356 
       
   357             CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap);
       
   358             CleanupStack::PushL(bitmapDevice);
       
   359 
       
   360             CFbsBitGc* bitmapGc = CFbsBitGc::NewL();
       
   361             CleanupStack::PushL(bitmapGc);
       
   362             bitmapGc->Activate(bitmapDevice);
       
   363 
       
   364             if (iTransparencyPossible)
       
   365                 {
       
   366                 GLX_LOG_INFO("DrmGif: HandleRunL() BitBltMasked");
       
   367                 bitmapGc->BitBltMasked(point, iDecodedBitmap[iAnimCount],
       
   368                         iOrigImageDimensions, iDecodedMask[iAnimCount],
       
   369                         EFalse);
       
   370                 }
       
   371             else
       
   372                 {
       
   373                 GLX_LOG_INFO("DrmGif: HandleRunL() BitBlt");
       
   374                 bitmapGc->BitBlt(point, iDecodedBitmap[iAnimCount]);
       
   375                 }
       
   376 
       
   377             delete iDecodedBitmap[iAnimCount];
       
   378             iDecodedBitmap[iAnimCount] = bitmap;
       
   379             CleanupStack::PopAndDestroy(bitmapGc);
       
   380             CleanupStack::PopAndDestroy(bitmapDevice);
       
   381             CleanupStack::Pop(bitmap);
       
   382             }
       
   383         }
       
   384 
       
   385     if (iAnimCount < iFrameCount - 1)
       
   386         {
       
   387         if (!iGlxDecoderAO->IsActive())
       
   388             {
       
   389             iAnimCount++;
       
   390             CreateBitmapAndStartDecodingL();
       
   391             }
       
   392         }
       
   393     else
       
   394         {
       
   395 #ifdef _DEBUG
       
   396         iStopTime.HomeTime();
       
   397         GLX_LOG_INFO1("DrmGif: HandleRunL() ConvertImageL took <%d> us",
       
   398                 (TInt)iStopTime.MicroSecondsFrom(iStartTime).Int64());
       
   399 #endif
       
   400         iBitmapReady = ETrue;
       
   401         iAnimateFlag = ETrue;
       
   402         iAnimCount = 0;
       
   403         ProcessImageL();
       
   404 
       
   405         //release imagedecoder after the conversion is over     
       
   406         if (iImageDecoder)
       
   407             {
       
   408             delete iImageDecoder;
       
   409             iImageDecoder = NULL;
       
   410             }
       
   411         }
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // ProcessImageL 
       
   416 // -----------------------------------------------------------------------------
       
   417 void CGlxDrmGifTextureCreator::ProcessImageL()
       
   418     {
       
   419     TRACER("CGlxDrmGifTextureCreator::ProcessImageL()");
       
   420     RefreshL();
       
   421     iAnimationTimer->Cancel();
       
   422     if (iAnimateFlag)
       
   423         {
       
   424         GLX_LOG_INFO1("DrmGif: ProcessImageL() - Frame Interval <%d> us",
       
   425                 (TInt)iFrameInfo.iDelay.Int64());
       
   426         TInt interval =((TInt)iFrameInfo.iDelay.Int64()) ? 
       
   427             ((TInt)iFrameInfo.iDelay.Int64()) : KDefaultFrameInterval;
       
   428         GLX_LOG_INFO1("DrmGif: ProcessImageL() interval=<%d> us", interval);
       
   429         iAnimationTimer->Start(interval, interval, TCallBack(TimerCallbackL,
       
   430                 this));
       
   431         }
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CreateImageDecoderL 
       
   436 // -----------------------------------------------------------------------------
       
   437 void CGlxDrmGifTextureCreator::CreateImageDecoderL(const TDesC& aImageFile)
       
   438     {
       
   439     TRACER("CGlxDrmGifTextureCreator::CreateImageDecoderL()");
       
   440     GLX_LOG_URI("DrmGif::CreateImageDecoderL(%S)", &aImageFile);
       
   441 
       
   442     CImageDecoder::TOptions options =
       
   443             (CImageDecoder::TOptions) (CImageDecoder::EOptionNoDither
       
   444                     | CImageDecoder::EOptionAlwaysThread);
       
   445     // Create a decoder for the image in the named file
       
   446     TRAPD(error,iImageDecoder = CImageDecoder::FileNewL(iFsSession,
       
   447                     aImageFile, options, KNullUid));
       
   448     if (error != KErrNone)
       
   449         {
       
   450         User::Leave(error);
       
   451         }
       
   452     iFrameInfo = iImageDecoder->FrameInfo();
       
   453     iOrigImageDimensions = iImageDecoder->FrameInfo().iOverallSizeInPixels;
       
   454     GLX_LOG_INFO1("DrmGif::CreateImageDecoderL() - Gif Frame Interval <%d> us",
       
   455             (TInt)iFrameInfo.iDelay.Int64());
       
   456     iFrameCount = iImageDecoder->FrameCount();
       
   457 
       
   458     // We are creating array of KGlxMaxFrameCount frames
       
   459     // So re-setting the array-count with the no.
       
   460     // It will animate till that no. of frames.
       
   461     if (iFrameCount > KGlxMaxFrameCount)
       
   462         {
       
   463         iFrameCount = KGlxMaxFrameCount;
       
   464         }
       
   465     //dont create the timer if it is a singleframe.no need to animate
       
   466     if (iFrameCount > 1)
       
   467         {
       
   468         iAnimationTimer = CPeriodic::NewL(CActive::EPriorityLow);
       
   469         }
       
   470     }
       
   471 
       
   472 // -----------------------------------------------------------------------------
       
   473 // TimerCallbackL 
       
   474 // -----------------------------------------------------------------------------
       
   475 TInt CGlxDrmGifTextureCreator::TimerCallbackL(TAny* aThis)
       
   476     {
       
   477     TRACER("CGlxDrmGifTextureCreator::TimerCallbackL()");
       
   478     static_cast<CGlxDrmGifTextureCreator*> (aThis)->ProcessTimerEventL();
       
   479     return KErrNone;
       
   480     }
       
   481 
       
   482 // -----------------------------------------------------------------------------
       
   483 // ProcessTimerEventL 
       
   484 // -----------------------------------------------------------------------------
       
   485 void CGlxDrmGifTextureCreator::ProcessTimerEventL()
       
   486     {
       
   487     TRACER("CGlxDrmGifTextureCreator::ProcessTimerEventL()");
       
   488     ProcessImageL();
       
   489     }
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // SetTexture 
       
   493 // -----------------------------------------------------------------------------
       
   494 void CGlxDrmGifTextureCreator::SetTexture(TInt aTextureId)
       
   495     {
       
   496     TRACER("CGlxDrmGifTextureCreator::SetTexture()");
       
   497     auto_ptr<MulVisualItem> item(new (EMM) MulVisualItem());
       
   498     iBinding->PopulateT(*item, *iMedia, ETrue, aTextureId);
       
   499     iModel->SetData(iItemIndex, item);
       
   500     }