homesync/contentmanager/cmserver/cmmemorymanager/src/cmmmshrinker.cpp
branchIOP_Improvements
changeset 40 08b5eae9f9ff
parent 39 6369bfd1b60d
child 41 b4d83ea1d6e2
equal deleted inserted replaced
39:6369bfd1b60d 40:08b5eae9f9ff
     1 /*
       
     2 * Copyright (c) 2006-2007 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:  CCmShrinker class in the Memory manager component
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <imageconversion.h> // CImageDecoder, CImageEncoder
       
    21 #include <bitmaptransforms.h> // CBitmapScaler
       
    22 #include <fbs.h> // CFbsBitmap
       
    23 #include <w32std.h> // RWsSession, CWsScreenDevice
       
    24 
       
    25 #include "cmdmmain.h"
       
    26 #include "msdebug.h"
       
    27 #include "cmmmimagemetadataresolver.h"
       
    28 #include "cmmmobserver.h"
       
    29 #include "cmmmshrinker.h"
       
    30 
       
    31 // CONSTANTS
       
    32 const TInt KScreenWidth = 128;
       
    33 const TInt KScreenHeight = 128;
       
    34 
       
    35 
       
    36 // ---------------------------------------------------------------------------
       
    37 // CCmMmShrinker::NewL
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 CCmMmShrinker* CCmMmShrinker::NewL( CCmDmMain& aDbManager )
       
    41     {
       
    42     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewL() start"));
       
    43     CCmMmShrinker* self = CCmMmShrinker::NewLC( aDbManager );
       
    44     CleanupStack::Pop( self );
       
    45     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewL() end"));
       
    46     return self;
       
    47     }
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // CCmMmShrinker::NewLC
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 CCmMmShrinker* CCmMmShrinker::NewLC( CCmDmMain& aDbManager )
       
    54     {
       
    55     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewLC() start"));
       
    56     CCmMmShrinker* self = new ( ELeave ) CCmMmShrinker( aDbManager );
       
    57     CleanupStack::PushL( self );
       
    58     self->ConstructL();
       
    59     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewLC() end"));
       
    60     return self;
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // C++ constructor
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CCmMmShrinker::CCmMmShrinker( CCmDmMain& aDbManager ) :
       
    68     CActive( EPriorityIdle ),
       
    69     iShrinkIndex( 0 ),
       
    70     iState( EIdle ),
       
    71     iDbManager( aDbManager )
       
    72     {
       
    73     
       
    74     CActiveScheduler::Add( this );
       
    75     }
       
    76 
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // CCmMmShrinker::ConstructL
       
    80 // ---------------------------------------------------------------------------
       
    81 //
       
    82 void CCmMmShrinker::ConstructL()
       
    83     {
       
    84     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ConstructL() start"));
       
    85 
       
    86     User::LeaveIfError( iFileSession.Connect() );
       
    87     User::LeaveIfError( RFbsSession::Connect() );
       
    88 
       
    89     // Get the screen size
       
    90     iScreenSize = ScreenSizeL();
       
    91     
       
    92     iImageMetadataResolver = CCmMmImageMetadataResolver::NewL( iFileSession );
       
    93 
       
    94     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ConstructL() end"));
       
    95     }
       
    96 
       
    97 
       
    98 // ---------------------------------------------------------------------------
       
    99 // C++ destructor
       
   100 // ---------------------------------------------------------------------------
       
   101 //
       
   102 CCmMmShrinker::~CCmMmShrinker()
       
   103     {
       
   104     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::~CCmMmShrinker() start"));
       
   105     Cancel();
       
   106     delete iBitmap;
       
   107     iFileSession.Close();
       
   108     
       
   109     delete iBitmapScaler;
       
   110     delete iFiles;
       
   111     delete iImageDecoder;
       
   112     delete iImageEncoder;
       
   113     RFbsSession::Disconnect();
       
   114     delete iImageMetadataResolver;
       
   115     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::~CCmMmShrinker() end"));
       
   116     }
       
   117 
       
   118 // ---------------------------------------------------------------------------
       
   119 // CCmMmShrinker::DoCancel
       
   120 // ---------------------------------------------------------------------------
       
   121 //
       
   122 void CCmMmShrinker::DoCancel()
       
   123     {
       
   124     ClearShrinker();
       
   125     }
       
   126 
       
   127 // ---------------------------------------------------------------------------
       
   128 // CCmMmShrinker::RunError
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 #ifdef _DEBUG
       
   132 TInt CCmMmShrinker::RunError( TInt aError )
       
   133 #else //_DEBUG
       
   134 TInt CCmMmShrinker::RunError( TInt /*aError*/ )
       
   135 #endif // _DEBÚG
       
   136     {
       
   137     TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunError error = %d"),
       
   138                                                              aError ));
       
   139                                                                     
       
   140     // NOTE!!!
       
   141     // Should we continue from the next file, if there's error in the 
       
   142     // middle of the shrinking operation
       
   143     iShrinkIndex++;
       
   144     iState = EIdle;
       
   145     SetActive();
       
   146     TRequestStatus* status = &iStatus;
       
   147     User::RequestComplete( status, KErrNone );
       
   148     return KErrNone;
       
   149     }
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // CCmMmShrinker::ShrinkImagesL
       
   153 // ---------------------------------------------------------------------------
       
   154 //
       
   155 void CCmMmShrinker::ShrinkImagesL( CDesCArray& aFiles )
       
   156     {
       
   157     // Cancel 1st
       
   158     Cancel();
       
   159     
       
   160     // Add processed files 
       
   161     if ( &aFiles )
       
   162         {
       
   163         delete iFiles; 
       
   164         iFiles = NULL;
       
   165         iFiles = new ( ELeave ) CDesC16ArrayFlat( aFiles.Count() );
       
   166         for (TInt i = 0; i < aFiles.Count(); i++)
       
   167             {
       
   168             iFiles->AppendL( aFiles[i] );
       
   169             }
       
   170         }
       
   171     // Start the action
       
   172     iShrinkIndex = 0;
       
   173     iState = EIdle;
       
   174     SetActive();
       
   175     TRequestStatus* status = &iStatus;
       
   176     User::RequestComplete( status, KErrNone);    
       
   177     }
       
   178     
       
   179 // ---------------------------------------------------------------------------
       
   180 // CCmMmShrinker::SetObserver
       
   181 // ---------------------------------------------------------------------------
       
   182 //
       
   183 void CCmMmShrinker::SetObserver( MCmMmObserver* aObserver )
       
   184     {
       
   185     iObserver = aObserver;
       
   186     }
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 // CCmMmShrinker::RunL
       
   190 // ---------------------------------------------------------------------------
       
   191 //
       
   192 void CCmMmShrinker::RunL()
       
   193     {
       
   194     TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL status = %d"),
       
   195                                                              iStatus.Int() ));
       
   196 
       
   197     // If all files have been processed, notify the observer.
       
   198     if ( iShrinkIndex >= iFiles->Count() )
       
   199         {
       
   200         if ( iObserver )
       
   201             {
       
   202             iObserver->ShrinkCompleteL( KErrNone );
       
   203             }
       
   204         }
       
   205     else 
       
   206         {
       
   207         if ( iState == EIdle )
       
   208             {
       
   209             const TDesC& origFilename = (*iFiles)[iShrinkIndex];
       
   210             iImageMetadataResolver->CaptureOrginalMetadataL( origFilename );
       
   211             // Check that file exists (entry is not actually used)
       
   212             TEntry entry;
       
   213             User::LeaveIfError( iFileSession.Entry( origFilename, entry ));
       
   214             iStartTime.HomeTime();
       
   215             CImageDecoder* imageDecoder = NULL;
       
   216             TRAPD( error, 
       
   217                    imageDecoder = CImageDecoder::FileNewL( 
       
   218                         iFileSession,
       
   219                         origFilename,
       
   220                         CImageDecoder::EOptionNone ) );
       
   221             if ( error )
       
   222                 {
       
   223                 if ( iObserver )
       
   224                     {
       
   225                     iObserver->ShrinkCompleteL( error );
       
   226                     }
       
   227                 }
       
   228             else
       
   229             	{
       
   230             	TUid imageType = KNullUid;
       
   231 	            TUid imageSubType = KNullUid;
       
   232 	            imageDecoder->ImageType( 0, imageType, imageSubType );
       
   233 
       
   234 	            if (  imageType == KImageTypeBMPUid )
       
   235 	                {
       
   236 	                iState = EScale;
       
   237 	                }
       
   238 	            else if ( imageType == KImageTypeGIFUid ||
       
   239 	                      imageType == KImageTypePNGUid ||
       
   240 	                      imageType == KImageTypeJPGUid )
       
   241 	                {
       
   242 	                iState = EDecode;
       
   243 	                }
       
   244 	            else
       
   245 	                {
       
   246 	                if ( iObserver )
       
   247 	                    {
       
   248 	                    iObserver->ShrinkCompleteL( KErrNone );
       
   249 	                    }
       
   250 	                }
       
   251 
       
   252 	            delete imageDecoder;
       
   253 	            imageDecoder = NULL;
       
   254             	}
       
   255             }
       
   256 
       
   257         TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: status = %d"),
       
   258             iStatus.Int() ));
       
   259 
       
   260         switch ( iState )
       
   261             {
       
   262             case EDecode:
       
   263                 {
       
   264                 const TDesC& origFilename = (*iFiles)[iShrinkIndex];
       
   265                 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: Decoding file \
       
   266                     %S"), &origFilename ));
       
   267 
       
   268                 delete iImageDecoder;
       
   269                 iImageDecoder = NULL;
       
   270                 delete iBitmap;
       
   271                 iBitmap = NULL;
       
   272 
       
   273                 iImageDecoder = CImageDecoder::FileNewL( iFileSession,
       
   274                                                          origFilename, CImageDecoder::EOptionNone );
       
   275                 iBitmap = new (ELeave) CFbsBitmap();
       
   276                 TInt error = iBitmap->Create(
       
   277                     iImageDecoder->FrameInfo().iOverallSizeInPixels,
       
   278                     iImageDecoder->FrameInfo().iFrameDisplayMode );
       
   279                 if ( error != KErrNone )
       
   280                     {
       
   281                     TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL \
       
   282                         error: %d"), error ));
       
   283                     if ( iObserver )
       
   284                         {
       
   285                         TRACE(Print(_L("[MEMORY MNGR]\t Clearing shrinker" )));                        
       
   286                         ClearShrinker();
       
   287                         iObserver->ShrinkCompleteL( error );
       
   288                         }
       
   289                     Cancel();
       
   290                     }
       
   291                 else 
       
   292                     {
       
   293                     iImageDecoder->Convert( &iStatus, *iBitmap );
       
   294 
       
   295                     iState = EScale;
       
   296                     SetActive();
       
   297                     }
       
   298                 break;
       
   299                 }
       
   300             case EScale:
       
   301                 {
       
   302                 const TDesC& origFilename = (*iFiles)[iShrinkIndex];
       
   303                 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: Scaling file \
       
   304                     %S"), &origFilename ));
       
   305 
       
   306                 // If converting is still ongoing we should continue it
       
   307                 if ( iStatus == KErrUnderflow )
       
   308                     {
       
   309                     TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: \
       
   310     Still decoding file %S"), &origFilename ));
       
   311                     iImageDecoder->ContinueConvert( &iStatus );
       
   312                     SetActive();
       
   313                     }
       
   314                 else 
       
   315                     {
       
   316                     delete iBitmapScaler;
       
   317                     iBitmapScaler = NULL;
       
   318                     iBitmapScaler = CBitmapScaler::NewL();
       
   319 
       
   320                     iBitmapScaler->Scale( &iStatus, *iBitmap, iScreenSize );
       
   321                     iState = EEncode;
       
   322                     SetActive();
       
   323 
       
   324                     delete iImageDecoder;
       
   325                     iImageDecoder = NULL;
       
   326                     }
       
   327 
       
   328                 break;
       
   329                 }
       
   330             case EEncode:
       
   331                 {
       
   332                 const TDesC& origFilename = (*iFiles)[iShrinkIndex];
       
   333                 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: Encoding file \
       
   334                     %S"), &origFilename ));
       
   335 
       
   336                 delete iImageEncoder;
       
   337                 iImageEncoder = NULL;
       
   338                 
       
   339                 // Shrink into private directory
       
   340                 PrivatePath( iFileSession, iTempFilename, origFilename );
       
   341                 
       
   342                 // Check that if the file already exists somehow...
       
   343                 if ( iTempFilename == origFilename )
       
   344                     {
       
   345                     // Delete the original
       
   346                     iFileSession.Delete( origFilename );
       
   347                     }
       
   348                 iImageEncoder = CImageEncoder::FileNewL(
       
   349                     iFileSession,
       
   350                     iTempFilename,
       
   351                     CImageEncoder::EOptionNone,
       
   352                     KImageTypeJPGUid );
       
   353 
       
   354                 iImageEncoder->Convert( &iStatus, *iBitmap );
       
   355                 iState = EReplace;
       
   356 
       
   357                 SetActive();
       
   358                 break;
       
   359                 }
       
   360             case EReplace:
       
   361                 {
       
   362                 const TDesC& origFilename = (*iFiles)[iShrinkIndex];
       
   363                 TRACE( Print(
       
   364                     _L("[MEMORY MNGR]\t CCmMmShrinker: Replacing file %S"),
       
   365                     &origFilename) );                                                 
       
   366                                                         
       
   367                 TInt error = iFileSession.Replace( 
       
   368                     iTempFilename, 
       
   369                     origFilename );                                       
       
   370                     
       
   371                 TRACE( Print(
       
   372                     _L("[MEMORY MNGR]\t CCmMmShrinker: Replace done err: %d"),
       
   373                     error ) );
       
   374                     
       
   375                 // Resolve orginal image metadata!!!
       
   376                 TRAPD( mdError, iImageMetadataResolver->ResolveMetadataL(
       
   377                         origFilename ) );
       
   378                 if( mdError )
       
   379                     {
       
   380                     TRACE( Print(
       
   381                         _L("[MEMORY MNGR]\t Metadata resolving error : %d"),
       
   382                         mdError ) );                    
       
   383                     }
       
   384                     
       
   385                 iStopTime.HomeTime();
       
   386 
       
   387                 TTimeIntervalMicroSeconds t =
       
   388                     iStartTime.MicroSecondsFrom( iStopTime );
       
   389                 error =  iDbManager.IncrementShrinkTimeL(
       
   390                     iFiles->Count(),
       
   391                     iStartTime.MicroSecondsFrom( iStopTime ).Int64() / 1000 );
       
   392                     
       
   393                 iState = EIdle;
       
   394                 iShrinkIndex++;
       
   395                 SetActive();
       
   396                 TRequestStatus* status = &iStatus;
       
   397                 User::RequestComplete( status, KErrNone );
       
   398                 break;
       
   399                 }
       
   400             case EIdle:
       
   401             	{
       
   402             	TRACE( Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL() \
       
   403                 Idle state")) );
       
   404                 break;
       
   405                 }
       
   406             default:
       
   407                 {
       
   408                 TRACE( Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL() \
       
   409                 Incorrect state")) );
       
   410                 if ( iObserver )
       
   411                     {
       
   412                     iObserver->ShrinkCompleteL( iStatus.Int() );
       
   413                     }
       
   414                 Cancel();
       
   415                 break;
       
   416                 }
       
   417             }
       
   418         }
       
   419     }
       
   420 
       
   421 
       
   422 // ---------------------------------------------------------------------------
       
   423 // CCmMmShrinker::ScreenSizeL
       
   424 // ---------------------------------------------------------------------------
       
   425 //
       
   426 TSize CCmMmShrinker::ScreenSizeL()
       
   427     {
       
   428     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ScreenSizeL() start"));
       
   429 
       
   430     TSize screenSize( KScreenWidth, KScreenHeight );
       
   431     RWsSession session;
       
   432 
       
   433     TInt error = session.Connect() ;
       
   434     CleanupClosePushL( session );
       
   435     if ( !error )
       
   436         {
       
   437         CWsScreenDevice* screenDevice = 
       
   438             new ( ELeave ) CWsScreenDevice( session );
       
   439         if ( screenDevice && !screenDevice->Construct() )
       
   440             {
       
   441             TSize temp( KScreenWidth, KScreenHeight );
       
   442             temp = screenDevice->SizeInPixels();
       
   443             // Use landscape mode in shrinking
       
   444             TRACE(Print(_L("[MEMORY MNGR]\t Image height = %d"),temp.iWidth));
       
   445             TRACE(Print(_L("[MEMORY MNGR]\t Image width = %d"),temp.iHeight)); 
       
   446             screenSize.iHeight = temp.iWidth;
       
   447             screenSize.iWidth = temp.iHeight;
       
   448             }
       
   449         delete screenDevice;
       
   450         screenDevice = NULL;
       
   451         }
       
   452 
       
   453     CleanupStack::PopAndDestroy( &session );
       
   454 
       
   455     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ScreenSizeL() end"));
       
   456     return screenSize;
       
   457     }
       
   458 
       
   459 // ---------------------------------------------------------------------------
       
   460 // CCmMmShrinker::PrivatePath
       
   461 // ---------------------------------------------------------------------------
       
   462 //   
       
   463 void CCmMmShrinker::PrivatePath( RFs& aFs, 
       
   464                                  TFileName& aPrivatePath, 
       
   465                                  const TFileName& aOriginal )
       
   466     {
       
   467     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::PrivatePath() start"));
       
   468     
       
   469     aPrivatePath.Zero();
       
   470     
       
   471     TParse nameParse;
       
   472     nameParse.Set( aOriginal, NULL, NULL );
       
   473         
       
   474     aPrivatePath.Append( nameParse.Drive() );
       
   475     TFileName privatePath;
       
   476     TInt err = aFs.PrivatePath( privatePath );
       
   477     if ( !err )
       
   478         {
       
   479         aPrivatePath.Append( privatePath );
       
   480         
       
   481         // Now the path contains everything but filename and extension
       
   482         // => check that the directory exists. If not, it will be created.
       
   483         // Possible error is ignored at the moment 
       
   484         // (normal case is KErrAlreadyExists)
       
   485         err = aFs.MkDirAll( aPrivatePath );
       
   486         
       
   487         
       
   488         aPrivatePath.Append( nameParse.NameAndExt() );
       
   489         }
       
   490     LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::PrivatePath() end"));
       
   491     }
       
   492     
       
   493 // ---------------------------------------------------------------------------
       
   494 // CCmMmShrinker::ClearShrinker
       
   495 // ---------------------------------------------------------------------------
       
   496 //
       
   497 void CCmMmShrinker::ClearShrinker()
       
   498     {
       
   499     if ( iImageDecoder )
       
   500         {
       
   501         iImageDecoder->Cancel();
       
   502         delete iImageDecoder;
       
   503         iImageDecoder = NULL;
       
   504         }
       
   505     if ( iBitmapScaler )
       
   506         {
       
   507         iBitmapScaler->Cancel();
       
   508         delete iBitmapScaler;
       
   509         iBitmapScaler = NULL;        
       
   510         }
       
   511     if ( iImageEncoder )
       
   512         {
       
   513         iImageEncoder->Cancel();
       
   514         delete iImageEncoder;
       
   515         iImageEncoder = NULL;        
       
   516         }
       
   517     if( iBitmap )
       
   518         {
       
   519         delete iBitmap;
       
   520         iBitmap = NULL;
       
   521         }
       
   522     }
       
   523     
       
   524 // End of file
       
   525