javauis/lcdui_akn/lcdgr/src/CMIDImageDecoder.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2005 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:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "CMIDImageDecoder.h"
       
    19 #include "LcdFbsImage.h"
       
    20 #include <j2me/jdebug.h>
       
    21 
       
    22 CMIDImageDecoder::CMIDImageDecoder(RFs& aFsSession, TDisplayMode aDisplayMode)
       
    23         : CActive(CActive::EPriorityStandard), iRFsSession(aFsSession), iDisplayMode(aDisplayMode)
       
    24 {
       
    25     CActiveScheduler::Add(this);
       
    26     iRFsSession = aFsSession;
       
    27 }
       
    28 
       
    29 void CMIDImageDecoder::ConstructL()
       
    30 {
       
    31     iDecoder = CBufferedImageDecoder::NewL(iRFsSession);
       
    32 }
       
    33 
       
    34 CMIDImageDecoder::~CMIDImageDecoder()
       
    35 {
       
    36     Cancel();
       
    37     ASSERT(NULL == iCallback);
       
    38     delete iBitmapImage;
       
    39     delete iDecoder;
       
    40 }
       
    41 
       
    42 void CMIDImageDecoder::AppendL(const TDesC8& aBuffer)
       
    43 {
       
    44     TInt err = KErrNone;
       
    45 
       
    46     if (iState == EStart)
       
    47     {
       
    48         TRAP(err, iDecoder->OpenL(aBuffer, CImageDecoder::EOptionPngMissingiENDFail));
       
    49 
       
    50         if (err == KEComErrNoInterfaceIdentified || err == KErrNotFound)
       
    51         {
       
    52             // If the format is unrecognised AND the first 2 bytes are 0 then we assume it
       
    53             // is a WBMP. This is a requirement of the below defect.
       
    54             // The first two bytes of other formats (e.g. ico) may also begin with 0, 0
       
    55             // but they should have already been recognised by the first call to OpenL
       
    56             if (aBuffer[0] == 0 && aBuffer[1] == 0)
       
    57             {
       
    58                 delete iDecoder;
       
    59                 iDecoder = NULL;
       
    60                 iDecoder = CBufferedImageDecoder::NewL(iRFsSession);
       
    61                 DEBUG("* CMIDImageDecoder::AppendL - Format can't be fully identified, assuming this is WBMP");
       
    62                 _LIT8(KWBMPMimeType, "image/vnd.wap.wbmp");
       
    63                 TRAP(err, iDecoder->OpenL(aBuffer, KWBMPMimeType, CImageDecoder::EOptionPngMissingiENDFail));
       
    64             }
       
    65         }
       
    66 
       
    67         if ((err != KErrUnderflow) && (err != KEComErrNoInterfaceIdentified) && (err != KErrNotFound))
       
    68         {
       
    69             //
       
    70             // something's gone wrong that we can't fix by appending more data
       
    71             //
       
    72             User::LeaveIfError(err);
       
    73         }
       
    74         iState = EOpenPending;
       
    75     }
       
    76     else
       
    77     {
       
    78         iDecoder->AppendDataL(aBuffer);
       
    79 
       
    80         if (!iDecoder->ValidDecoder())
       
    81         {
       
    82             TRAP(err, iDecoder->ContinueOpenL());
       
    83             if ((err == KErrUnderflow) || (err == KEComErrNoInterfaceIdentified) || (err == KErrNotFound))
       
    84             {
       
    85                 // decoder or framework needs more data to determine codec.
       
    86                 return;
       
    87             }
       
    88 
       
    89             //
       
    90             // If something else has gone wrong then we can't fix by appending more data
       
    91             //
       
    92             User::LeaveIfError(err);
       
    93         }
       
    94     }
       
    95 
       
    96     if (iDecoder->ValidDecoder())
       
    97     {
       
    98         if (!iDecoder->IsImageHeaderProcessingComplete())
       
    99         {
       
   100             iDecoder->ContinueProcessingHeaderL();
       
   101             if (iDecoder->IsImageHeaderProcessingComplete())
       
   102             {
       
   103                 iState = EOpenComplete;
       
   104             }
       
   105         }
       
   106         else
       
   107         {
       
   108             iState = EOpenComplete;
       
   109         }
       
   110     }
       
   111 }
       
   112 
       
   113 void NullPointer(TAny* aPtr)
       
   114 {
       
   115     * static_cast<TAny**>(aPtr) = NULL;
       
   116 }
       
   117 
       
   118 void CMIDImageDecoder::DecodeL(MMIDImageObserver* aCallback)
       
   119 {
       
   120     //
       
   121     // If we are asked to decode, but have not yet managed to process the
       
   122     // image header we leave with KErrCorrrupt indicating that we think
       
   123     // the encoded image data is corrupt.
       
   124     //
       
   125     if (iState < EOpenComplete)
       
   126     {
       
   127         User::Leave(KErrCorrupt);
       
   128     }
       
   129     ASSERT(NULL == iCallback);
       
   130     CleanupStack::PushL(TCleanupItem(NullPointer, &iCallback));
       
   131     iCallback = aCallback;
       
   132     ConvertL();
       
   133     CleanupStack::Pop();
       
   134 }
       
   135 
       
   136 void CMIDImageDecoder::Complete(TInt aResult)
       
   137 {
       
   138     if (iCallback)
       
   139     {
       
   140         iCallback->DecodeComplete(aResult);
       
   141         iCallback = NULL;
       
   142     }
       
   143 }
       
   144 
       
   145 void CMIDImageDecoder::ConvertL()
       
   146 {
       
   147     iState = EConvertPending;
       
   148 
       
   149     if (NULL == iBitmapImage)
       
   150     {
       
   151         const TFrameInfo& frameInfo = iDecoder->FrameInfo();
       
   152 
       
   153         TSize size = frameInfo.iOverallSizeInPixels;
       
   154 
       
   155         // S60: Set the colormode of the bitmap to be exactly as the phone's display.
       
   156         // This will cause CLcdImage class just to duplicate the handle of this image,
       
   157         // and not converting the pixels from the image's original color format to phone's color format.
       
   158         // The image is needed to be in the same color format as the phone's display so BitBlt() is the most efficient.
       
   159         //
       
   160         // Decoding directly to 16MA does not work in 5.0 HW. It works only in emulator and not for JPEG.
       
   161         // The image decoders need to fix this.
       
   162         // We decode to 16MU still and then a conversion from 16MU->16MA will be done
       
   163         //
       
   164         // Insufficient information available to load image in its natural format.
       
   165 
       
   166         TDisplayMode colorMode = frameInfo.iFrameDisplayMode;
       
   167         TDisplayMode alphaMode = ENone;
       
   168 
       
   169         if (frameInfo.iFlags & TFrameInfo::ETransparencyPossible)
       
   170         {
       
   171             if (frameInfo.iFlags & TFrameInfo::EAlphaChannel)
       
   172             {
       
   173                 alphaMode = EGray256;
       
   174             }
       
   175             else
       
   176             {
       
   177                 alphaMode = EGray2;
       
   178             }
       
   179         }
       
   180 
       
   181         //
       
   182         // This step is the most likely to fail in low memory conditions.
       
   183         //
       
   184         CLcdFbsImage* fbsImage = CLcdFbsImage::NewL(size, colorMode, alphaMode);
       
   185         CleanupStack::PushL(fbsImage);
       
   186         iBitmapImage = new(ELeave) CMIDBitmapImage(*fbsImage);
       
   187         CleanupStack::Pop(fbsImage);
       
   188     }
       
   189 
       
   190     CFbsBitmap* colorBitmap = iBitmapImage->ColorBitmap();
       
   191     CFbsBitmap* alphaBitmap = iBitmapImage->AlphaBitmap();
       
   192 
       
   193     if (alphaBitmap)
       
   194     {
       
   195         iDecoder->Convert(&iStatus, *colorBitmap, *alphaBitmap, 0);
       
   196     }
       
   197     else
       
   198     {
       
   199         iDecoder->Convert(&iStatus, *colorBitmap, 0);
       
   200     }
       
   201     SetActive();
       
   202 }
       
   203 
       
   204 void CMIDImageDecoder::Dispose()
       
   205 {
       
   206     delete this;
       
   207 }
       
   208 
       
   209 MMIDBitmapImage* CMIDImageDecoder::BitmapImage() const
       
   210 {
       
   211     return iBitmapImage;
       
   212 }
       
   213 
       
   214 void CMIDImageDecoder::RunL()
       
   215 {
       
   216     ASSERT(iState == EConvertPending);
       
   217     Complete(iStatus.Int());
       
   218 }
       
   219 
       
   220 TInt CMIDImageDecoder::RunError(TInt aError)
       
   221 {
       
   222     ASSERT(KErrNone == aError);   // should never happen
       
   223     return aError;
       
   224 }
       
   225 
       
   226 void CMIDImageDecoder::DoCancel()
       
   227 {
       
   228     ASSERT(iState == EConvertPending);
       
   229     iDecoder->Cancel();
       
   230 }
       
   231 
       
   232