videofeeds/utils/src/vcxnsimageconverter.cpp
changeset 0 96612d01cf9f
equal deleted inserted replaced
-1:000000000000 0:96612d01cf9f
       
     1 /*
       
     2 * Copyright (c) 2009-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 the License "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:    Converter that creates icons from picture files.*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <AknUtils.h>        // TAknWindowLineLayout
       
    22 #include <gulicon.h>         // CGulIcon
       
    23 #include <bautils.h>         // BaflUtils
       
    24 #include <imageconversion.h> // Image converter
       
    25 #include <AknIconUtils.h>
       
    26 
       
    27 #include "vcxnsimageconverter.h"
       
    28 #include "vcxnsimageconverterobserver.h"
       
    29 #include "IptvDebug.h"
       
    30 
       
    31 _LIT(KMifExtension, ".mif");
       
    32 
       
    33 
       
    34 // ============================ LOCAL FUNCTIONS ================================
       
    35 
       
    36 void ScaleBitmapL( CFbsBitmap*& aImage, TSize aSize )
       
    37     {
       
    38     if ( aImage )
       
    39         {
       
    40         CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
       
    41         CleanupStack::PushL( bitmap );
       
    42         bitmap->Create( aSize, aImage->DisplayMode() );
       
    43         AknIconUtils::ScaleBitmapL( aSize, bitmap, aImage );
       
    44         delete aImage;
       
    45         aImage = bitmap;
       
    46         CleanupStack::Pop( bitmap );
       
    47         }
       
    48     }
       
    49 
       
    50 // ============================ MEMBER FUNCTIONS ===============================
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CVcxNsImageConverter::CVcxNsImageConverter()
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CVcxNsImageConverter::CVcxNsImageConverter(
       
    57     MVcxNsImageConverterObserver& aObserver,
       
    58     RFs& aFsSession )
       
    59   : CActive( EPriorityStandard ),
       
    60     iFsSession( aFsSession ),
       
    61     iSynchronous( EFalse ),
       
    62     iConvertingMif( EFalse ),
       
    63     iMifBitmapId( 0 ),
       
    64     iMifMaskId( 0 ),
       
    65     iObserver( aObserver )
       
    66     {
       
    67     }
       
    68 
       
    69 // -----------------------------------------------------------------------------
       
    70 // CVcxNsImageConverter::ConstructL()
       
    71 // -----------------------------------------------------------------------------
       
    72 //
       
    73 void CVcxNsImageConverter::ConstructL()
       
    74     {
       
    75     CActiveScheduler::Add( this );
       
    76     }
       
    77 
       
    78 // -----------------------------------------------------------------------------
       
    79 // CVcxNsImageConverter::NewL()
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 EXPORT_C CVcxNsImageConverter* CVcxNsImageConverter::NewL(
       
    83     MVcxNsImageConverterObserver& aObserver,
       
    84     RFs& aFsSession )
       
    85     {
       
    86     IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::NewL()");
       
    87 
       
    88     CVcxNsImageConverter* self = new (ELeave) CVcxNsImageConverter(
       
    89             aObserver, aFsSession );
       
    90     CleanupStack::PushL( self );
       
    91     self->ConstructL();
       
    92     CleanupStack::Pop( self );
       
    93     return self;
       
    94     }
       
    95 
       
    96 // -----------------------------------------------------------------------------
       
    97 // CVcxNsImageConverter::~CVcxNsImageConverter()
       
    98 // -----------------------------------------------------------------------------
       
    99 //
       
   100 CVcxNsImageConverter::~CVcxNsImageConverter()
       
   101     {
       
   102     IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::~CVcxNsImageConverter()");
       
   103 
       
   104     Cancel();
       
   105 
       
   106     // If decoder is cancelled, these might stay reserved.
       
   107     delete iDecoder;
       
   108     delete iBitmap;
       
   109     delete iMask;
       
   110     delete iMifFileName;
       
   111     }
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // CVcxNsImageConverter::GetImageType()
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 EXPORT_C TInt CVcxNsImageConverter::GetImageType(
       
   118     const TDesC& aFileName,
       
   119     TImageType& aImageType )
       
   120     {
       
   121     IPTVLOGSTRING2_LOW_LEVEL("CVcxNsImageConverter::GetImageType() %S", &aFileName);
       
   122 
       
   123     TBuf<KFileExtensionLength> ext;
       
   124 
       
   125     if ( GetExtension( aFileName, ext ))
       
   126         {
       
   127         ext.LowerCase();
       
   128 
       
   129         if ( ext.Compare( KMifExtension )) // Returns zero if match.
       
   130             {
       
   131             aImageType = EOther;
       
   132             }
       
   133         else
       
   134             {
       
   135             aImageType = EMif;
       
   136             }
       
   137 
       
   138         return KErrNone;
       
   139         }
       
   140 
       
   141     return KErrGeneral;
       
   142     }
       
   143 
       
   144 // -----------------------------------------------------------------------------
       
   145 // CVcxNsImageConverter::ConvertL()
       
   146 // Converts image file synchronoysly.
       
   147 // -----------------------------------------------------------------------------
       
   148 //
       
   149 EXPORT_C CGulIcon* CVcxNsImageConverter::ConvertL(
       
   150     const TDesC& aFileName,
       
   151     TSize aImageSize,
       
   152     TBool aCreateMask )
       
   153     {
       
   154     IPTVLOGSTRING2_LOW_LEVEL("CVcxNsImageConverter::ConvertL(picture) %S", &aFileName);
       
   155 
       
   156     CGulIcon* icon = NULL;
       
   157 
       
   158     // Start sycnhronous image convert
       
   159     iSynchronous = ETrue;
       
   160 
       
   161     if ( StartConvertL( aFileName, aImageSize, aCreateMask ) == KErrNone)
       
   162         {
       
   163         CActiveScheduler::Start();
       
   164 
       
   165         if ( iStatus == KErrNone )
       
   166             {
       
   167             if ( !iImageScalable ) // use AknIconUtils:ScaleBitmap to scale image.
       
   168                 {
       
   169                 ScaleBitmapL( iBitmap, iMifImageSize );
       
   170                 ScaleBitmapL( iMask, iMifImageSize );
       
   171                 }
       
   172 
       
   173             icon = CGulIcon::NewL( iBitmap, iMask );
       
   174             icon->SetBitmapsOwnedExternally( EFalse );
       
   175 
       
   176             iBitmap = NULL; // Not owned by us anymore.
       
   177             iMask   = NULL;
       
   178             }
       
   179         }
       
   180 
       
   181     return icon;
       
   182     }
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // CVcxNsImageConverter::ConvertL()
       
   186 // Converts mif file synchronoysly.
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 EXPORT_C CGulIcon* CVcxNsImageConverter::ConvertL(
       
   190     const TDesC& aFileName,
       
   191     TSize aImageSize,
       
   192     TInt aBitmapId,
       
   193     TInt aMaskId )
       
   194     {
       
   195     IPTVLOGSTRING2_LOW_LEVEL("CVcxNsImageConverter::ConvertL(mif) %S", &aFileName);
       
   196 
       
   197 	CFbsBitmap* bitmap = NULL;
       
   198     CFbsBitmap* mask = NULL;
       
   199 
       
   200     if ( aFileName.Length() == 0 )
       
   201         {
       
   202         IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::ConvertL(mif) file did not exist.");
       
   203         return NULL;
       
   204         }
       
   205 
       
   206     // Skip the file-existence check with file names starting with \ -character.
       
   207     // BaflUtils cannot handle these (e.g. select drive) so it would fail.
       
   208     if ( aFileName[0] != '\\' )
       
   209         {
       
   210         if ( ! BaflUtils::FileExists( iFsSession, aFileName ) )
       
   211             {
       
   212             IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::ConvertL(mif) file did not exist.");
       
   213             return NULL;
       
   214             }
       
   215         }
       
   216 
       
   217     AknIconUtils::CreateIconLC(bitmap, mask, aFileName, aBitmapId, aMaskId);
       
   218 
       
   219     CGulIcon* icon = CGulIcon::NewL(bitmap, mask);
       
   220     CleanupStack::PushL(icon);
       
   221 
       
   222     // ownership of bitmap and mask transferred to icon
       
   223     icon->SetBitmapsOwnedExternally(EFalse);
       
   224 
       
   225     AknIconUtils::SetSize(bitmap, aImageSize);
       
   226     AknIconUtils::SetSize(mask, aImageSize);
       
   227 
       
   228     CleanupStack::Pop(icon);
       
   229     CleanupStack::Pop(mask);
       
   230     CleanupStack::Pop(bitmap);
       
   231 
       
   232     return icon;
       
   233     }
       
   234 
       
   235 // -----------------------------------------------------------------------------
       
   236 // CVcxNsImageConverter::StartConvertL()
       
   237 // Starts converting image file asynchronously.
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 EXPORT_C TInt CVcxNsImageConverter::StartConvertL(
       
   241     const TDesC& aFileName,
       
   242     TSize aReqSize,
       
   243     TBool aCreateMask )
       
   244     {
       
   245     IPTVLOGSTRING2_LOW_LEVEL("CVcxNsImageConverter::StartConvertL(picture) %S", &aFileName);
       
   246 
       
   247     if ( IsActive() )
       
   248         {
       
   249         return KErrInUse;
       
   250         }
       
   251 
       
   252     if ( iDecoder )
       
   253         {
       
   254         iDecoder->Cancel();
       
   255         delete iDecoder;
       
   256         iDecoder = NULL;
       
   257         }
       
   258 
       
   259     if ( ! BaflUtils::FileExists( iFsSession, aFileName ) )
       
   260         {
       
   261         IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::StartConvertL(picture) file did not exist.");
       
   262         return KErrNotFound;
       
   263         }
       
   264 
       
   265     TRAPD( createError, { iDecoder = CImageDecoder::FileNewL( iFsSession, aFileName ); } );
       
   266 
       
   267     if ( createError != KErrNone )
       
   268         {
       
   269         IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::StartConvertL(picture) file not supported?");
       
   270         return createError;
       
   271         }
       
   272 
       
   273     // original image size
       
   274     TFrameInfo info     = iDecoder->FrameInfo();
       
   275     TSize      trueSize = info.iOverallSizeInPixels;
       
   276     TSize      wantedSize( trueSize );
       
   277     iImageScalable = info.iFlags & TFrameInfo::EFullyScaleable;
       
   278 
       
   279     // Count mismatch of true size to requested size in horisontal and vertical direction.
       
   280     TReal verticalMismatch   = ((TReal) trueSize.iHeight) / ((TReal) aReqSize.iHeight);
       
   281     TReal horisontalMismatch = ((TReal) trueSize.iWidth)  / ((TReal) aReqSize.iWidth);
       
   282 
       
   283     if (verticalMismatch == 0 || horisontalMismatch == 0)
       
   284         {
       
   285         return KErrDivideByZero;
       
   286         }
       
   287 
       
   288     // Picture size is more off the requested size horisontally than vertically.
       
   289     if (horisontalMismatch > verticalMismatch)
       
   290         {
       
   291         wantedSize.SetSize((TInt) aReqSize.iWidth,                                   // Width
       
   292                          (TInt) (((TReal)trueSize.iHeight) / horisontalMismatch)); // Height
       
   293         }
       
   294     // Picture size is more off the requested size vertically than horisontally.
       
   295     else
       
   296         {
       
   297         wantedSize.SetSize((TInt) (((TReal)trueSize.iWidth) / verticalMismatch), // Width
       
   298                          (TInt) aReqSize.iHeight);                             // Height
       
   299         }
       
   300     
       
   301     // Make sure size we did not go over the requested limits because
       
   302     // of rounding errors or other additions made to rectangle.
       
   303     if (wantedSize.iWidth > aReqSize.iWidth)
       
   304         {
       
   305         wantedSize.iWidth = aReqSize.iWidth;
       
   306         }
       
   307     if (wantedSize.iHeight > aReqSize.iHeight)
       
   308         {
       
   309         wantedSize.iHeight = aReqSize.iHeight;
       
   310         }
       
   311 
       
   312     if ( iImageScalable )
       
   313         {
       
   314         trueSize = wantedSize;
       
   315         }
       
   316     else
       
   317         {
       
   318         iMifImageSize = wantedSize;
       
   319         }
       
   320 
       
   321     // create bitmap for the proper size
       
   322     iBitmap = new ( ELeave ) CFbsBitmap();
       
   323     iBitmap->Create( trueSize, info.iFrameDisplayMode );
       
   324 
       
   325     // create mask if available and requested.
       
   326     if ( aCreateMask && (info.iFlags & TFrameInfo::ETransparencyPossible) )
       
   327         {
       
   328         iMask = new (ELeave) CFbsBitmap;
       
   329 
       
   330         if ( info.iFlags & TFrameInfo::EAlphaChannel )
       
   331             {
       
   332             iMask->Create( trueSize, EGray256 );
       
   333             }
       
   334         else
       
   335             {
       
   336             iMask->Create( trueSize, EGray2 );
       
   337             }
       
   338         }
       
   339     else
       
   340         {
       
   341         iMask = NULL;
       
   342         }
       
   343 
       
   344     // start converting.
       
   345     if (iMask)
       
   346         {
       
   347         iDecoder->Convert( &iStatus, *iBitmap, *iMask );
       
   348         }
       
   349     else
       
   350         {
       
   351         iDecoder->Convert( &iStatus, *iBitmap );
       
   352         }
       
   353 
       
   354     // start waiting for completion
       
   355     iConvertingMif = EFalse;
       
   356     SetActive();
       
   357     return KErrNone;
       
   358     }
       
   359 
       
   360 // -----------------------------------------------------------------------------
       
   361 // CVcxNsImageConverter::StartConvertL()
       
   362 // Starts converting mif file asynchronously.
       
   363 // -----------------------------------------------------------------------------
       
   364 //
       
   365 EXPORT_C TInt CVcxNsImageConverter::StartConvertL(
       
   366     const TDesC& aFileName,
       
   367     TSize aImageSize,
       
   368     TInt aBitmapId,
       
   369     TInt aMaskId )
       
   370     {
       
   371     IPTVLOGSTRING2_LOW_LEVEL("CVcxNsImageConverter::StartConvertL(mif) %S", &aFileName);
       
   372 
       
   373     if ( IsActive() )
       
   374         {
       
   375         return KErrInUse;
       
   376         }
       
   377 
       
   378     delete iMifFileName;
       
   379     iMifFileName = NULL;
       
   380 
       
   381     iMifFileName  = HBufC16::NewL( aFileName.Length() );
       
   382     *iMifFileName = aFileName;
       
   383     iMifImageSize = aImageSize;
       
   384     iMifBitmapId  = aBitmapId;
       
   385     iMifMaskId    = aMaskId;
       
   386 
       
   387     iConvertingMif = ETrue;
       
   388 
       
   389     // Sets this object as active and completes immediately, but asynchronously.
       
   390     SetActive();
       
   391     iStatus = KRequestPending;
       
   392     TRequestStatus* stat = &iStatus;
       
   393     User::RequestComplete(stat, KErrNone);
       
   394     return KErrNone;
       
   395     }
       
   396 
       
   397 // -----------------------------------------------------------------------------
       
   398 // CVcxNsImageConverter::RunL()
       
   399 // From CActive, called when converting is done
       
   400 // -----------------------------------------------------------------------------
       
   401 //
       
   402 void CVcxNsImageConverter::RunL()
       
   403     {
       
   404     if ( iConvertingMif )
       
   405         {
       
   406         IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::RunL() after mif conversion.");
       
   407 
       
   408         CGulIcon* icon = ConvertL( *iMifFileName, iMifImageSize, iMifBitmapId, iMifMaskId );
       
   409 
       
   410         iObserver.ImageConversionCompletedL( (icon ? KErrNone : KErrGeneral), icon );
       
   411         }
       
   412     else // Converting image
       
   413         {
       
   414         IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::RunL() after image conversion.");
       
   415         
       
   416         // Free decoder. Otherwise the last image file (on disk) stays reserved
       
   417         // until client releases this object (CVcxNsImageConverter).
       
   418         if ( iDecoder )
       
   419             {
       
   420             iDecoder->Cancel();
       
   421             delete iDecoder;
       
   422             iDecoder = NULL;
       
   423             }
       
   424 
       
   425         // On error cases, free the already reserved bitmaps.
       
   426         if ( iStatus != KErrNone )
       
   427             {
       
   428             if ( iBitmap )
       
   429                 {
       
   430                 delete iBitmap;
       
   431                 iBitmap = NULL;
       
   432                 }
       
   433             if ( iMask )
       
   434                 {
       
   435                 delete iMask;
       
   436                 iMask = NULL;
       
   437                 }
       
   438             }
       
   439 
       
   440         if( iSynchronous )
       
   441             {
       
   442             // Stop the scheduler. Rest is handlen in ConvertL method
       
   443             iSynchronous = EFalse;
       
   444             CActiveScheduler::Stop();
       
   445             }
       
   446         else
       
   447             {
       
   448             if ( iStatus == KErrNone )
       
   449                 {
       
   450                 if ( !iImageScalable ) // use AknIconUtils:ScaleBitmapL to scale image.
       
   451                     {
       
   452                     ScaleBitmapL( iBitmap, iMifImageSize );
       
   453                     ScaleBitmapL( iMask, iMifImageSize );
       
   454                     }
       
   455 
       
   456                 // set converted image to icon array
       
   457                 CreateAndSetIconL();
       
   458                 }
       
   459             else
       
   460                 {
       
   461                 // In case of error, we just set default icon for application
       
   462                 ReportErrorL();
       
   463                 }
       
   464             }
       
   465         }
       
   466     }
       
   467 
       
   468 // -----------------------------------------------------------------------------
       
   469 // CVcxNsImageConverter::DoCancel()
       
   470 // -----------------------------------------------------------------------------
       
   471 //
       
   472 void CVcxNsImageConverter::DoCancel()
       
   473     {
       
   474     if ( iDecoder )
       
   475         {
       
   476         iDecoder->Cancel();
       
   477         delete iDecoder;
       
   478         iDecoder = NULL;
       
   479         }
       
   480 
       
   481     delete iBitmap;
       
   482     iBitmap = NULL;
       
   483 
       
   484     delete iMask;
       
   485     iMask = NULL;
       
   486     }
       
   487 
       
   488 // -----------------------------------------------------------------------------
       
   489 // CVcxNsImageConverter::RunError()
       
   490 // -----------------------------------------------------------------------------
       
   491 //
       
   492 TInt CVcxNsImageConverter::RunError(TInt aError)
       
   493     {
       
   494     DoCancel();
       
   495 
       
   496     TRAP_IGNORE( iObserver.ImageConversionCompletedL( aError, NULL ) );
       
   497 
       
   498     return KErrNone;
       
   499     }
       
   500 
       
   501 // -----------------------------------------------------------------------------
       
   502 // CVcxNsImageConverter::CreateAndSetIconL()
       
   503 // -----------------------------------------------------------------------------
       
   504 //
       
   505 void CVcxNsImageConverter::CreateAndSetIconL()
       
   506     {
       
   507     IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::CreateAndSetIconL()");
       
   508 
       
   509     CGulIcon* icon = CGulIcon::NewL( iBitmap, iMask );
       
   510     CleanupStack::PushL( icon );
       
   511     icon->SetBitmapsOwnedExternally( EFalse );
       
   512 
       
   513     iBitmap = NULL; // Not owned by us anymore.
       
   514     iMask   = NULL;
       
   515 
       
   516     iObserver.ImageConversionCompletedL( KErrNone, icon );
       
   517 
       
   518     CleanupStack::Pop( icon );
       
   519     }
       
   520 
       
   521 // -----------------------------------------------------------------------------
       
   522 // CVcxNsImageConverter::ReportErrorL()
       
   523 // -----------------------------------------------------------------------------
       
   524 //
       
   525 void CVcxNsImageConverter::ReportErrorL()
       
   526     {
       
   527     IPTVLOGSTRING_LOW_LEVEL("CVcxNsImageConverter::ReportErrorL()");
       
   528 
       
   529     iObserver.ImageConversionCompletedL( iStatus.Int(), NULL );
       
   530     }
       
   531 
       
   532 // -----------------------------------------------------------------------------
       
   533 // CVcxNsImageConverter::GetExtension()
       
   534 // -----------------------------------------------------------------------------
       
   535 //
       
   536 TBool CVcxNsImageConverter::GetExtension(const TDesC& aPath, TDes& aExtension)
       
   537     {
       
   538     if (aPath.Length() > 0)
       
   539         {
       
   540         TInt dot = aPath.LocateReverse('.');
       
   541 
       
   542         if (dot != KErrNotFound)
       
   543             {
       
   544             TPtrC16 suffixPtr = aPath.Mid(dot);
       
   545             if ( suffixPtr.Length() >= KSuffixPtrMinLength &&
       
   546                  suffixPtr.Length() <= KSuffixPtrMaxLength)
       
   547                 {
       
   548                 aExtension.Copy(suffixPtr);
       
   549 
       
   550                 return ETrue;
       
   551                 }
       
   552             else
       
   553                 {
       
   554                 aExtension.Zero();
       
   555                 }
       
   556             }
       
   557         }
       
   558 
       
   559     return EFalse;
       
   560     }