PECengine/AttributeLibrary2/SrcWVAttributes/CPEngMyLogoConverter.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     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:  MyLogo converter.
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include "CPEngMyLogoConverter.h"
       
    20 #include "PresenceDebugPrint.h"
       
    21 
       
    22 #include <E32Std.h>
       
    23 #include <PEngWVPresenceAttributes2.h>
       
    24 #include <ImageConversion.h>
       
    25 #include <BitmapTransforms.h>
       
    26 
       
    27 
       
    28 
       
    29 //LOCAL constants
       
    30 namespace
       
    31     {
       
    32     //MyLogo image frame
       
    33     const TInt KPEngMyLogoFrame = 0;
       
    34 
       
    35     //MyLogo converter panics
       
    36     _LIT( KPEngMyLogoConverterPanic, "MyLogoConv" );
       
    37 
       
    38     //MyLogo converter panic reasons
       
    39     enum TPEngMyLogoConverterPanicReasons
       
    40         {
       
    41         EConvUnkownConvertState,
       
    42         EConvNoImageDecoder,
       
    43         EConvNoMyLogoBitmap,
       
    44         EConvMyLogoBitmapExists,
       
    45         EConvMyLogoEncoderExists,
       
    46         EConvMyLogoScalerExists,
       
    47         EConvParamsMissingNotifyNewLogo,
       
    48         EConvParamsMissingVerifyMyLogoRequirements1,
       
    49         EConvParamsMissingVerifyMyLogoRequirements2
       
    50         };
       
    51     }
       
    52 
       
    53 
       
    54 
       
    55 
       
    56 // ============================ MEMBER FUNCTIONS ===============================
       
    57 
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 // CPEngMyLogoConverter::FileNewL()
       
    61 // -----------------------------------------------------------------------------
       
    62 //
       
    63 CPEngMyLogoConverter* CPEngMyLogoConverter::FileNewL( const TDesC& aFileName,
       
    64                                                       MPEngMyLogoConversionObserver& aObserver )
       
    65     {
       
    66     CPEngMyLogoConverter* self = new ( ELeave ) CPEngMyLogoConverter( aObserver );
       
    67     CleanupStack::PushL( self );
       
    68     self->ConstructFromFileL( aFileName );
       
    69     CleanupStack::Pop( self );
       
    70     return self;
       
    71     }
       
    72 
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CPEngMyLogoConverter::DataNewL()
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CPEngMyLogoConverter* CPEngMyLogoConverter::DataNewL( const TDesC8& aImageData,
       
    79                                                       MPEngMyLogoConversionObserver& aObserver )
       
    80     {
       
    81     CPEngMyLogoConverter* self = new ( ELeave ) CPEngMyLogoConverter( aObserver );
       
    82     CleanupStack::PushL( self );
       
    83     self->ConstructFromDataL( aImageData );
       
    84     CleanupStack::Pop( self );
       
    85     return self;
       
    86     }
       
    87 
       
    88 
       
    89 
       
    90 // Destructor
       
    91 CPEngMyLogoConverter::~CPEngMyLogoConverter()
       
    92     {
       
    93     CActive::Cancel();
       
    94     iObserver.HandleConverterDestroy();
       
    95 
       
    96     delete iImageDataBuffer;
       
    97     delete iImageMimeTypeBuffer;
       
    98     delete iImageFileNameBuffer;
       
    99     delete iImageDecoder;
       
   100     delete iImageEncoder;
       
   101     delete iBitmapScaler;
       
   102     delete iMyLogoBitmap;
       
   103 
       
   104     iFs.Close();
       
   105     }
       
   106 
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CPEngMyLogoConverter::CPEngMyLogoConverter
       
   110 // C++ default constructor can NOT contain any code, that
       
   111 // might leave.
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 CPEngMyLogoConverter::CPEngMyLogoConverter( MPEngMyLogoConversionObserver& aObserver )
       
   115         : CActive( EPriorityIdle ),
       
   116         iState( EConverterIdle ),
       
   117         iObserver( aObserver )
       
   118     {
       
   119     CActiveScheduler::Add( this );
       
   120     }
       
   121 
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // CPEngMyLogoConverter::ConstructFromFileL()
       
   125 // Symbian 2nd phase constructor can leave.
       
   126 // -----------------------------------------------------------------------------
       
   127 //
       
   128 void CPEngMyLogoConverter::ConstructFromFileL( const TDesC& aImageFile )
       
   129     {
       
   130     User::LeaveIfError( iFs.Connect() );
       
   131     iImageFileNameBuffer = aImageFile.AllocL();
       
   132 
       
   133     if ( aImageFile.Length() > 0 )
       
   134         {
       
   135         RFile imageFile;
       
   136         CleanupClosePushL( imageFile );
       
   137 
       
   138 
       
   139         //Try open source file with different access modes
       
   140         TInt openErr = imageFile.Open( iFs, aImageFile, EFileShareReadersOnly );
       
   141         if ( openErr != KErrNone )
       
   142             {
       
   143             openErr = imageFile.Open( iFs, aImageFile, EFileShareAny | EFileStream );
       
   144             }
       
   145         User::LeaveIfError( openErr );
       
   146 
       
   147 
       
   148         //And read file contents to buffer
       
   149         TInt fileSize;
       
   150         User::LeaveIfError( imageFile.Size( fileSize ) );
       
   151         iImageDataBuffer = HBufC8::NewL( fileSize );
       
   152         TPtr8 imageData( iImageDataBuffer->Des() );
       
   153 
       
   154         User::LeaveIfError( imageFile.Read( imageData ) );
       
   155 
       
   156         CleanupStack::PopAndDestroy(); // imageFile
       
   157 
       
   158 
       
   159         //And open image decoder to buffer
       
   160         iImageDecoder = CImageDecoder::DataNewL( iFs,
       
   161                                                  *iImageDataBuffer,
       
   162                                                  CImageDecoder::EOptionAlwaysThread );
       
   163         }
       
   164 
       
   165     else
       
   166         {
       
   167         iImageDataBuffer = HBufC8::NewL( 0 );
       
   168         iImageMimeTypeBuffer = HBufC8::NewL( 0 );
       
   169         }
       
   170     }
       
   171 
       
   172 
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CPEngMyLogoConverter::ConstructFromDataL()
       
   176 // Symbian 2nd phase constructor can leave.
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 void CPEngMyLogoConverter::ConstructFromDataL( const TDesC8& aImageData )
       
   180     {
       
   181     iImageFileNameBuffer = HBufC::NewL( 0 );
       
   182 
       
   183     if ( aImageData.Length() > 0 )
       
   184         {
       
   185         //Make a local copy from image
       
   186         iImageDataBuffer = aImageData.AllocL();
       
   187 
       
   188         //And open image decoder to buffer
       
   189         iImageDecoder = CImageDecoder::DataNewL( iFs,
       
   190                                                  *iImageDataBuffer,
       
   191                                                  CImageDecoder::EOptionAlwaysThread );
       
   192         }
       
   193 
       
   194     else
       
   195         {
       
   196         iImageDataBuffer = HBufC8::NewL( 0 );
       
   197         iImageMimeTypeBuffer = HBufC8::NewL( 0 );
       
   198         }
       
   199     }
       
   200 
       
   201 // -----------------------------------------------------------------------------
       
   202 // CPEngMyLogoConverter::IssueConvert()
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 void CPEngMyLogoConverter::IssueConvert( TRequestStatus& aRequestStatus )
       
   206     {
       
   207     //Issue first image processing round
       
   208     iStatus = KRequestPending;
       
   209     SetStateActive( EConverterIdle );
       
   210 
       
   211     TRequestStatus *s = &iStatus;
       
   212     User::RequestComplete( s, KErrNone );
       
   213 
       
   214     //And cache client request status so it can be signalled later
       
   215     //Client request status must be also set to pending state..
       
   216     iClientRequest = &aRequestStatus;
       
   217     *iClientRequest = KRequestPending;
       
   218     }
       
   219 
       
   220 
       
   221 // -----------------------------------------------------------------------------
       
   222 // CPEngMyLogoConverter::RunL()
       
   223 // From CActive
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 void CPEngMyLogoConverter::RunL()
       
   227     {
       
   228     PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::RunL() iState[%d], iStatus[%d]" ),
       
   229              iState, iStatus.Int() );
       
   230 
       
   231     switch ( iState )
       
   232         {
       
   233         case EConverterIdle:
       
   234             {
       
   235             if ( VerifyMyLogoRequirementsL() )
       
   236                 {
       
   237                 NotifyNewLogo();
       
   238                 ConversionCompletedD( KErrNone );
       
   239                 }
       
   240 
       
   241             else
       
   242                 {
       
   243                 IssueImageOpenToBitmapL();
       
   244                 SetStateActive( EImageOpenToBitmap );
       
   245                 }
       
   246 
       
   247             break;
       
   248             }
       
   249 
       
   250         case EImageOpenToBitmap:
       
   251             {
       
   252             User::LeaveIfError( iStatus.Int() );
       
   253 
       
   254             delete iImageDecoder;
       
   255             iImageDecoder = NULL;
       
   256 
       
   257             IssueBitmapScaleDownL();
       
   258             SetStateActive( EBitmapScaleDown );
       
   259             break;
       
   260             }
       
   261 
       
   262 
       
   263         case EBitmapScaleDown:
       
   264             {
       
   265             User::LeaveIfError( iStatus.Int() );
       
   266 
       
   267             delete iBitmapScaler;
       
   268             iBitmapScaler = NULL;
       
   269 
       
   270             IssueBitmapStoreToImageL();
       
   271             SetStateActive( EBitmapStoreToImage );
       
   272             break;
       
   273             }
       
   274 
       
   275         case EBitmapStoreToImage:
       
   276             {
       
   277             User::LeaveIfError( iStatus.Int() );
       
   278             if ( iImageDataBuffer->Size() > KPEngWVMyLogoImageMaxByteSize )
       
   279                 {
       
   280                 User::Leave( KErrTooBig );
       
   281                 }
       
   282 
       
   283             NotifyNewLogo();
       
   284             ConversionCompletedD( KErrNone );
       
   285             break;
       
   286             }
       
   287 
       
   288 
       
   289         default:
       
   290             {
       
   291             PanicConverter( EConvUnkownConvertState );
       
   292             break;
       
   293             }
       
   294         }
       
   295     }
       
   296 
       
   297 
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // CPEngMyLogoConverter::RunError()
       
   301 // From CActive
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 TInt CPEngMyLogoConverter::RunError( TInt aError )
       
   305     {
       
   306     PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::RunError [%d]" ), aError );
       
   307 
       
   308     //RunL() has leaved. Stop the processing.
       
   309     ConversionCompletedD( aError );
       
   310 
       
   311     return KErrNone;
       
   312     }
       
   313 
       
   314 
       
   315 // -----------------------------------------------------------------------------
       
   316 // CPEngMyLogoConverter::DoCancel()
       
   317 // From CActive
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 void CPEngMyLogoConverter::DoCancel()
       
   321     {
       
   322     //cancel the operation step currently running...
       
   323     switch ( iState )
       
   324         {
       
   325         case EConverterIdle:
       
   326             {
       
   327             //no issued request to cancel
       
   328             break;
       
   329             }
       
   330 
       
   331         case EImageOpenToBitmap:
       
   332             {
       
   333             iImageDecoder->Cancel();
       
   334             break;
       
   335             }
       
   336 
       
   337         case EBitmapScaleDown:
       
   338             {
       
   339             iBitmapScaler->Cancel();
       
   340             break;
       
   341             }
       
   342 
       
   343         case EBitmapStoreToImage:
       
   344             {
       
   345             iImageEncoder->Cancel();
       
   346             break;
       
   347             }
       
   348 
       
   349         default:
       
   350             {
       
   351             //nothing to do
       
   352             break;
       
   353             }
       
   354         }
       
   355 
       
   356     //and complete original client request
       
   357     User::RequestComplete( iClientRequest, KErrCancel );
       
   358     }
       
   359 
       
   360 
       
   361 // -----------------------------------------------------------------------------
       
   362 // CPEngMyLogoConverter::SetStateActive()
       
   363 // -----------------------------------------------------------------------------
       
   364 //
       
   365 void CPEngMyLogoConverter::SetStateActive( TLogoConverterState aNewState )
       
   366     {
       
   367     SetActive();
       
   368     iState = aNewState;
       
   369 
       
   370     //Give other threads a chance
       
   371     User::After( 0 );       // CSI: 92 #
       
   372     }
       
   373 
       
   374 
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CPEngMyLogoConverter::VerifyMyLogoRequirements()
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 TBool CPEngMyLogoConverter::VerifyMyLogoRequirementsL()
       
   381     {
       
   382     __ASSERT_DEBUG( iImageDataBuffer,
       
   383                     PanicConverter( EConvParamsMissingVerifyMyLogoRequirements1 ) );
       
   384 
       
   385     if ( iImageDataBuffer->Length() == 0 )
       
   386         {
       
   387         //Empty logo - no processing needed
       
   388         return ETrue;
       
   389         }
       
   390 
       
   391 
       
   392     //verify image properties
       
   393     __ASSERT_DEBUG( iImageDecoder && !iImageMimeTypeBuffer,
       
   394                     PanicConverter( EConvParamsMissingVerifyMyLogoRequirements2 ) );
       
   395 
       
   396     if ( iImageDecoder->FrameCount() == 0 )
       
   397         {
       
   398         User::Leave( KErrNotSupported );  //no frames in image
       
   399         }
       
   400 
       
   401 
       
   402     TFrameInfo fi;
       
   403     fi = iImageDecoder->FrameInfo( KPEngMyLogoFrame );
       
   404 
       
   405 
       
   406     TUid imageType;
       
   407     TUid imageSubType;
       
   408     iImageDecoder->ImageType( KPEngMyLogoFrame, imageType, imageSubType );
       
   409 
       
   410 
       
   411     //Check image type
       
   412     if ( ( imageType != KImageTypeGIFUid ) && ( imageType != KImageTypeJPGUid ) )
       
   413         {
       
   414         PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::VerifyMyLogoRequirementsL() - wrong image format [%08x]" ),
       
   415                  imageType.iUid );
       
   416         return EFalse;
       
   417         }
       
   418 
       
   419     //Check image pixel size
       
   420     if ( ( fi.iOverallSizeInPixels.iHeight > KPEngWVMyLogoImageMaxHeight ) ||
       
   421          ( fi.iOverallSizeInPixels.iWidth > KPEngWVMyLogoImageMaxWidth ) )
       
   422         {
       
   423         PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::VerifyMyLogoRequirementsL() - image pixel size too big h[%d] w[%d]" ),
       
   424                  fi.iOverallSizeInPixels.iHeight, fi.iOverallSizeInPixels.iWidth );
       
   425         return EFalse;
       
   426         }
       
   427 
       
   428     //Check image byte size
       
   429     if ( iImageDataBuffer->Size() > KPEngWVMyLogoImageMaxByteSize )
       
   430         {
       
   431         PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::VerifyMyLogoRequirementsL() - image byte size too big [%d]" ),
       
   432                  iImageDataBuffer->Size() );
       
   433         return EFalse;
       
   434         }
       
   435 
       
   436 
       
   437     //Perfectly OK logo image.
       
   438     if ( imageType == KImageTypeGIFUid )
       
   439         {
       
   440         iImageMimeTypeBuffer = KPEngWVMyLogoMimeImageGif().AllocL();
       
   441         }
       
   442     else
       
   443         {
       
   444         iImageMimeTypeBuffer = KPEngWVMyLogoMimeJpeg().AllocL();
       
   445         }
       
   446 
       
   447     return ETrue;
       
   448     }
       
   449 
       
   450 
       
   451 
       
   452 // -----------------------------------------------------------------------------
       
   453 // CPEngMyLogoConverter::IssueImageOpenToBitmapL()
       
   454 // -----------------------------------------------------------------------------
       
   455 //
       
   456 void CPEngMyLogoConverter::IssueImageOpenToBitmapL()
       
   457     {
       
   458     __ASSERT_DEBUG( !iMyLogoBitmap,
       
   459                     PanicConverter( EConvMyLogoBitmapExists ) );
       
   460 
       
   461     __ASSERT_DEBUG( iImageDecoder,
       
   462                     PanicConverter( EConvNoImageDecoder ) );
       
   463 
       
   464 
       
   465     //For future: This could be optimized to take just 1/8 sized image...
       
   466     TFrameInfo fi;
       
   467     fi = iImageDecoder->FrameInfo( KPEngMyLogoFrame );
       
   468 
       
   469     iMyLogoBitmap = new( ELeave ) CFbsBitmap;
       
   470     User::LeaveIfError( iMyLogoBitmap->Create( fi.iOverallSizeInPixels,
       
   471                                                fi.iFrameDisplayMode ) );
       
   472 
       
   473     iImageDecoder->Convert( &iStatus, *iMyLogoBitmap, KPEngMyLogoFrame );
       
   474     }
       
   475 
       
   476 
       
   477 
       
   478 // -----------------------------------------------------------------------------
       
   479 // CPEngMyLogoConverter::IssueBitmapScaleDownL()
       
   480 // -----------------------------------------------------------------------------
       
   481 //
       
   482 void CPEngMyLogoConverter::IssueBitmapScaleDownL()
       
   483     {
       
   484     __ASSERT_DEBUG( !iBitmapScaler,
       
   485                     PanicConverter( EConvMyLogoScalerExists ) );
       
   486 
       
   487     __ASSERT_DEBUG( iMyLogoBitmap,
       
   488                     PanicConverter( EConvNoMyLogoBitmap ) );
       
   489 
       
   490 
       
   491     iBitmapScaler = CBitmapScaler::NewL();
       
   492     iBitmapScaler->Scale( &iStatus,
       
   493                           *iMyLogoBitmap,
       
   494                           TSize( KPEngWVMyLogoImageMaxWidth, KPEngWVMyLogoImageMaxHeight ),
       
   495                           ETrue );
       
   496     }
       
   497 
       
   498 
       
   499 // -----------------------------------------------------------------------------
       
   500 // CPEngMyLogoConverter::IssueBitmapStoreToImageL()
       
   501 // -----------------------------------------------------------------------------
       
   502 //
       
   503 void CPEngMyLogoConverter::IssueBitmapStoreToImageL()
       
   504     {
       
   505     __ASSERT_DEBUG( !iImageEncoder && !iImageMimeTypeBuffer,
       
   506                     PanicConverter( EConvMyLogoEncoderExists ) );
       
   507 
       
   508     __ASSERT_DEBUG( iMyLogoBitmap,
       
   509                     PanicConverter( EConvNoMyLogoBitmap ) );
       
   510 
       
   511 
       
   512     iImageMimeTypeBuffer = KPEngWVMyLogoMimeJpeg().AllocL();
       
   513 
       
   514     delete iImageDataBuffer;
       
   515     iImageDataBuffer = NULL;
       
   516 
       
   517     iImageEncoder = CImageEncoder::DataNewL( iImageDataBuffer,
       
   518                                              KPEngWVMyLogoMimeJpeg,
       
   519                                              CImageEncoder::EOptionAlwaysThread );
       
   520     iImageEncoder->SetThumbnail( EFalse );
       
   521     iImageEncoder->Convert( &iStatus, *iMyLogoBitmap );
       
   522     }
       
   523 
       
   524 
       
   525 
       
   526 // -----------------------------------------------------------------------------
       
   527 // CPEngMyLogoConverter::NotifyNewLogo()
       
   528 // -----------------------------------------------------------------------------
       
   529 //
       
   530 void CPEngMyLogoConverter::NotifyNewLogo()
       
   531     {
       
   532     __ASSERT_DEBUG( iImageDataBuffer && iImageMimeTypeBuffer && iImageFileNameBuffer,
       
   533                     PanicConverter( EConvParamsMissingNotifyNewLogo )  );
       
   534 
       
   535 
       
   536 
       
   537     iObserver.HandleNewMyLogo( iImageDataBuffer, iImageMimeTypeBuffer, iImageFileNameBuffer );
       
   538 
       
   539     //HandleNewMyLogo took the ownership of passed
       
   540     //iImageDataBuffer and iImageMimeTypeBuffer and iImageFileNameBuffer
       
   541     //==> NULL own member pointers
       
   542     iImageDataBuffer = NULL;
       
   543     iImageMimeTypeBuffer = NULL;
       
   544     iImageFileNameBuffer = NULL;
       
   545     }
       
   546 
       
   547 
       
   548 
       
   549 // -----------------------------------------------------------------------------
       
   550 // CPEngMyLogoConverter::ConversionCompletedD()
       
   551 // -----------------------------------------------------------------------------
       
   552 //
       
   553 void CPEngMyLogoConverter::ConversionCompletedD( TInt aStatus )
       
   554     {
       
   555     User::RequestComplete( iClientRequest, aStatus );
       
   556     delete this;
       
   557     }
       
   558 
       
   559 
       
   560 // -----------------------------------------------------------------------------
       
   561 // CPEngMyLogoConverter::PanicConverter()
       
   562 // -----------------------------------------------------------------------------
       
   563 //
       
   564 void CPEngMyLogoConverter::PanicConverter( TInt aPanicReason ) const
       
   565     {
       
   566     User::Panic( KPEngMyLogoConverterPanic, aPanicReason );
       
   567     }
       
   568 
       
   569 
       
   570 
       
   571 //  End of File
       
   572 
       
   573