phonebookui/Phonebook/View/src/CPbkImageReader.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002 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 *           Provides Phonebook image reader class methods.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CPbkImageReader.h"
       
    22 #include "MPbkImageReaderObserver.h"
       
    23 #include "TPbkImageLoadParameters.h"
       
    24 
       
    25 #include <imageconversion.h>
       
    26 #include <bitmaptransforms.h>
       
    27 
       
    28 /// Unnamed namespace for local defintions
       
    29 namespace {
       
    30 
       
    31 // LOCAL CONSTANTS AND MACROS
       
    32 
       
    33 enum TReaderState
       
    34     {
       
    35     EStateIntialize = 0,
       
    36     EStateOpenImage,
       
    37     EStateConvertImageToBitmap,
       
    38     EStateScaleBitmap,
       
    39     EStateComplete,
       
    40     EStateCancelled
       
    41     };
       
    42 
       
    43 const TInt KMaxMimeTypeLength = 256;
       
    44 
       
    45 #ifdef _DEBUG
       
    46 enum TPanicCode
       
    47     {
       
    48     EPanicPreCond_ConvertImageToBitmapL = 1,
       
    49     EPanicPreCond_ScaleBitmapL,
       
    50     EPanicPreCond_Complete,
       
    51     EPanicPostCond_Complete,
       
    52     EPanicPostCond_OptimalLoadingSize
       
    53     };
       
    54 #endif
       
    55 
       
    56 
       
    57 // ==================== LOCAL FUNCTIONS ====================
       
    58 
       
    59 #ifdef _DEBUG
       
    60 void Panic(TPanicCode aPanicCode)
       
    61     {
       
    62     _LIT(KPanicText, "CPbkImageReader");
       
    63     User::Panic(KPanicText, aPanicCode);
       
    64     }
       
    65 #endif
       
    66 
       
    67 inline TBool operator<=(const TSize& aLhs, const TSize& aRhs)
       
    68     {
       
    69     return (aLhs.iWidth<=aRhs.iWidth && aLhs.iHeight<=aRhs.iHeight);
       
    70     }
       
    71 
       
    72 // Copied from CPalbBitmap, remove when possible
       
    73 TInt Ceil(const TInt aVal, const TInt aDiv)
       
    74     {
       
    75     return (((aVal%aDiv)>0) ? (TInt)((aVal/aDiv)+1):(TInt)(aVal/aDiv));
       
    76     }
       
    77 
       
    78 // Copied from CPalbBitmap, remove when possible
       
    79 TSize SizeDividedByValueAndCeil(const TSize& aSize, const TInt aDiv)
       
    80     {
       
    81     return TSize(
       
    82         Ceil( aSize.iWidth, aDiv), 
       
    83         Ceil( aSize.iHeight, aDiv) );
       
    84     }
       
    85 
       
    86 // Copied from CPalbBitmap, remove when possible
       
    87 TSize OptimalLoadingSize(const TSize& aOriginalSize, const TSize& aNeededSize)
       
    88     {
       
    89     TSize resSize = SizeDividedByValueAndCeil( aOriginalSize, 8 );
       
    90     if( !(aNeededSize <= resSize) )
       
    91         {
       
    92         resSize = SizeDividedByValueAndCeil( aOriginalSize, 4 );
       
    93         if( !(aNeededSize <= resSize) )
       
    94             {
       
    95             resSize = SizeDividedByValueAndCeil( aOriginalSize, 2 );
       
    96             if( !(aNeededSize <= resSize) )
       
    97                 {
       
    98                 resSize = aOriginalSize;
       
    99                 }
       
   100             }
       
   101         }
       
   102 
       
   103     // if the resulting size is not the original size,
       
   104     // it has to be between needed size and original size
       
   105     __ASSERT_DEBUG(resSize == aOriginalSize
       
   106                    || (aNeededSize <= resSize && resSize <= aOriginalSize),
       
   107                    Panic(EPanicPostCond_OptimalLoadingSize));
       
   108 
       
   109     return resSize;
       
   110     }
       
   111 
       
   112 }  // namespace
       
   113 
       
   114 
       
   115 // ================= MEMBER FUNCTIONS =======================
       
   116 
       
   117 inline CPbkImageReader::CPbkImageReader
       
   118         (MPbkImageReaderObserver& aObserver) :
       
   119     CActive(CActive::EPriorityStandard),
       
   120     iObserver(aObserver)
       
   121     {
       
   122     CActiveScheduler::Add(this);
       
   123     }
       
   124 
       
   125 CPbkImageReader* CPbkImageReader::NewL
       
   126         (MPbkImageReaderObserver& aObserver)
       
   127     {
       
   128     CPbkImageReader* self = new(ELeave) CPbkImageReader(aObserver);
       
   129     CleanupStack::PushL(self);
       
   130     self->ConstructL();
       
   131     CleanupStack::Pop(self);
       
   132     return self;
       
   133     }
       
   134 
       
   135 void CPbkImageReader::ConstructL()
       
   136     {
       
   137     User::LeaveIfError(iFsSession.Connect());
       
   138     }
       
   139 
       
   140 CPbkImageReader::~CPbkImageReader()
       
   141     {
       
   142     Cancel();
       
   143     delete iBitmapScaler;
       
   144     delete iImageDecoder;
       
   145     delete iMimeString;
       
   146     delete iBitmap;
       
   147     iFsSession.Close();
       
   148     }
       
   149 
       
   150 void CPbkImageReader::ReadFromFileL
       
   151         (const TDesC& aFileName, const TPbkImageLoadParameters* aParams)
       
   152     {
       
   153     InitReadL(aParams);
       
   154     delete iImageDecoder;
       
   155     iImageDecoder = NULL;
       
   156     iImageDecoder = CImageDecoder::FileNewL(iFsSession, aFileName);
       
   157 
       
   158     // Make the open phase asynchronous as well by signaling own iStatus
       
   159     iState = EStateOpenImage;
       
   160     TRequestStatus* status = &iStatus;
       
   161     User::RequestComplete(status, KErrNone);
       
   162     SetActive();
       
   163     }
       
   164 
       
   165 void CPbkImageReader::ReadFromBufferL
       
   166         (const TDesC8& aBuffer, const TPbkImageLoadParameters* aParams/*=NULL*/)
       
   167     {
       
   168     InitReadL(aParams);
       
   169     delete iImageDecoder;
       
   170     iImageDecoder = NULL;
       
   171     iImageDecoder = CImageDecoder::DataNewL(iFsSession, aBuffer);
       
   172 
       
   173     // Make the open phase asynchronous as well by signaling own iStatus
       
   174     iState = EStateOpenImage;
       
   175     TRequestStatus* status = &iStatus;
       
   176     User::RequestComplete(status, KErrNone);
       
   177     SetActive();
       
   178     }
       
   179 
       
   180 const TDesC8& CPbkImageReader::MimeString() const
       
   181     {
       
   182     if (iMimeString)
       
   183         {
       
   184         return *iMimeString;
       
   185         }
       
   186     else
       
   187         {
       
   188         return KNullDesC8;
       
   189         }
       
   190     }
       
   191 
       
   192 void CPbkImageReader::RecognizeFormatFromFileL(const TDesC& aFileName)
       
   193     {
       
   194     delete iMimeString;
       
   195     iMimeString = NULL;
       
   196     iMimeString = HBufC8::NewL(KMaxMimeTypeLength);
       
   197     TPtr8 mimePtr = iMimeString->Des();
       
   198     CImageDecoder::GetMimeTypeFileL(iFsSession, aFileName, mimePtr);
       
   199     }
       
   200 
       
   201 void CPbkImageReader::RecognizeFormatFromBufferL(const TDesC8& aBuffer)
       
   202     {
       
   203     delete iMimeString;
       
   204     iMimeString = NULL;
       
   205     iMimeString = HBufC8::NewL(KMaxMimeTypeLength);
       
   206     TPtr8 mimePtr = iMimeString->Des();
       
   207     CImageDecoder::GetMimeTypeDataL(aBuffer, mimePtr);
       
   208     }
       
   209 
       
   210 void CPbkImageReader::FrameInfo(TInt aFrame, TFrameInfo& aInfo) const
       
   211     {
       
   212     aInfo = iImageDecoder->FrameInfo(aFrame);
       
   213     }
       
   214 
       
   215 TInt CPbkImageReader::FrameCount() const
       
   216     {
       
   217     return iImageDecoder->FrameCount();
       
   218     }
       
   219 
       
   220 void CPbkImageReader::NextStateL()
       
   221     {
       
   222     ++iState;
       
   223 
       
   224     switch (iState)
       
   225         {
       
   226         case EStateConvertImageToBitmap:
       
   227             {
       
   228             ConvertImageToBitmapL();
       
   229             break;
       
   230             }
       
   231         case EStateScaleBitmap:
       
   232             {
       
   233             ScaleBitmapL();
       
   234             break;
       
   235             }
       
   236         case EStateComplete:
       
   237             {
       
   238             Complete();
       
   239             break;
       
   240             }
       
   241         default:
       
   242             {
       
   243             // iImageReader might sometimes complete although it has been canceled!
       
   244             // Catch those cases here.
       
   245             break;
       
   246             }
       
   247         }
       
   248     }
       
   249 
       
   250 void CPbkImageReader::ConvertImageToBitmapL()
       
   251     {
       
   252     __ASSERT_DEBUG(iImageDecoder && !iBitmap, 
       
   253         Panic(EPanicPreCond_ConvertImageToBitmapL));
       
   254 
       
   255     // Get image size
       
   256     const TFrameInfo& frameInfo = 
       
   257         iImageDecoder->FrameInfo(iParams.iFrameNumber);
       
   258     TSize bitmapSize = frameInfo.iOverallSizeInPixels;
       
   259     if (iParams.iFlags & TPbkImageLoadParameters::EScaleImage)
       
   260         {
       
   261         // Get optimal loading size >= desired size
       
   262         bitmapSize = OptimalLoadingSize(bitmapSize,iParams.iSize);
       
   263         }
       
   264 
       
   265     // Create bitmap
       
   266     delete iBitmap;
       
   267 	iBitmap = NULL;
       
   268     iBitmap = new(ELeave) CFbsBitmap;
       
   269     User::LeaveIfError(iBitmap->Create(bitmapSize,iParams.iDisplayMode));
       
   270 
       
   271     // Convert image to bitmap
       
   272     iImageDecoder->Convert(&iStatus, *iBitmap, iParams.iFrameNumber);
       
   273     SetActive();
       
   274     }
       
   275 
       
   276 void CPbkImageReader::ScaleBitmapL()
       
   277     {
       
   278     __ASSERT_DEBUG(iBitmap, Panic(EPanicPreCond_ScaleBitmapL));
       
   279 
       
   280     if ((iParams.iFlags & TPbkImageLoadParameters::EScaleImage) && 
       
   281         !(iParams.iFlags & TPbkImageLoadParameters::EUseFastScaling))
       
   282         {
       
   283         const TSize bitmapSize = iBitmap->SizeInPixels();
       
   284         if (bitmapSize.iWidth > iParams.iSize.iWidth || 
       
   285             bitmapSize.iHeight > iParams.iSize.iHeight)
       
   286             {
       
   287             if (!iBitmapScaler)
       
   288                 {
       
   289                 iBitmapScaler = CBitmapScaler::NewL();
       
   290                 }
       
   291             iBitmapScaler->Scale(&iStatus, *iBitmap, iParams.iSize);
       
   292             SetActive();
       
   293             return;
       
   294             }
       
   295         }
       
   296 
       
   297     // No scaling requested or needed, go directly to next state
       
   298     NextStateL();
       
   299     }
       
   300 
       
   301 void CPbkImageReader::Complete()
       
   302     {
       
   303     __ASSERT_DEBUG(iImageDecoder && iBitmap, Panic(EPanicPreCond_Complete));
       
   304 
       
   305     // End state machine
       
   306     ++iState;
       
   307 
       
   308     // Close the image source
       
   309     CloseImage();
       
   310 
       
   311     // Release ownership of iBitmap
       
   312     CFbsBitmap* bitmap = iBitmap;
       
   313     iBitmap = NULL;
       
   314 
       
   315     __ASSERT_DEBUG(!iImageDecoder && !iBitmap, 
       
   316         Panic(EPanicPostCond_Complete));
       
   317 
       
   318     // Notify observer about completion
       
   319     iObserver.ImageReadComplete(*this,bitmap);
       
   320     }
       
   321 
       
   322 void CPbkImageReader::InitReadL(const TPbkImageLoadParameters* aParams)
       
   323     {
       
   324     Cancel();
       
   325     if (aParams)
       
   326         {
       
   327         iParams = *aParams;
       
   328         }
       
   329     iState = EStateOpenImage;
       
   330     }
       
   331 
       
   332 void CPbkImageReader::CloseImage()
       
   333     {
       
   334     delete iImageDecoder;
       
   335     iImageDecoder = NULL;
       
   336     }
       
   337 
       
   338 void CPbkImageReader::RunL()
       
   339     {
       
   340     TInt status = iStatus.Int();
       
   341     switch (status)
       
   342         {
       
   343         case KErrNone:
       
   344             {
       
   345             if (iState == EStateOpenImage)
       
   346                 {
       
   347                 iObserver.ImageOpenComplete(*this);
       
   348                 }
       
   349             NextStateL();
       
   350             break;
       
   351             }
       
   352         case KErrCancel:
       
   353             {
       
   354             // In case of cancel the observer is not signaled
       
   355             break;
       
   356             }
       
   357         default:
       
   358             {
       
   359             iObserver.ImageReadFailed(*this, status);
       
   360             break;
       
   361             }
       
   362         }
       
   363     }
       
   364 
       
   365 void CPbkImageReader::Cancel()
       
   366     {
       
   367     if (!IsActive())
       
   368         {
       
   369         DoCancel();
       
   370         }
       
   371     else
       
   372         {
       
   373         CActive::Cancel();
       
   374         }
       
   375     }
       
   376 
       
   377 TInt CPbkImageReader::RunError(TInt aError)
       
   378     {
       
   379     iObserver.ImageReadFailed(*this, aError);
       
   380     return KErrNone;
       
   381     }
       
   382 
       
   383 void CPbkImageReader::DoCancel()
       
   384     {
       
   385     if (iImageDecoder)
       
   386         {
       
   387         iImageDecoder->Cancel();
       
   388         }
       
   389     if (iBitmapScaler)
       
   390         {
       
   391         iBitmapScaler->Cancel();
       
   392         }
       
   393     CloseImage();
       
   394     delete iBitmap;
       
   395     iBitmap = NULL;
       
   396     iState = EStateCancelled;
       
   397     }
       
   398 
       
   399 //  End of File