mmappcomponents/mmappcommonui/albumartutility/src/mpximageutil.cpp
changeset 0 a2952bb97e68
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 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:  Implementation of CMPXImageUtil.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32std.h>
       
    21 #include <s32mem.h>
       
    22 #include <bitmaptransforms.h>
       
    23 #include <mda/common/video.h>
       
    24 #include <eikenv.h>
       
    25 #include <MetaDataUtility.h>
       
    26 #include <MetaDataFieldContainer.h>
       
    27 #include <mpxuser.h>
       
    28 #include <mpxlog.h>
       
    29 
       
    30 #include "mpximageutil.h"
       
    31 
       
    32 // CONSTANTS
       
    33 const TInt KMPXBitmapBufferGranularity = 1024;
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // Two-phased constructor.
       
    39 // -----------------------------------------------------------------------------
       
    40 //
       
    41 CMPXImageUtil* CMPXImageUtil::NewL()
       
    42     {
       
    43     MPX_FUNC( "CMPXImageUtil::NewL" );
       
    44     CMPXImageUtil* self = new ( ELeave ) CMPXImageUtil();
       
    45     CleanupStack::PushL( self );
       
    46     self->ConstructL();
       
    47     CleanupStack::Pop( self ); 
       
    48     return self; 
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // C++ constructor can NOT contain any code that might leave.
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 CMPXImageUtil::CMPXImageUtil() :
       
    56     iOperation( EIdle )
       
    57     {
       
    58     MPX_FUNC( "CMPXImageUtil::CMPXImageUtil" );
       
    59     }
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // Symbian 2nd phase constructor can leave.
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 void CMPXImageUtil::ConstructL()
       
    66     {
       
    67     MPX_FUNC( "CMPXImageUtil::ConstructL" );
       
    68     User::LeaveIfError( iFs.Connect() );
       
    69     
       
    70     // this is needed in order to create CFbsBitmap instances and it has to be 
       
    71     // done before instantiating the bitmap scaler
       
    72     User::LeaveIfError( RFbsSession::Connect( iFs ) );
       
    73 
       
    74     iScaler = CBitmapScaler::NewL();
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // Destructor
       
    79 // -----------------------------------------------------------------------------
       
    80 //
       
    81 CMPXImageUtil::~CMPXImageUtil()
       
    82     {
       
    83     MPX_FUNC( "CMPXImageUtil::~CMPXImageUtil" );
       
    84     delete iDecoder; 
       
    85     delete iEncoder; 
       
    86     delete iScaler;
       
    87     
       
    88     if (RFbsSession::GetSession())
       
    89         {
       
    90         RFbsSession::Disconnect();
       
    91         }    
       
    92     iFs.Close();
       
    93     }
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // CMPXImageUtil::ExtractL
       
    97 // Synchronous method.
       
    98 // -----------------------------------------------------------------------------
       
    99 //
       
   100 HBufC8* CMPXImageUtil::ExtractL( const TDesC& aUri )
       
   101     {
       
   102     MPX_FUNC( "CMPXImageUtil::ExtractL" );
       
   103     
       
   104     HBufC8* ret( NULL );
       
   105     CMetaDataUtility* metaDataUtil = CMetaDataUtility::NewL();
       
   106     CleanupStack::PushL( metaDataUtil );
       
   107 
       
   108     RArray<TMetaDataFieldId> wantedFields;
       
   109     CleanupClosePushL( wantedFields );
       
   110     wantedFields.AppendL( EMetaDataJpeg );
       
   111     
       
   112     metaDataUtil->OpenFileL( aUri, wantedFields );
       
   113     const CMetaDataFieldContainer& metaCont = metaDataUtil->MetaDataFieldsL();
       
   114     TPtrC data = metaCont.Field( EMetaDataJpeg );
       
   115     
       
   116     if ( data.Length() )
       
   117         {
       
   118         // if no album art return NULL
       
   119         ret = MPXUser::Alloc8L( data );       
       
   120         }
       
   121     
       
   122     CleanupStack::PopAndDestroy( &wantedFields );
       
   123     CleanupStack::PopAndDestroy( metaDataUtil );
       
   124     
       
   125     return ret;    
       
   126     }
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CMPXImageUtil::Decode 
       
   130 // -----------------------------------------------------------------------------
       
   131 //
       
   132 void CMPXImageUtil::Decode(
       
   133     TRequestStatus& aStatus, 
       
   134     const TDesC& aSourceJPGFile, 
       
   135     CFbsBitmap& aDestBMP, 
       
   136     TSize aSize, 
       
   137     TDisplayMode aDisplayMode /* = EColor64K */)
       
   138     {
       
   139     MPX_FUNC( "CMPXImageUtil::Decode" );
       
   140     TRAPD( err, DoDecodeL( aStatus, aSourceJPGFile, aDestBMP, aSize, aDisplayMode ) );
       
   141     if ( err )
       
   142         {
       
   143         TRequestStatus* status = &aStatus;      
       
   144         User::RequestComplete( status, err );
       
   145         }
       
   146     }
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // Starts to decode an image from a buffer. 
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 void CMPXImageUtil::Decode(
       
   153     TRequestStatus& aStatus,
       
   154     const TDesC8& aJPGData, 
       
   155     CFbsBitmap& aDestBMP,     
       
   156     TSize aSize, 
       
   157     TDisplayMode aDisplayMode /* = EColor64K */)
       
   158     {
       
   159     MPX_FUNC( "CMPXImageUtil::Decode" );
       
   160     TRAPD( err, DoDecodeL( aStatus, aJPGData, aDestBMP, aSize, aDisplayMode ) );
       
   161     if ( err )
       
   162         {
       
   163         TRequestStatus* status = &aStatus;      
       
   164         User::RequestComplete( status, err );
       
   165         }
       
   166     }
       
   167     
       
   168 // -----------------------------------------------------------------------------
       
   169 // CMPXImageUtil::Encode
       
   170 // Converts a BMP to a JPG.
       
   171 // -----------------------------------------------------------------------------
       
   172 //
       
   173 void CMPXImageUtil::Encode(
       
   174     TRequestStatus& aStatus,
       
   175     const CFbsBitmap& aSourceBMP,
       
   176     HBufC8*& aDestJPG )
       
   177     {
       
   178     MPX_FUNC( "CMPXImageUtil::Encode" );
       
   179     TRAPD( err, DoEncodeL( aStatus, aSourceBMP, aDestJPG ) );
       
   180     if ( err )
       
   181         {
       
   182         TRequestStatus* status = &aStatus;      
       
   183         User::RequestComplete( status, err );
       
   184         }
       
   185     }
       
   186     
       
   187 // -----------------------------------------------------------------------------
       
   188 // CMPXImageUtil::Scale
       
   189 // Scales a BMP to a specified size.
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 void CMPXImageUtil::Scale(
       
   193     TRequestStatus& aStatus,
       
   194     CFbsBitmap& aSrcBMP, 
       
   195     CFbsBitmap& aDestBMP,
       
   196     TSize aSize,     
       
   197     TDisplayMode aDisplayMode /* = EColor64K */)
       
   198     {    
       
   199     MPX_FUNC( "CMPXImageUtil::Scale" );
       
   200     TRAPD( err, DoScaleL( aStatus, aSrcBMP, aDestBMP, aSize, aDisplayMode ) );
       
   201     if ( err )
       
   202         {
       
   203         TRequestStatus* status = &aStatus;      
       
   204         User::RequestComplete( status, err );
       
   205         }
       
   206     }
       
   207     
       
   208 // -----------------------------------------------------------------------------
       
   209 // CMPXImageUtil::BitmapL
       
   210 // -----------------------------------------------------------------------------
       
   211 //
       
   212 CFbsBitmap* CMPXImageUtil::BitmapL(
       
   213     const TDesC8& aBMPData)
       
   214     {
       
   215     MPX_FUNC( "CMPXImageUtil::BitmapL" );
       
   216 
       
   217     CFbsBitmap* bitmap = new ( ELeave ) CFbsBitmap;
       
   218     CleanupStack::PushL( bitmap );
       
   219 
       
   220     RDesReadStream stream( aBMPData );
       
   221     CleanupClosePushL( stream );
       
   222     stream >> *bitmap;
       
   223     CleanupStack::PopAndDestroy( &stream );
       
   224     
       
   225     CleanupStack::Pop( bitmap );
       
   226 
       
   227     return bitmap;
       
   228     }
       
   229 
       
   230 // -----------------------------------------------------------------------------
       
   231 // CMPXImageUtil::BitmapDataL
       
   232 // -----------------------------------------------------------------------------
       
   233 //
       
   234 HBufC8* CMPXImageUtil::BitmapDataL(
       
   235     const CFbsBitmap& aBMP)
       
   236     {
       
   237     MPX_FUNC("CMPXImageUtil::BitmapDataL");
       
   238     
       
   239     CBufBase* buffer = CBufSeg::NewL( KMPXBitmapBufferGranularity );
       
   240     CleanupStack::PushL( buffer );
       
   241 
       
   242     RBufWriteStream stream( *buffer );
       
   243     CleanupClosePushL( stream );
       
   244     stream << aBMP;
       
   245     stream.CommitL();
       
   246     CleanupStack::PopAndDestroy( &stream );
       
   247 
       
   248     TInt length( buffer->Size() );
       
   249     HBufC8* data = HBufC8::NewL( length );
       
   250     TPtr8 ptr( data->Des() );
       
   251     buffer->Read( 0, ptr, length );
       
   252 
       
   253     CleanupStack::PopAndDestroy( buffer );
       
   254 
       
   255     return data;
       
   256     }
       
   257     
       
   258 // -----------------------------------------------------------------------------
       
   259 // CMPXImageUtil::CancelRequest
       
   260 // Cancel Asynch requests
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 void CMPXImageUtil::CancelRequest()
       
   264     {
       
   265     MPX_FUNC( "CMPXImageUtil::CancelRequest" );
       
   266     switch ( iOperation )
       
   267         {
       
   268         case EDecoding:
       
   269             {
       
   270             if( iDecoder )
       
   271                 {
       
   272                 iDecoder->Cancel();
       
   273                 delete iDecoder;
       
   274                 iDecoder = NULL;
       
   275                 }
       
   276             break;
       
   277             }
       
   278         case EEncoding:
       
   279             {
       
   280             if( iEncoder )
       
   281                 {
       
   282                 iEncoder->Cancel();
       
   283                 delete iEncoder;
       
   284                 iEncoder = NULL;
       
   285                 }
       
   286             break;
       
   287             }
       
   288         case EScaling:
       
   289             {
       
   290             if( iScaler )
       
   291                 {
       
   292                 iScaler->Cancel();
       
   293                 }
       
   294             break;
       
   295             }
       
   296         default: 
       
   297             {
       
   298             // No Asynchronous events are taking place, do nothing.
       
   299             break;
       
   300             }
       
   301         }
       
   302     }
       
   303 
       
   304 // -----------------------------------------------------------------------------
       
   305 // CMPXImageUtil::DoDecodeL
       
   306 // -----------------------------------------------------------------------------
       
   307 //
       
   308 void CMPXImageUtil::DoDecodeL(
       
   309     TRequestStatus& aStatus, 
       
   310     const TDesC& aSourceJPGFile, 
       
   311     CFbsBitmap& aDestBMP, 
       
   312     TSize aSize,    
       
   313     TDisplayMode aDisplayMode /* = EColor64K */)
       
   314     {
       
   315     MPX_FUNC( "CMPXImageUtil::DoDecodeL" );
       
   316     
       
   317     delete iDecoder; 
       
   318     iDecoder = NULL;
       
   319     // create the decoder
       
   320     iDecoder = CImageDecoder::FileNewL( iFs, aSourceJPGFile );
       
   321     
       
   322     // Get image size
       
   323     const TFrameInfo& frameInfo = iDecoder->FrameInfo();
       
   324     TSize bitmapSize = frameInfo.iOverallSizeInPixels;
       
   325     bitmapSize = OptimalLoadingSize( bitmapSize, aSize );
       
   326 
       
   327     User::LeaveIfError( aDestBMP.Create( bitmapSize, aDisplayMode ) ); 
       
   328 
       
   329     // start conversion to bitmap
       
   330     iOperation = EDecoding;
       
   331     iDecoder->Convert( &aStatus, aDestBMP );
       
   332     }
       
   333     
       
   334 // -----------------------------------------------------------------------------
       
   335 // CMPXImageUtil::DoDecodeL
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 void CMPXImageUtil::DoDecodeL(
       
   339     TRequestStatus& aStatus, 
       
   340     const TDesC8& aSourceJPG, 
       
   341     CFbsBitmap& aDestBMP,     
       
   342     TSize aSize,    
       
   343     TDisplayMode aDisplayMode /* = EColor64K */)
       
   344     {
       
   345     MPX_FUNC( "CMPXImageUtil::DoDecodeL" );
       
   346 
       
   347     delete iDecoder; 
       
   348     iDecoder = NULL;
       
   349 
       
   350     // create the decoder
       
   351     iDecoder = CImageDecoder::DataNewL( iFs, aSourceJPG );
       
   352 
       
   353     // Get image size
       
   354     const TFrameInfo& frameInfo = iDecoder->FrameInfo();
       
   355     TSize bitmapSize = frameInfo.iOverallSizeInPixels;
       
   356     bitmapSize = OptimalLoadingSize( bitmapSize, aSize );
       
   357 
       
   358     // create the destination bitmap
       
   359     User::LeaveIfError( aDestBMP.Create( bitmapSize, aDisplayMode ) ); 
       
   360 
       
   361     // start conversion to bitmap
       
   362     iOperation = EDecoding;
       
   363     iDecoder->Convert( &aStatus, aDestBMP );
       
   364     }
       
   365     
       
   366 // -----------------------------------------------------------------------------
       
   367 // CMPXImageUtil::DoEncodeL
       
   368 // -----------------------------------------------------------------------------
       
   369 //
       
   370 void CMPXImageUtil::DoEncodeL(
       
   371     TRequestStatus& aStatus, 
       
   372     const CFbsBitmap& aSourceBMP, 
       
   373     HBufC8*& aDestJPG)
       
   374     {
       
   375     MPX_FUNC( "CMPXImageUtil::DoEncodeL" );
       
   376     
       
   377     // Encode as JPEG
       
   378     delete iEncoder;
       
   379     iEncoder = NULL;
       
   380     iEncoder = CImageEncoder::DataNewL(
       
   381         aDestJPG, CImageEncoder::EOptionNone, KImageTypeJPGUid );
       
   382     iOperation = EEncoding;
       
   383     iEncoder->Convert( &aStatus, aSourceBMP );        
       
   384     }
       
   385     
       
   386 // -----------------------------------------------------------------------------
       
   387 // CMPXImageUtil::DoScaleL
       
   388 // -----------------------------------------------------------------------------
       
   389 //
       
   390 void CMPXImageUtil::DoScaleL(
       
   391     TRequestStatus& aStatus, 
       
   392     CFbsBitmap& aSourceBMP, 
       
   393     CFbsBitmap& aDestBMP,
       
   394     TSize aSize, 
       
   395     TDisplayMode aDisplayMode /* = EColor64K */)
       
   396     {
       
   397     MPX_FUNC( "CMPXImageUtil::DoScaleL" );
       
   398 
       
   399     // create the destination bitmap
       
   400     User::LeaveIfError( aDestBMP.Create( aSize, aDisplayMode ) );
       
   401     
       
   402     // if TBool aMaintainAspectRatio = ETrue, then the image may not have be
       
   403     // 95x95.  If TBool aMaintainAspectRatio = EFalse, the image may appear
       
   404     // to be stretched, as the aspect ratio is not maintained.
       
   405     iOperation = EScaling;
       
   406     iScaler->Scale( &aStatus, aSourceBMP, aDestBMP, ETrue );
       
   407     }
       
   408 
       
   409 // -----------------------------------------------------------------------------
       
   410 // Determines optimum loading size for the bitmap.
       
   411 // -----------------------------------------------------------------------------
       
   412 TSize CMPXImageUtil::OptimalLoadingSize(
       
   413     const TSize& aOriginalSize,
       
   414     const TSize& aNeededSize )
       
   415     {
       
   416     TSize size = AdjustSize( aOriginalSize, aNeededSize );
       
   417     
       
   418     // Find max scaling factor which won't make image smaller than target size
       
   419     TInt shift = 3;
       
   420     while (shift && ( ( aOriginalSize.iWidth >> shift ) < size.iWidth || 
       
   421         ( aOriginalSize.iHeight >> shift ) < size.iHeight ) )
       
   422         {
       
   423         shift--;
       
   424         }
       
   425 
       
   426     TInt round = ( 1 << shift ) - 1;  // Used to "round up" the scaled values
       
   427     TSize loadSize( ( aOriginalSize.iWidth + round ) >> shift,
       
   428         ( aOriginalSize.iHeight + round ) >> shift );
       
   429         
       
   430     return loadSize;
       
   431     }
       
   432 
       
   433 // -----------------------------------------------------------------------------
       
   434 // CMPXImageUtil::AdjustSize
       
   435 // -----------------------------------------------------------------------------
       
   436 //
       
   437 TSize CMPXImageUtil::AdjustSize(
       
   438     const TSize& aSourceSize,
       
   439     const TSize& aTargetSize )
       
   440     {
       
   441     TSize size( aTargetSize );
       
   442     
       
   443     if ( aTargetSize.iHeight * aSourceSize.iWidth < 
       
   444         aTargetSize.iWidth * aSourceSize.iHeight )
       
   445         {
       
   446         // Source has taller aspect than target so reduce target width
       
   447         size.iWidth = ( aTargetSize.iHeight * aSourceSize.iWidth ) / 
       
   448             aSourceSize.iHeight;
       
   449         }
       
   450     else
       
   451         {
       
   452         // Source has wider aspect than target so reduce target height
       
   453         size.iHeight = ( aTargetSize.iWidth * aSourceSize.iHeight ) / 
       
   454             aSourceSize.iWidth;
       
   455         }
       
   456         
       
   457     return size;        
       
   458     }
       
   459 
       
   460 //  End of File