javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtimagedataloader.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved. This program and the accompanying materials
       
     4  * are made available under the terms of the Eclipse Public License v1.0
       
     5  * which accompanies this distribution, and is available at
       
     6  * http://www.eclipse.org/legal/epl-v10.html
       
     7  *
       
     8  * Contributors:
       
     9  *     Nokia Corporation - S60 implementation
       
    10  *******************************************************************************/
       
    11 
       
    12 
       
    13 #include <imageconversion.h>
       
    14 #include <f32file.h>
       
    15 #include <gdi.h>
       
    16 #include "swtimagedataloader.h"
       
    17 #include "swtimage.h"
       
    18 
       
    19 
       
    20 //lint -esym( 613, CSwtImageDataLoader::iDecoder )
       
    21 //lint -esym( 613, CSwtImageDataLoader::iEncoder )
       
    22 
       
    23 
       
    24 // ======== MEMBER FUNCTIONS ========
       
    25 
       
    26 
       
    27 CSwtImageDataLoader::~CSwtImageDataLoader()
       
    28 {
       
    29     Cancel();
       
    30     FreeBitmaps(); // delete iBitmap and iMask
       
    31     FreeBuffers(); // delete iBuffer
       
    32     delete iDecoder;
       
    33 
       
    34     delete iImageData;
       
    35     if (iImageDataArray)
       
    36     {
       
    37         iImageDataArray->ResetAndDestroy();
       
    38     }
       
    39     delete iImageDataArray;
       
    40 
       
    41     delete iEncoder;
       
    42 
       
    43     if (iActiveScheduler)
       
    44     {
       
    45         delete iActiveScheduler;
       
    46     }
       
    47     RFbsSession::Disconnect();
       
    48     iFs.Close();
       
    49 
       
    50 #ifdef _lint
       
    51     iBuffer = NULL;
       
    52     iMask   = NULL;
       
    53     iBitmap = NULL;
       
    54 #endif
       
    55 }
       
    56 
       
    57 CSwtImageDataLoader::CSwtImageDataLoader()
       
    58         : CActive(EPriorityStandard)
       
    59         , iImageCoordinates(TPoint::EUninitialized)
       
    60         , iDesc(NULL, 0, 0)
       
    61 {
       
    62     CActiveScheduler::Add(this);
       
    63 }
       
    64 
       
    65 CSwtImageDataLoader* CSwtImageDataLoader::NewL()
       
    66 {
       
    67     CActiveScheduler* activeScheduler = NULL;
       
    68     if (!CActiveScheduler::Current())
       
    69     {
       
    70         activeScheduler = new(ELeave) CActiveScheduler;
       
    71         CleanupStack::PushL(activeScheduler);
       
    72         CActiveScheduler::Install(activeScheduler);
       
    73     }
       
    74     CSwtImageDataLoader* self = new(ELeave) CSwtImageDataLoader();
       
    75     CleanupStack::PushL(self);
       
    76     self->ConstructL();
       
    77     CleanupStack::Pop(1);   // self
       
    78 
       
    79     if (activeScheduler)
       
    80     {
       
    81         self->iActiveScheduler = activeScheduler;
       
    82         CleanupStack::Pop(1);  //activescheduler
       
    83     }
       
    84     return self;
       
    85 }
       
    86 
       
    87 void CSwtImageDataLoader::ConstructL()
       
    88 {
       
    89     iImageDataArray = new(ELeave) CSwtImageDataArray(10);
       
    90     User::LeaveIfError(iFs.Connect());
       
    91     User::LeaveIfError(RFbsSession::Connect(iFs));
       
    92 }
       
    93 
       
    94 void CSwtImageDataLoader::DecodeImageL(const TDesC& aFileName)
       
    95 {
       
    96     // In normal use of ImageDataLoader, it must be disposed by its creator
       
    97     // after a call to this method ( so iDecoder should not be not NULL
       
    98     // because of a previous call to this method )
       
    99     ASSERT(!iDecoder);
       
   100 
       
   101     // In case ImageDataLoader is not used normally and we are not in debug,
       
   102     // ASSERT is ignored, so deleting iDecoder is safer
       
   103     delete iDecoder;
       
   104     iDecoder = NULL;
       
   105     // Same applies to other data members of CSwtImageDataLoader
       
   106 
       
   107     /* Known issue:
       
   108     Sometimes after a few thousand RThread::Create(), it fails with KErrGeneral from RThread::Create().
       
   109     There is a problem with the underlying PC emulation of threads. When a thread is terminated under Symbian OS,
       
   110     the thread has exited and freed it's memory, but the underlying Windows thread cannot free it's resources until
       
   111     the emulator process exits. After a few thousand threads have been created and destroyed, the resources mount up
       
   112     so that there is no space left to create a new thread and the emulator becomes useless and needs restarting.
       
   113     Apparent Memory Leak. This behaviour can be seen when opening and closing an application. The memory footprint
       
   114     of the emulator keeps going up each time the app is terminated and closed.
       
   115     There is no current solution for 7.0 and precursors, it is a limitation of the emulator.
       
   116     The problem does not show up on hardware.
       
   117     */
       
   118     TRAPD(error, (iDecoder = CImageDecoder::FileNewL(iFs, aFileName,
       
   119                              CImageDecoder::EOptionAlwaysThread)));
       
   120     LeaveIfErrorFromICLDecoderL(error);
       
   121 
       
   122     // Check if the image is GIF
       
   123     TUid imgType;
       
   124     TUid imgSubType;
       
   125     iDecoder->ImageType(0, imgType, imgSubType);
       
   126     if (imgType == KImageTypeGIFUid)
       
   127     {
       
   128         iIsGif = ETrue;
       
   129     }
       
   130 
       
   131     TInt nbFrame = iDecoder->FrameCount();
       
   132     for (TInt index = 0; index < nbFrame; ++index)
       
   133     {
       
   134         FreeBitmaps();
       
   135         const TFrameInfo& currentFrame = iDecoder->FrameInfo(index);
       
   136 
       
   137         SetMaskL(currentFrame);
       
   138         SetLogicalScreenValues(currentFrame);
       
   139         SetFrameInfosL(currentFrame);
       
   140 
       
   141         // Calculate the optimal display mode for the new bitmap and create it
       
   142         TDisplayMode dispMode(EColor16MU);
       
   143         if (iIsGif && currentFrame.iFrameDisplayMode == EColor256)
       
   144         {
       
   145             // iFrameDisplayMode may always return EColor256.
       
   146             // Return maximum color mode to ensure best image quality.
       
   147             dispMode = EColor16M;
       
   148         }
       
   149         else if (currentFrame.iFrameDisplayMode < EColor16M
       
   150                  || currentFrame.iFrameDisplayMode == EColor4K)
       
   151         {
       
   152             dispMode = EColor64K;
       
   153         }
       
   154         iBitmap = new(ELeave) CFbsBitmap;
       
   155         User::LeaveIfError(
       
   156             iBitmap->Create(
       
   157                 currentFrame.iOverallSizeInPixels,
       
   158                 dispMode));
       
   159 
       
   160         TRequestStatus localStatus;
       
   161         // Mask is created each time because the frames size may vary in a single source
       
   162         if (iMask == NULL)
       
   163         {
       
   164             iDecoder->Convert(&localStatus, *iBitmap, index);
       
   165         }
       
   166         else
       
   167         {
       
   168 
       
   169             iDecoder->Convert(&localStatus,*iBitmap, *iMask, index);
       
   170         }
       
   171 
       
   172         // We are waiting on the TRequestStatus we passed to the asynchronous
       
   173         // function "convert( ... )" so that we transform the call to an
       
   174         // asyncrhonous method into a call to a synchronous one.
       
   175         User::WaitForRequest(localStatus);
       
   176         LeaveIfErrorFromICLDecoderL(localStatus.Int());
       
   177 
       
   178         ExtractImagedataL();
       
   179     }
       
   180 
       
   181     FreeBitmaps();
       
   182 }
       
   183 
       
   184 void CSwtImageDataLoader::DecodeWholeImageFromBufferL(const TDesC8& aBuffer)
       
   185 {
       
   186     iWholeImageAtOnce = ETrue;
       
   187 
       
   188     // In normal use of ImageDataLoader, it must be disposed by its creator after a call to this method ( so iDecoder should not be not NULL because of a previous call to this method )
       
   189     ASSERT(iDecoder == NULL);
       
   190     // In case ImageDataLoader is not used normally and we are not in debug, ASSERT is ignored, so deleting iDecoder is safer
       
   191     delete iDecoder;
       
   192     iDecoder = NULL;
       
   193     // Same applies to other data members of CSwtImageDataLoader
       
   194 
       
   195     TRAPD(error,(iDecoder = CImageDecoder::DataNewL(iFs, aBuffer,CImageDecoder::EOptionAlwaysThread)));
       
   196     LeaveIfErrorFromICLDecoderL(error);
       
   197 
       
   198     TInt nbFrame = iDecoder->FrameCount();
       
   199     for (TInt index = 0; index < nbFrame; ++index)
       
   200     {
       
   201         DecodeFrameL(index);
       
   202     }
       
   203 
       
   204     FreeBitmaps();
       
   205 
       
   206     LeaveIfErrorFromICLDecoderL(iResult);
       
   207 }
       
   208 
       
   209 void CSwtImageDataLoader::DecodeImageFromBufferL(const TDesC8& aBuffer)
       
   210 {
       
   211     iNextFrameToDecode = 0;
       
   212 
       
   213     iBuffer = aBuffer.AllocL();
       
   214     iDesc.Set(iBuffer->Des());
       
   215 
       
   216     // In normal use of ImageDataLoader, it must be disposed by its creator after decoding an image ( so iDecoder should not be not NULL because of a previous call to this method )
       
   217     ASSERT(iDecoder == NULL);
       
   218     // In case ImageDataLoader is not used normally and we are not in debug, ASSERT is ignored, so deleting iDecoder is safer
       
   219     delete iDecoder;
       
   220     iDecoder = NULL;
       
   221     // Same applies to other data members of CSwtImageDataLoader
       
   222 
       
   223     TRAPD(error, (iDecoder = CImageDecoder::DataNewL(iFs, iDesc, CImageDecoder::EOptionAlwaysThread)));
       
   224     LeaveIfErrorFromICLDecoderL(error);
       
   225 
       
   226     // We are starting with a new frame ( the first one )
       
   227     iStartDecodingAnother = ETrue;
       
   228 
       
   229     // If frame to decode has not been detected by decoder and header is not complete, then more data is needed
       
   230     if ((iDecoder->FrameCount() <= iNextFrameToDecode) && (!iDecoder->IsImageHeaderProcessingComplete()))
       
   231         return; // need data
       
   232 
       
   233     // Start decoding frames from the buffer
       
   234     while (iStartDecodingAnother)
       
   235     {
       
   236         DecodeNextFrameL();
       
   237     };
       
   238 }
       
   239 
       
   240 TBool CSwtImageDataLoader::DecodeNextFrameL()
       
   241 {
       
   242     if (iNextFrameToDecode < iDecoder->FrameCount() && iStartDecodingAnother)
       
   243     {
       
   244         DecodeFrameL(iNextFrameToDecode);
       
   245         LeaveIfErrorFromICLDecoderL(iResult);
       
   246 
       
   247         return ETrue;
       
   248     }
       
   249 
       
   250     return EFalse;
       
   251 }
       
   252 
       
   253 void CSwtImageDataLoader::DecodeFrameL(TInt aIndexOfFrame)
       
   254 {
       
   255     FreeBitmaps();
       
   256     const TFrameInfo& currentFrame = iDecoder->FrameInfo(aIndexOfFrame);
       
   257 
       
   258     SetMaskL(currentFrame);
       
   259     SetLogicalScreenValues(currentFrame);
       
   260     SetFrameInfosL(currentFrame);
       
   261     // Check if the image is GIF
       
   262     TUid imgType;
       
   263     TUid imgSubType;
       
   264     iDecoder->ImageType(0, imgType, imgSubType);
       
   265     if (imgType == KImageTypeGIFUid)
       
   266     {
       
   267         iIsGif = ETrue;
       
   268     }
       
   269 
       
   270 
       
   271     // Calculate the optimal display mode for the new bitmap and create it
       
   272     TDisplayMode dispMode(EColor16MU);
       
   273     if (iIsGif && currentFrame.iFrameDisplayMode == EColor256)
       
   274     {
       
   275         // iFrameDisplayMode may always return EColor256.
       
   276         // Return maximum color mode to ensure best image quality.
       
   277         dispMode = EColor16M;
       
   278     }
       
   279     else if (currentFrame.iFrameDisplayMode < EColor16M
       
   280              || currentFrame.iFrameDisplayMode == EColor4K)
       
   281     {
       
   282         dispMode = EColor64K;
       
   283     }
       
   284 
       
   285     // creating the main bitmap
       
   286     iBitmap = new(ELeave) CFbsBitmap();
       
   287     User::LeaveIfError(iBitmap->Create(currentFrame.iOverallSizeInPixels,dispMode));
       
   288 
       
   289 
       
   290     // Mask is created each time because the frames size may vary in a single source
       
   291     if (iMask == NULL)
       
   292     {
       
   293         iDecoder->Convert(&iStatus, *iBitmap, aIndexOfFrame);
       
   294     }
       
   295     else
       
   296     {
       
   297         iDecoder->Convert(&iStatus, *iBitmap, *iMask, aIndexOfFrame);
       
   298     }
       
   299 
       
   300     // The mechanism used in the function DecodeImage( ... ) does not work here for unclear reasons.
       
   301     // ( the convert function returns and the returned status is KRequestPending ). So we use this one.
       
   302     SetActive();
       
   303     CActiveScheduler::Start();
       
   304 
       
   305     // Extracting Imagedata is performed in Runl;
       
   306 }
       
   307 
       
   308 void CSwtImageDataLoader::AppendDataL(const TDesC8& aBuffer)
       
   309 {
       
   310     // newBuffer is created and initialized with iBuffer content ( and iBuffer is deleted )
       
   311     HBufC8* newBuffer = iBuffer->ReAllocL(iBuffer->Length()+aBuffer.Length());
       
   312     // Set iBuffer to the new larger buffer ( for next time )
       
   313     iBuffer = newBuffer;
       
   314     // Refresh iDesc and append new data
       
   315     iDesc.Set(iBuffer->Des());
       
   316     iDesc.Append(aBuffer);
       
   317 
       
   318     // In normal use of ImageDataLoader, it must be disposed by its creator after decoding an image ( so iDecoder should not be not NULL because of a previous call to DecodeImageFromBufferL method )
       
   319     ASSERT(iDecoder);
       
   320     // In case ImageDataLoader is not used normally and we are not in debug, ASSERT is ignored, so deleting iDecoder is safer
       
   321     delete iDecoder;
       
   322     iDecoder = NULL;
       
   323     // Same applies to other data members of CSwtImageDataLoader
       
   324 
       
   325     TRAPD(error, (iDecoder = CImageDecoder::DataNewL(iFs, iDesc, CImageDecoder::EOptionAlwaysThread)));
       
   326     LeaveIfErrorFromICLDecoderL(error);
       
   327 
       
   328     // data have been appended. Now launching the correct action
       
   329     iStartDecodingAnother = ETrue;
       
   330 
       
   331     // If frame to decode has not been detected by decoder and header is not complete, then process newly read data
       
   332     if ((iDecoder->FrameCount() <= iNextFrameToDecode) && (!iDecoder->IsImageHeaderProcessingComplete()))
       
   333     {
       
   334         iDecoder->ContinueProcessingHeaderL();
       
   335         // If now processed data is enough to decode then do it
       
   336         if (!((iDecoder->FrameCount() <= iNextFrameToDecode) && (!iDecoder->IsImageHeaderProcessingComplete())))
       
   337         {
       
   338             while (DecodeNextFrameL()) {};
       
   339             return;
       
   340         }
       
   341         // If processed data is still not enough to decode then wait for next data
       
   342         else
       
   343         {
       
   344             return;
       
   345         }
       
   346     }
       
   347     // If frame to decode has been detected by decoder then decode frame
       
   348     else if (iDecoder->FrameCount() > iNextFrameToDecode)
       
   349     {
       
   350         while (DecodeNextFrameL()) {};
       
   351         return;
       
   352     }
       
   353     // If frame to decode has not been detected by decoder while header is complete, then don't process this unknown newly read data
       
   354     else
       
   355     {
       
   356         return;
       
   357     }
       
   358 }
       
   359 
       
   360 void CSwtImageDataLoader::EncodeImageToFileL(MSwtImageData& aImageData, TInt aFormat, const TDesC& aDestination)
       
   361 {
       
   362     CheckDestinationL(aDestination, iFs);
       
   363     // -- First of all : getting an image object
       
   364     CSwtImage* image = NULL;
       
   365     image = CSwtImage::NewL(NULL, aImageData, NULL);
       
   366     CleanupStack::PushL(image);
       
   367 
       
   368     // -- Second extracting a CFbsBitmat
       
   369     CFbsBitmap* bitmap(NULL);
       
   370     TBool haveMask = image->MaskBitmap() != NULL;
       
   371     if (haveMask)
       
   372     {
       
   373         bitmap = image->BitmapWithAlphaLC();
       
   374     }
       
   375     else
       
   376     {
       
   377         bitmap = &image->Bitmap();
       
   378     }
       
   379 
       
   380 
       
   381 
       
   382     // -- third :  create an encoder based on the format
       
   383 
       
   384     const TDesC8& mime = GetMimeType(static_cast<TSwtImageType>(aFormat));
       
   385 
       
   386     // REMINDER : Symbian does not manage any kind of transparency for the time being.
       
   387     TRAPD(error, (iEncoder = CImageEncoder::FileNewL(
       
   388                                  iFs,
       
   389                                  aDestination,
       
   390                                  mime,
       
   391                                  CImageEncoder::EOptionAlwaysThread
       
   392                              )));
       
   393 
       
   394     LeaveIfErrorFromICLEncoderL(error);
       
   395     // Fourth : execute decoding
       
   396     // Note, the encoder does not support to save alpha channel yet.
       
   397     // so, if the bitmamp's display mode is EColor16MA, the alpha channel data will be ignored
       
   398     iEncoder->Convert(&iStatus,*bitmap);
       
   399 
       
   400     // -- Finally wait and quit
       
   401 
       
   402     // The mechanism used in the equivalent function DecodeImage( ... ) does not work here for unclear reasons.
       
   403     // ( the convert function returns and the returned status is KRequestPending ). So we use this one.
       
   404     SetActive();
       
   405     CActiveScheduler::Start();
       
   406 
       
   407     if (haveMask)
       
   408     {
       
   409         CleanupStack::PopAndDestroy(bitmap);
       
   410     }
       
   411 
       
   412     CleanupStack::PopAndDestroy(image);
       
   413     delete iEncoder;
       
   414     iEncoder = NULL;
       
   415     LeaveIfErrorFromICLEncoderL(iResult);
       
   416 }
       
   417 
       
   418 HBufC8* CSwtImageDataLoader::EncodeImageToStreamL(MSwtImageData& aImageData, TInt aFormat)
       
   419 {
       
   420 
       
   421     // -- First of all : getting an image object
       
   422     CSwtImage* image = NULL;
       
   423     image = CSwtImage::NewL(NULL, aImageData, NULL);
       
   424     CleanupStack::PushL(image);
       
   425 
       
   426     // -- Second extracting a CFbsBitmat
       
   427     CFbsBitmap& bitmap = image->Bitmap();
       
   428 
       
   429     // -- third :  create an encoder based on the format
       
   430 
       
   431     const TDesC8& mime = GetMimeType(static_cast<TSwtImageType>(aFormat));
       
   432     // REMINDER : Symbian does not manage any kind of transparency for the time being.
       
   433     TRAPD(error, (iEncoder = CImageEncoder::DataNewL(
       
   434                                  iBuffer,
       
   435                                  mime,
       
   436                                  CImageEncoder::EOptionAlwaysThread
       
   437                              )));   // lint !e613
       
   438 
       
   439     LeaveIfErrorFromICLEncoderL(error);
       
   440     // Fourth : execute decoding
       
   441     iEncoder->Convert(&iStatus,bitmap);
       
   442 
       
   443     // -- Finally wait and quit
       
   444 
       
   445     // The mechanism used in the equivalent function DecodeImage( ... ) does not work here for unclear reasons.
       
   446     // ( the convert function returns and the returned status is KRequestPending ). So we use this one.
       
   447     SetActive();
       
   448     CActiveScheduler::Start();
       
   449 
       
   450     CleanupStack::PopAndDestroy(image);
       
   451     delete iEncoder;
       
   452     iEncoder = NULL;
       
   453     LeaveIfErrorFromICLEncoderL(iResult);
       
   454     return iBuffer;
       
   455 }
       
   456 
       
   457 /*
       
   458  *  Free the bitmaps and their associated data
       
   459  */
       
   460 void CSwtImageDataLoader::LeaveIfErrorFromICLDecoderL(TInt aLeaveCode) const
       
   461 {
       
   462     switch (aLeaveCode)
       
   463     {
       
   464     case KErrNone:
       
   465         break;
       
   466     case KErrNotFound:
       
   467         // Error in loading related codec
       
   468         User::Leave(ESwtErrorIO);
       
   469     case KErrUnderflow:
       
   470     case KEComErrNoInterfaceIdentified:
       
   471     case KErrCorrupt:
       
   472         // Codec unknown for the image
       
   473         User::Leave(ESwtErrorInvalidImage);
       
   474     default:
       
   475         User::Leave(aLeaveCode);
       
   476     }
       
   477 }
       
   478 
       
   479 void CSwtImageDataLoader::LeaveIfErrorFromICLEncoderL(TInt aLeaveCode) const
       
   480 {
       
   481     switch (aLeaveCode)
       
   482     {
       
   483     case KErrNone:
       
   484         break;
       
   485     case KErrNotFound:
       
   486     case KEComErrNoInterfaceIdentified:
       
   487         // Error in loading related codec : should not happen
       
   488         User::Leave(aLeaveCode);      // what else?
       
   489     case KErrUnderflow:
       
   490     case KErrCorrupt:
       
   491         User::Leave(ESwtErrorInvalidImage);
       
   492     default:
       
   493         User::Leave(aLeaveCode);
       
   494     }
       
   495 }
       
   496 
       
   497 void CSwtImageDataLoader::FreeBitmaps()
       
   498 {
       
   499     delete iBitmap;
       
   500     iBitmap = NULL;
       
   501     delete iMask;
       
   502     iMask = NULL;
       
   503 }
       
   504 
       
   505 void CSwtImageDataLoader::FreeBuffers()
       
   506 {
       
   507     delete iBuffer;
       
   508     iBuffer = NULL;
       
   509 }
       
   510 
       
   511 void CSwtImageDataLoader::ExtractImagedataL()
       
   512 {
       
   513     CSwtImage* image = NULL;
       
   514 
       
   515     image = CSwtImage::NewL(*iBitmap, iMask, iImageCoordinates, iDelay, iDisposal);   //lint !e613
       
   516     CleanupStack::PushL(image);
       
   517     // After this line the ImageData object pointed by iImageDataArray will be owned by us
       
   518     SetImageDataL(*image->GetImageDataL());
       
   519 
       
   520     CleanupStack::PopAndDestroy(image);
       
   521 }
       
   522 
       
   523 CSwtImageDataArray* CSwtImageDataLoader::GetImageData()
       
   524 {
       
   525     return iImageDataArray;
       
   526 }
       
   527 
       
   528 void CSwtImageDataLoader::SetImageDataL(MSwtImageData& aImageData)
       
   529 {
       
   530     iImageDataArray->AppendL(&aImageData);
       
   531 }
       
   532 
       
   533 void CSwtImageDataLoader::Dispose()
       
   534 {
       
   535     delete this;
       
   536 }
       
   537 
       
   538 void CSwtImageDataLoader::SetMaskL(const TFrameInfo& aInfo)
       
   539 {
       
   540     if (!(aInfo.iFlags & TFrameInfo::ETransparencyPossible))
       
   541     {
       
   542         return;
       
   543     }
       
   544 
       
   545     TDisplayMode mode(EGray2);
       
   546     if (aInfo.iFlags & TFrameInfo::EAlphaChannel)
       
   547     {
       
   548         mode = EGray256;
       
   549     }
       
   550 
       
   551     iMask = new(ELeave) CFbsBitmap();
       
   552     User::LeaveIfError(iMask->Create(aInfo.iOverallSizeInPixels, mode));
       
   553 }
       
   554 
       
   555 void CSwtImageDataLoader::SetLogicalScreenValues(const TFrameInfo& aInfo)
       
   556 {
       
   557     if (iLogicalScreenValues.iHeight < aInfo.iOverallSizeInPixels.iHeight)
       
   558         iLogicalScreenValues.iHeight = aInfo.iOverallSizeInPixels.iHeight;
       
   559     if (iLogicalScreenValues.iWidth  < aInfo.iOverallSizeInPixels.iWidth)
       
   560         iLogicalScreenValues.iWidth = aInfo.iOverallSizeInPixels.iWidth;
       
   561 }
       
   562 
       
   563 TInt CSwtImageDataLoader::GetLogicalScreenHeight()
       
   564 {
       
   565     return iLogicalScreenValues.iHeight;
       
   566 }
       
   567 
       
   568 TInt CSwtImageDataLoader::GetLogicalScreenWidth()
       
   569 {
       
   570     return iLogicalScreenValues.iWidth;
       
   571 }
       
   572 
       
   573 void CSwtImageDataLoader::SetFrameInfosL(const TFrameInfo& aInfo)
       
   574 {
       
   575     iImageCoordinates = aInfo.iFrameCoordsInPixels.iTl;
       
   576 
       
   577     iDelay = I64INT(aInfo.iDelay.Int64()) / 10000;   // micro to 1/100 th of second
       
   578 
       
   579     if (aInfo.iFlags & TFrameInfo::ELeaveInPlace)
       
   580         iDisposal = KSwtDisposalFillNone;
       
   581     else if (aInfo.iFlags & TFrameInfo::ERestoreToBackground)
       
   582         iDisposal = KSwtDisposalFillBackground;
       
   583     else if (aInfo.iFlags & TFrameInfo::ERestoreToPrevious)
       
   584         iDisposal = KSwtDisposalFillPrevious;
       
   585     else
       
   586         iDisposal = KSwtDisposalUnspecified;
       
   587 }
       
   588 
       
   589 void CSwtImageDataLoader::RunL()
       
   590 {
       
   591     CActiveScheduler::Stop();
       
   592     iResult = iStatus.Int();
       
   593 
       
   594     if (iDecoder != NULL)
       
   595     {
       
   596         ASSERT(iEncoder ==NULL);
       
   597         switch (iResult)
       
   598         {
       
   599         case KErrNone:
       
   600             ExtractImagedataL();
       
   601             // Update decoding state in case of bufferized decoding
       
   602             iStartDecodingAnother = ETrue;
       
   603             ++iNextFrameToDecode;
       
   604             break;
       
   605 
       
   606         case KErrUnderflow:
       
   607             if (iWholeImageAtOnce)
       
   608             {
       
   609                 iResult = KErrCorrupt;
       
   610             }
       
   611             // In case of bufferized decoding this is not an error
       
   612             else
       
   613             {
       
   614                 iResult = KErrNone;
       
   615                 iStartDecodingAnother = EFalse;
       
   616             }
       
   617             break;
       
   618 
       
   619         default:
       
   620             break;
       
   621         }
       
   622     }
       
   623     else
       
   624     {
       
   625         ASSERT(iEncoder !=NULL);
       
   626         switch (iResult)
       
   627         {
       
   628         case KErrNone:
       
   629             break;
       
   630         case KErrUnderflow:
       
   631             iResult = KErrCorrupt;
       
   632             break;
       
   633         default:
       
   634             ASSERT(0);
       
   635             break;
       
   636         }
       
   637     }
       
   638 }
       
   639 
       
   640 void CSwtImageDataLoader::DoCancel()
       
   641 {
       
   642     if (iDecoder)
       
   643         iDecoder->Cancel();
       
   644     if (iEncoder)
       
   645         iEncoder->Cancel();
       
   646 }
       
   647 
       
   648 TInt CSwtImageDataLoader::RunError(TInt aError)
       
   649 {
       
   650     // Delete all processed bitmaps
       
   651     FreeBitmaps(); // delete iBitmap and iMask
       
   652     FreeBuffers(); // delete iBuffer
       
   653     if (iImageDataArray)
       
   654     {
       
   655         iImageDataArray->ResetAndDestroy();
       
   656         delete iImageDataArray;
       
   657         iImageDataArray = NULL;
       
   658     }
       
   659 
       
   660 
       
   661     // Complete with error
       
   662     iImageStatus = &iStatus;
       
   663     User::RequestComplete(iImageStatus, aError);
       
   664     return KErrNone;
       
   665 }
       
   666 
       
   667 
       
   668 void CSwtImageDataLoader::CheckDestinationL(const TDesC& aDestination, const RFs& aFs) const
       
   669 {
       
   670     // As we expect the file being correctly set, if it not possible to create a file then we leave
       
   671 
       
   672     TEntry entry;
       
   673     TInt err = KErrNone;
       
   674 
       
   675     TParse parser;
       
   676     parser.Set(aDestination,NULL,NULL);
       
   677 
       
   678     if (!parser.IsRoot())
       
   679     {
       
   680         err = aFs.Entry(parser.DriveAndPath(), entry);
       
   681         if (err != KErrNone)
       
   682             User::Leave(ESwtErrorIO);
       
   683     }
       
   684     else if (!parser.NameOrExtPresent())
       
   685     {
       
   686         User::Leave(ESwtErrorIO);
       
   687     }
       
   688 
       
   689     err = aFs.Entry(parser.FullName(), entry);
       
   690     if (entry.IsReadOnly())
       
   691         User::Leave(ESwtErrorIO);
       
   692 
       
   693 }
       
   694 
       
   695 const TDesC8& CSwtImageDataLoader::GetMimeType(TSwtImageType aFormat) const
       
   696 {
       
   697     _LIT8(KGif,"image/gif");
       
   698     _LIT8(KPng,"image/png");
       
   699     _LIT8(KJpg, "image/jpeg");
       
   700 
       
   701     switch (aFormat)
       
   702     {
       
   703     case ESwtImageGif:
       
   704         return KGif;
       
   705     case ESwtImagePng:
       
   706         return KPng;
       
   707     case ESwtImageJpeg:
       
   708         return KJpg;
       
   709     default:
       
   710         ASSERT(EFalse);
       
   711         return KNullDesC8;
       
   712     }
       
   713 }
       
   714 
       
   715 //lint +esym( 613, CSwtImageDataLoader::iDecoder )
       
   716 //lint +esym( 613, CSwtImageDataLoader::iEncoder )