wvuing/wvuieng/EngSrc/CCAImageLoader.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:  Image loader and scaler
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CCAImageLoader.h"
       
    20 #include "MCAChatInterface.h"
       
    21 #include "CCAContentMessage.h"
       
    22 
       
    23 #include "ChatDebugPrint.h"
       
    24 #include "chatdebugassert.h"
       
    25 #include "impsbuilddefinitions.h"
       
    26 
       
    27 #include "mcaimpsfactory.h"
       
    28 #include "mcaimpsimclient.h"
       
    29 #include "wvengutils.h"
       
    30 #include "imnginternalcrkeys.h"
       
    31 #include "imprivatecrkeys.h"
       
    32 #include "imvariant.hrh"
       
    33 
       
    34 #include <ImageConversion.h>
       
    35 #include <BitmapTransforms.h>
       
    36 #include <s32file.h>
       
    37 
       
    38 // CONSTANTS
       
    39 const TInt KChatCustomBitmapWidth = 320;
       
    40 const TInt KChatCustomBitmapHeight = 240;
       
    41 
       
    42 // From ICL documentation:
       
    43 // "all decoder plugins also support thumbnail decodes with ratios of 1:2, 1:4 and 1:8."
       
    44 const TInt KDecodeScaleRatioMin = 2;
       
    45 const TInt KDecodeScaleRatioMax = 8;
       
    46 
       
    47 
       
    48 //-----------------------------------------------------------------------------
       
    49 // CCAImageLoader::CCAImageLoader
       
    50 // ( Other items commented in header )
       
    51 //-----------------------------------------------------------------------------
       
    52 CCAImageLoader::CCAImageLoader(
       
    53     MCAChatInterface& aChatInterface, MCAImpsFactory& aImpsFactory )
       
    54         : CActive( CActive::EPriorityLow ),
       
    55         iChatInterface( aChatInterface ),
       
    56         iImpsFactory( aImpsFactory )
       
    57     {
       
    58     CHAT_DP_FUNC_ENTER( "CCAImageLoader::CCAImageLoader" );
       
    59     CActiveScheduler::Add( this );
       
    60     CHAT_DP_FUNC_DONE( "CCAImageLoader::CCAImageLoader" );
       
    61     }
       
    62 
       
    63 //-----------------------------------------------------------------------------
       
    64 // CCAImageLoader::CCAImageLoader
       
    65 // ( Other items commented in header )
       
    66 //-----------------------------------------------------------------------------
       
    67 CCAImageLoader::~CCAImageLoader()
       
    68     {
       
    69     CHAT_DP_FUNC_ENTER( "CCAImageLoader::~CCAImageLoader" );
       
    70     iFs.Close();
       
    71 
       
    72     delete iDecoder;
       
    73     delete iScaler;
       
    74     delete iEncoder;
       
    75     delete iBitmap;
       
    76     delete iContent;
       
    77 
       
    78     iMessages.Close();
       
    79 
       
    80     CHAT_DP_FUNC_DONE( "CCAImageLoader::~CCAImageLoader" );
       
    81     }
       
    82 
       
    83 //-----------------------------------------------------------------------------
       
    84 // CCAImageLoader::NewL
       
    85 // ( Other items commented in header )
       
    86 //-----------------------------------------------------------------------------
       
    87 CCAImageLoader* CCAImageLoader::NewL( MCAChatInterface& aChatInterface,
       
    88                                       MCAImpsFactory& aImpsFactory )
       
    89     {
       
    90     CHAT_DP_FUNC_ENTER( "CCAImageLoader::NewL" );
       
    91     CCAImageLoader* self =
       
    92         new ( ELeave ) CCAImageLoader( aChatInterface, aImpsFactory );
       
    93     CleanupStack::PushL( self );
       
    94     self->ConstructL();
       
    95     CleanupStack::Pop( self );
       
    96     CHAT_DP_FUNC_DONE( "CCAImageLoader::NewL" );
       
    97     return self;
       
    98     }
       
    99 
       
   100 //-----------------------------------------------------------------------------
       
   101 // CCAImageLoader::ConstructL
       
   102 // ( Other items commented in header )
       
   103 //-----------------------------------------------------------------------------
       
   104 void CCAImageLoader::ConstructL()
       
   105     {
       
   106     CHAT_DP_FUNC_ENTER( "CCAImageLoader::ConstructL" );
       
   107     User::LeaveIfError( iFs.Connect() );
       
   108 
       
   109     iSendNotScalable = WVEngUtils::CRKeyL( KCRUidIMVariation, KIMVariationKey )
       
   110                        & EIMFeatSendNotScalable;
       
   111     CHAT_DP_FUNC_DONE( "CCAImageLoader::ConstructL" );
       
   112     }
       
   113 
       
   114 
       
   115 //-----------------------------------------------------------------------------
       
   116 // CCAImageLoader::RunL
       
   117 // ( Other items commented in header )
       
   118 //-----------------------------------------------------------------------------
       
   119 void CCAImageLoader::RunL()
       
   120     {
       
   121     CHAT_DP_FUNC_ENTER( "CCAImageLoader::RunL" );
       
   122     TInt status = iStatus.Int();
       
   123     CHAT_DP( D_CHAT_LIT( "Status %d" ), status );
       
   124     switch ( status )
       
   125         {
       
   126         case KErrUnderflow:
       
   127             {
       
   128             if ( iDecoder )
       
   129                 {
       
   130                 CHAT_DP( D_CHAT_LIT( "Continue converting." ) );
       
   131                 iStatus = KRequestPending;
       
   132                 iDecoder->ContinueConvert( &iStatus );
       
   133                 }
       
   134             else
       
   135                 {
       
   136                 CompleteRequestL();
       
   137                 }
       
   138             break;
       
   139             }
       
   140         case KErrNone:
       
   141             {
       
   142             if ( iDecoder )
       
   143                 {
       
   144                 delete iDecoder;
       
   145                 iDecoder = NULL;
       
   146                 switch ( iCurrentMessage->ContentProcessState() )
       
   147                     {
       
   148                     case MCAMessage::EContentNotProcessed:
       
   149                         {
       
   150                         CHAT_DP( D_CHAT_LIT( "-> Start scaling." ) );
       
   151                         // Decode ready -> Start scaling.
       
   152                         iCurrentMessage->SetProcessState(
       
   153                             MCAMessage::EBitmapDecoded );
       
   154                         StartProcessingL( *iCurrentMessage );
       
   155                         break;
       
   156                         }
       
   157                     case MCAMessage::EContentReady:
       
   158                         {
       
   159                         CHAT_DP(
       
   160                             D_CHAT_LIT( "-> Start scaling to thumbnail." ) );
       
   161                         // Decode ready -> Start making thumbnail.
       
   162                         iCurrentMessage->SetProcessState(
       
   163                             MCAMessage::EContentDecoded );
       
   164                         StartProcessingL( *iCurrentMessage );
       
   165                         break;
       
   166                         }
       
   167                     default:
       
   168                         {
       
   169                         iStatus = KErrNotSupported;
       
   170                         CompleteRequestL();
       
   171                         break;
       
   172                         }
       
   173                     }
       
   174 
       
   175                 }
       
   176             else if ( iScaler )
       
   177                 {
       
   178                 // scaling ready -> start encoding
       
   179                 delete iScaler;
       
   180                 iScaler = NULL;
       
   181                 switch ( iCurrentMessage->ContentProcessState() )
       
   182                     {
       
   183                     case MCAMessage::EBitmapDecoded:
       
   184                         {
       
   185                         CHAT_DP( D_CHAT_LIT( "-> Start encoding." ) );
       
   186                         iCurrentMessage->SetProcessState(
       
   187                             MCAMessage::EBitmapScaled );
       
   188                         StartProcessingL( *iCurrentMessage );
       
   189                         break;
       
   190                         }
       
   191                     case MCAMessage::EContentDecoded:
       
   192                         {
       
   193                         CHAT_DP( D_CHAT_LIT( "Thumbnail ready." ) );
       
   194                         CCAContentMessage* message =
       
   195                             static_cast< CCAContentMessage* >( iCurrentMessage );
       
   196                         message->SetThumbnail( iBitmap );
       
   197                         iBitmap = NULL;
       
   198                         iCurrentMessage->SetProcessState(
       
   199                             MCAMessage::EThumbnailReady );
       
   200                         CompleteRequestL();
       
   201                         break;
       
   202                         }
       
   203                     default:
       
   204                         {
       
   205                         iStatus = KErrNotSupported;
       
   206                         CompleteRequestL();
       
   207                         break;
       
   208                         }
       
   209                     }
       
   210                 }
       
   211             else if ( iEncoder )
       
   212                 {
       
   213                 CHAT_DP( D_CHAT_LIT( "Content ready. -> Stop processing." ) );
       
   214                 delete iEncoder;
       
   215                 iEncoder = NULL;
       
   216                 iCurrentMessage->SetProcessState( MCAMessage::EContentReady );
       
   217                 iCurrentMessage->SetContentData( iContent );
       
   218                 iContent = NULL;
       
   219                 delete iBitmap;
       
   220                 iBitmap = NULL;
       
   221                 CompleteRequestL();
       
   222                 }
       
   223             else
       
   224                 {
       
   225                 iStatus = KErrNotSupported;
       
   226                 CompleteRequestL();
       
   227                 }
       
   228             break;
       
   229             }
       
   230         case KErrNoMemory:
       
   231             {
       
   232             // RunError will handle this case
       
   233             User::Leave( KErrNoMemory );
       
   234             }
       
   235         default:
       
   236             {
       
   237             CompleteRequestL();
       
   238             break;
       
   239             }
       
   240         }
       
   241     CHAT_DP_FUNC_DONE( "CCAImageLoader::RunL" );
       
   242     }
       
   243 
       
   244 //-----------------------------------------------------------------------------
       
   245 // CCAImageLoader::DoCancel
       
   246 // ( Other items commented in header )
       
   247 //-----------------------------------------------------------------------------
       
   248 void CCAImageLoader::DoCancel()
       
   249     {
       
   250     CHAT_DP_FUNC_ENTER( "CCAImageLoader::DoCancel" );
       
   251 
       
   252     ClearState();
       
   253     iCurrentMessage->HandleProcessingComplete( *this, iStatus.Int() );
       
   254     CHAT_DP_FUNC_DONE( "CCAImageLoader::DoCancel" );
       
   255     }
       
   256 
       
   257 //-----------------------------------------------------------------------------
       
   258 // CCAImageLoader::RunError
       
   259 // ( Other items commented in header )
       
   260 //-----------------------------------------------------------------------------
       
   261 TInt CCAImageLoader::RunError( TInt aError )
       
   262     {
       
   263     CHAT_DP_FUNC_ENTER( "CCAImageLoader::RunError" );
       
   264     if ( IsActive() )
       
   265         {
       
   266         iStatus = aError;
       
   267         Cancel();
       
   268         }
       
   269 
       
   270     if ( aError == KErrNoMemory )
       
   271         {
       
   272         CActiveScheduler::Current()->Error( KErrNoMemory );
       
   273         }
       
   274 
       
   275     // Clean up and reset all pending messages
       
   276     ClearState();
       
   277     TRAP_IGNORE( ResetProcessingL( aError ) );
       
   278 
       
   279     CHAT_DP_FUNC_DONE( "CCAImageLoader::RunError" );
       
   280     return KErrNone;
       
   281     }
       
   282 
       
   283 //-----------------------------------------------------------------------------
       
   284 // CCAImageLoader::RequestProcessing
       
   285 // ( Other items commented in header )
       
   286 //-----------------------------------------------------------------------------
       
   287 void CCAImageLoader::RequestProcessingL( MCAMessage& aMessage )
       
   288     {
       
   289     CHAT_DP_FUNC_ENTER( "CCAImageLoader::RequestProcessingL" );
       
   290     // Append to scheduler
       
   291     iMessages.AppendL( &aMessage );
       
   292     LaunchProcessingL();
       
   293     CHAT_DP_FUNC_DONE( "CCAImageLoader::RequestProcessingL" );
       
   294     }
       
   295 
       
   296 //-----------------------------------------------------------------------------
       
   297 // CCAImageLoader::StartProcessing
       
   298 // ( Other items commented in header )
       
   299 //-----------------------------------------------------------------------------
       
   300 void CCAImageLoader::StartProcessingL( MCAMessage& aMessage )
       
   301     {
       
   302     CHAT_DP_FUNC_ENTER( "CCAImageLoader::StartProcessingL" );
       
   303     // File -> bitmap
       
   304     // bitmap -> scaled bitmap
       
   305     // scaled bitmap -> encoded content
       
   306 
       
   307     iCurrentMessage = &aMessage;
       
   308     switch ( aMessage.ContentProcessState() )
       
   309         {
       
   310         case MCAMessage::EContentNotProcessed:  // File -> bitmap
       
   311             {
       
   312             __CHAT_ASSERT_DEBUG( !iDecoder );
       
   313             iDecoder = CImageDecoder::FileNewL( iFs, aMessage.Text() );
       
   314 
       
   315             TSize origSize( iDecoder->FrameInfo().iOverallSizeInPixels );
       
   316             ScaleSize( origSize, iTargetSize );
       
   317             TBool fullyScaleable( iDecoder->FrameInfo().iFlags & TFrameInfo::EFullyScaleable );
       
   318 
       
   319             TInt frameCount = iDecoder->FrameCount();
       
   320             if ( frameCount > 1 && iSendNotScalable )
       
   321                 {
       
   322                 // Animated gif, try to send file as it is
       
   323                 // Animation would be lost in decoding/scaling process
       
   324 
       
   325                 delete iDecoder;    // Delete -> unlocks image file
       
   326                 iDecoder = NULL;
       
   327 
       
   328                 // Open file
       
   329                 RFile file;
       
   330                 User::LeaveIfError( file.Open( iFs, aMessage.Text(), EFileRead ) );
       
   331                 CleanupClosePushL( file );
       
   332 
       
   333                 // Get file size
       
   334                 TInt fileSize = 0;
       
   335                 User::LeaveIfError( file.Size( fileSize ) );
       
   336 
       
   337                 // Check file size, if bigger than max transaction content -> leave
       
   338                 if ( fileSize >
       
   339                      iImpsFactory.CreateImClientL()->MaxTransactionContentLengthL() )
       
   340                     {
       
   341                     User::Leave( KErrOverflow );
       
   342                     }
       
   343 
       
   344                 // Get file content
       
   345                 HBufC8* content = HBufC8::NewLC( fileSize );
       
   346                 TPtr8 ptr( content->Des() );
       
   347                 User::LeaveIfError( file.Read( ptr, fileSize ) );
       
   348 
       
   349                 // Set content to message, ownership is transferred
       
   350                 CleanupStack::Pop( content );
       
   351                 CleanupStack::PopAndDestroy();  // file.Close()
       
   352                 iCurrentMessage->SetProcessState( MCAMessage::EContentReady );
       
   353                 iCurrentMessage->SetContentData( content );
       
   354 
       
   355                 // Complete
       
   356                 CompleteRequestL();
       
   357                 break;
       
   358                 }
       
   359 
       
   360             TSize decodeSize( DecodeSize( origSize, iTargetSize, fullyScaleable ) );
       
   361 
       
   362             __CHAT_ASSERT_DEBUG( !iBitmap );
       
   363             iBitmap = new ( ELeave ) CFbsBitmap();
       
   364             User::LeaveIfError( iBitmap->Create( decodeSize,
       
   365                                                  iDecoder->FrameInfo().iFrameDisplayMode ) );
       
   366             iDecoder->Convert( &iStatus, *iBitmap );
       
   367             if ( !IsActive() )
       
   368                 {
       
   369                 SetActive();
       
   370                 }
       
   371             break;
       
   372             }
       
   373         case MCAMessage::EBitmapDecoded:        // scale bitmap to size 320x240
       
   374             {
       
   375             TSize currentSize( iBitmap ? iBitmap->SizeInPixels() : iTargetSize );
       
   376 
       
   377             if ( currentSize != iTargetSize )
       
   378                 {
       
   379                 // bitmap exists and the size is wrong,
       
   380                 // we have to scale the bitmap
       
   381                 __CHAT_ASSERT_DEBUG( !iScaler );
       
   382                 iScaler = CBitmapScaler::NewL();
       
   383                 iScaler->Scale( &iStatus, *iBitmap, iTargetSize );
       
   384                 if ( !IsActive() )
       
   385                     {
       
   386                     SetActive();
       
   387                     }
       
   388                 }
       
   389             else
       
   390                 {
       
   391                 // the size is already correct => skip this step
       
   392                 aMessage.SetProcessState( MCAMessage::EBitmapScaled );
       
   393                 StartProcessingL( aMessage );
       
   394                 }
       
   395             break;
       
   396             }
       
   397         case MCAMessage::EBitmapScaled:         // encode bitmap for sending
       
   398             {
       
   399             __CHAT_ASSERT_DEBUG( !iEncoder );
       
   400             iEncoder = CImageEncoder::DataNewL( iContent, aMessage.MimeType() );
       
   401             iEncoder->Convert( &iStatus, *iBitmap );
       
   402             if ( !IsActive() )
       
   403                 {
       
   404                 SetActive();
       
   405                 }
       
   406             break;
       
   407             }
       
   408         case MCAMessage::EContentReady:         // decode bitmap for creating thumbnail
       
   409             {
       
   410             __CHAT_ASSERT_DEBUG( !iDecoder );
       
   411             iDecoder = CImageDecoder::DataNewL( iFs, aMessage.ContentData() );
       
   412 
       
   413             CCAContentMessage* message =
       
   414                 static_cast< CCAContentMessage* >( iCurrentMessage );
       
   415             iThumbSize = message->ThumbnailSize();
       
   416 
       
   417             TSize origSize( iDecoder->FrameInfo().iOverallSizeInPixels );
       
   418             TBool fullyScaleable( iDecoder->FrameInfo().iFlags & TFrameInfo::EFullyScaleable );
       
   419 
       
   420             TSize decodeSize( DecodeSize( origSize, iThumbSize, fullyScaleable ) );
       
   421 
       
   422             __CHAT_ASSERT_DEBUG( !iBitmap );
       
   423             iBitmap = new ( ELeave ) CFbsBitmap();
       
   424             User::LeaveIfError( iBitmap->Create( decodeSize,
       
   425                                                  iDecoder->FrameInfo().iFrameDisplayMode ) );
       
   426             iDecoder->Convert( &iStatus, *iBitmap );
       
   427             if ( !IsActive() )
       
   428                 {
       
   429                 SetActive();
       
   430                 }
       
   431             break;
       
   432             }
       
   433         case MCAMessage::EContentDecoded:       // scale bitmap to thumbnail size.
       
   434             {
       
   435             TSize currentSize( iBitmap ? iBitmap->SizeInPixels() : iThumbSize );
       
   436 
       
   437             if ( currentSize != iThumbSize )
       
   438                 {
       
   439                 // bitmap exists and the size is wrong,
       
   440                 // we have to scale the bitmap
       
   441                 __CHAT_ASSERT_DEBUG( !iScaler );
       
   442                 iScaler = CBitmapScaler::NewL();
       
   443                 iScaler->Scale( &iStatus, *iBitmap, iThumbSize );
       
   444                 if ( !IsActive() )
       
   445                     {
       
   446                     SetActive();
       
   447                     }
       
   448                 }
       
   449             else
       
   450                 {
       
   451                 // bitmap size is already correct,
       
   452                 // set the thumbnail and complete request
       
   453                 CCAContentMessage* message =
       
   454                     static_cast< CCAContentMessage* >( iCurrentMessage );
       
   455                 message->SetThumbnail( iBitmap );
       
   456                 iBitmap = NULL;
       
   457                 aMessage.SetProcessState( MCAMessage::EThumbnailReady );
       
   458                 CompleteRequestL();
       
   459                 }
       
   460             break;
       
   461             }
       
   462 #ifdef RD_SEND_NOT_SUPPORTED_CONTENT
       
   463         case MCAMessage::EContentNotSupported:
       
   464         case MCAMessage::EContentNotSupportedDrm:
       
   465         case MCAMessage::EContentCorrupted:
       
   466             {
       
   467             RFileReadStream fileStream;
       
   468             User::LeaveIfError( fileStream.Open(	iFs,
       
   469                                                  aMessage.Text(),
       
   470                                                  EFileRead ) );
       
   471             CleanupClosePushL( fileStream );
       
   472             TInt length = fileStream.Source()->SizeL();
       
   473             HBufC8* temp = HBufC8::NewLC( length );
       
   474             TPtr8 ptr( temp->Des() );
       
   475             fileStream.ReadL( ptr, length );
       
   476             CleanupStack::Pop( temp );
       
   477             iCurrentMessage->SetContentData( temp );
       
   478             CleanupStack::PopAndDestroy();  // fileStream
       
   479             CompleteRequestL();
       
   480             break;
       
   481             }
       
   482 #endif //RD_SEND_NOT_SUPPORTED_CONTENT
       
   483         default:
       
   484             {
       
   485             // State is not known for processing. Complete it.
       
   486             CompleteRequestL();
       
   487             break;
       
   488             }
       
   489         }
       
   490     CHAT_DP_FUNC_DONE( "CCAImageLoader::StartProcessingL" );
       
   491     }
       
   492 
       
   493 //-----------------------------------------------------------------------------
       
   494 // CCAImageLoader::CancelProcessing
       
   495 // ( Other items commented in header )
       
   496 //-----------------------------------------------------------------------------
       
   497 void CCAImageLoader::CancelProcessing( MCAMessage& aMessage )
       
   498     {
       
   499     CHAT_DP_FUNC_ENTER( "CCAImageLoader::CancelProcessing" );
       
   500     if ( iCurrentMessage == &aMessage )
       
   501         {
       
   502         if ( IsActive() )
       
   503             {
       
   504             Cancel();
       
   505             }
       
   506         iCurrentMessage = NULL;
       
   507         }
       
   508     CHAT_DP_FUNC_DONE( "CCAImageLoader::CancelProcessing" );
       
   509     }
       
   510 
       
   511 //-----------------------------------------------------------------------------
       
   512 // CCAImageLoader::CancelProcessing
       
   513 // ( Other items commented in header )
       
   514 //-----------------------------------------------------------------------------
       
   515 void CCAImageLoader::RemoveProcessingL( MCAMessage& aMessage )
       
   516     {
       
   517     CHAT_DP_FUNC_ENTER( "CCAImageLoader::RemoveProcessingL" );
       
   518     // Cancel if message is processed at the moment.
       
   519     CancelProcessing( aMessage );
       
   520     // Remove message from scheduler
       
   521     TInt messageIndex( iMessages.Find( &aMessage ) );
       
   522     if ( messageIndex >= 0 )
       
   523         {
       
   524         iMessages.Remove( messageIndex );
       
   525         LaunchProcessingL();
       
   526         }
       
   527     CHAT_DP_FUNC_DONE( "CCAImageLoader::RemoveProcessingL" );
       
   528     }
       
   529 
       
   530 //-----------------------------------------------------------------------------
       
   531 // CCAImageLoader::LaunchProcessing
       
   532 // ( Other items commented in header )
       
   533 //-----------------------------------------------------------------------------
       
   534 void CCAImageLoader::LaunchProcessingL()
       
   535     {
       
   536     CHAT_DP_FUNC_ENTER( "CCAImageLoader::LaunchProcessingL" );
       
   537     TInt count( iMessages.Count() );
       
   538     if ( count > 0 && !IsActive() )
       
   539         {
       
   540         TRAPD( error, StartProcessingL( *iMessages[ 0 ] ) );
       
   541         if ( error == KErrNoMemory )
       
   542             {
       
   543             // if no memory: stop the whole process
       
   544             TRAP_IGNORE( ResetProcessingL( error ) );
       
   545             }
       
   546         else if ( error < 0 )
       
   547             {
       
   548             iMessages[ 0 ]->SetProcessState( MCAMessage::EContentCorrupted );
       
   549             TInt ignore;
       
   550             TRAP( ignore, CompleteRequestL() );
       
   551             User::Leave( error );
       
   552             }
       
   553         }
       
   554     CHAT_DP_FUNC_DONE( "CCAImageLoader::LaunchProcessingL" );
       
   555     }
       
   556 
       
   557 //-----------------------------------------------------------------------------
       
   558 // CCAImageLoader::DecodeSize
       
   559 // Scale to nearest (larger or equal) size with ratio 1:1, 1:2, 1:4 or 1:8
       
   560 //-----------------------------------------------------------------------------
       
   561 TSize CCAImageLoader::DecodeSize( const TSize& aSize, const TSize& aTargetSize,
       
   562                                   TBool aAnyRatio )
       
   563     {
       
   564     if ( aAnyRatio || aSize == aTargetSize )
       
   565         {
       
   566         // decoder can scale to any ratio or the size is already correct
       
   567         return aTargetSize;
       
   568         }
       
   569 
       
   570     // 1:1 is always valid ratio for decode scaling
       
   571     TInt lastValidRatio( 1 );
       
   572     for ( TInt ratio( KDecodeScaleRatioMin ); ratio <= KDecodeScaleRatioMax; ratio <<= 1 )
       
   573         {
       
   574         if ( aSize.iWidth % ratio + aSize.iHeight % ratio == 0 )
       
   575             {
       
   576             // this ratio is valid
       
   577             if ( aSize.iWidth / ratio < aTargetSize.iWidth ||
       
   578                  aSize.iHeight / ratio < aTargetSize.iHeight )
       
   579                 {
       
   580                 // the decoded size was smaller in some dimension,
       
   581                 // the last valid ratio should be used
       
   582                 break;
       
   583                 }
       
   584 
       
   585             // this scale ratio results to greater or equal size
       
   586             lastValidRatio = ratio;
       
   587             }
       
   588         }
       
   589 
       
   590     // return the size scaled with correct ratio
       
   591     return TSize( aSize.iWidth / lastValidRatio,
       
   592                   aSize.iHeight / lastValidRatio );
       
   593     }
       
   594 
       
   595 //-----------------------------------------------------------------------------
       
   596 // CCAImageLoader::ScaleSize
       
   597 // ( Other items commented in header )
       
   598 //-----------------------------------------------------------------------------
       
   599 TBool CCAImageLoader::ScaleSize( const TSize& aSize, TSize& aNewSize )
       
   600     {
       
   601     CHAT_DP_FUNC_ENTER( "CCAImageLoader::ScaleSize" );
       
   602     if ( Max( aSize.iHeight, aSize.iWidth ) > KChatCustomBitmapWidth )
       
   603         {
       
   604         // scaling needed
       
   605         if ( aSize.iHeight > aSize.iWidth )
       
   606             {
       
   607             aNewSize.SetSize( KChatCustomBitmapHeight, KChatCustomBitmapWidth );
       
   608             }
       
   609         else
       
   610             {
       
   611             aNewSize.SetSize( KChatCustomBitmapWidth, KChatCustomBitmapHeight );
       
   612             }
       
   613         return ETrue;
       
   614         }
       
   615 
       
   616     // old size is correct
       
   617     aNewSize = aSize;
       
   618     CHAT_DP_FUNC_DONE( "CCAImageLoader::ScaleSize" );
       
   619     return EFalse;
       
   620     }
       
   621 
       
   622 //-----------------------------------------------------------------------------
       
   623 // CCAImageLoader::CompleteRequestL
       
   624 // ( Other items commented in header )
       
   625 //-----------------------------------------------------------------------------
       
   626 void CCAImageLoader::CompleteRequestL()
       
   627     {
       
   628     CHAT_DP_FUNC_ENTER( "CCAImageLoader::CompleteRequestL" );
       
   629     iCurrentMessage->HandleProcessingComplete( *this, iStatus.Int() );
       
   630     TInt index = iMessages.Find( iCurrentMessage );
       
   631     if ( index >= 0 )
       
   632         {
       
   633         iMessages.Remove( index );
       
   634         }
       
   635     iCurrentMessage = NULL;
       
   636     LaunchProcessingL();
       
   637     CHAT_DP_FUNC_DONE( "CCAImageLoader::CompleteRequestL" );
       
   638     }
       
   639 
       
   640 //-----------------------------------------------------------------------------
       
   641 // CCAImageLoader::ResetProcessingL
       
   642 // ( Other items commented in header )
       
   643 //-----------------------------------------------------------------------------
       
   644 void CCAImageLoader::ResetProcessingL( TInt aReason )
       
   645     {
       
   646     CHAT_DP_FUNC_ENTER( "CCAImageLoader::ResetProcessingL" );
       
   647     // cancel operation
       
   648     if ( IsActive() )
       
   649         {
       
   650         iStatus = aReason;
       
   651         Cancel();
       
   652         }
       
   653 
       
   654     // show note
       
   655     if ( aReason == KErrNoMemory )
       
   656         {
       
   657         CActiveScheduler::Current()->Error( KErrNoMemory );
       
   658         }
       
   659 
       
   660     // reset all pending messages
       
   661     TInt count = iMessages.Count();
       
   662     for ( TInt i = count - 1; i >= 0; --i )
       
   663         {
       
   664         iMessages[ i ]->SetProcessState( MCAMessage::EContentCorrupted );
       
   665         iMessages[ i ]->HandleProcessingComplete( *this, aReason );
       
   666         iMessages.Remove( i );
       
   667         }
       
   668     CHAT_DP_FUNC_DONE( "CCAImageLoader::ResetProcessingL" );
       
   669     }
       
   670 
       
   671 //-----------------------------------------------------------------------------
       
   672 // CCAImageLoader::ClearState
       
   673 // ( Other items commented in header )
       
   674 //-----------------------------------------------------------------------------
       
   675 void CCAImageLoader::ClearState()
       
   676     {
       
   677     CHAT_DP_FUNC_ENTER( "CCAImageLoader::ClearState" );
       
   678     if ( iScaler )
       
   679         {
       
   680         CHAT_DP_TXT( "CCAImageLoader::ClearState - Cancel scaler" );
       
   681         iScaler->Cancel();
       
   682         delete iScaler;
       
   683         iScaler = NULL;
       
   684         }
       
   685     if ( iDecoder )
       
   686         {
       
   687         CHAT_DP_TXT( "CCAImageLoader::ClearState - Cancel decoder" );
       
   688         iDecoder->Cancel();
       
   689         delete iDecoder;
       
   690         iDecoder = NULL;
       
   691         }
       
   692     if ( iEncoder )
       
   693         {
       
   694         CHAT_DP_TXT( "CCAImageLoader::ClearState - Cancel encoder" );
       
   695         iEncoder->Cancel();
       
   696         delete iEncoder;
       
   697         iEncoder = NULL;
       
   698         }
       
   699     if ( iBitmap )
       
   700         {
       
   701         delete iBitmap;
       
   702         iBitmap = NULL;
       
   703         }
       
   704     CHAT_DP_FUNC_DONE( "CCAImageLoader::ClearState" );
       
   705     }
       
   706 
       
   707 // End of file