connectivitymodules/SeCon/services/pcd/src/sconmetadata.cpp
branchRCL_3
changeset 20 4a793f564d72
equal deleted inserted replaced
19:0aa8cc770c8a 20:4a793f564d72
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "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:  SConMetadata implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include <utf.h>  // for CnvUtfConverter
       
    22 #include <MetaDataUtility.h>
       
    23 #include <MetaDataFieldContainer.h>
       
    24 #include <MetaDataField.hrh>
       
    25 #include <caf/content.h>
       
    26 #include <caf/data.h>
       
    27 #include <ExifRead.h>
       
    28 #include <ExifTag.h>
       
    29 
       
    30 #include "sconmetadata.h"
       
    31 #include "sconconmltask.h"
       
    32 #include "sconpcdconsts.h"
       
    33 #include "sconvideoparser.h"
       
    34 #include "debug.h"
       
    35 #include "sconmetadatafielddefs.h"
       
    36 
       
    37 
       
    38 
       
    39 const TInt KBufferSize(1024);
       
    40 // Size of buffer to load from file start to get EXIF thumbnail
       
    41 const TInt KJpegLoadBufferSize = 65536; // 64k
       
    42 
       
    43 
       
    44 const TUint32 KFieldMaxLength = 0xFFFFFFFF; // four bytes reserved for "length" information
       
    45 
       
    46 // GPS related Exif IDs
       
    47 const TUint16 KGPSLatitudeRef	= 0x01;
       
    48 const TUint16 KGPSLatitude 	 	= 0x02;
       
    49 const TUint16 KGPSLongitudeRef	= 0x03;
       
    50 const TUint16 KGPSLongitude		= 0x04;
       
    51 const TUint16 KGPSAltitudeRef	= 0x05;
       
    52 const TUint16 KGPSAltitude		= 0x06;
       
    53 
       
    54 
       
    55 // extensions for exif parser
       
    56 _LIT(KJpgExt, ".jpg");
       
    57 _LIT(KJpegExt, ".jpeg");
       
    58 // extensions for audio metadata parser
       
    59 _LIT(KAacExt, ".aac");
       
    60 _LIT(KMp3Ext, ".mp3");
       
    61 _LIT(KMp4Ext, ".mp4");
       
    62 _LIT(KWmaExt, ".wma");
       
    63 // extensions for video metadata parser
       
    64 _LIT(KM4aExt, ".m4a");
       
    65 _LIT(K3gpExt, ".3gp");
       
    66 
       
    67 
       
    68 // ============================= MEMBER FUNCTIONS ===============================
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // SConMetadata::ProcessTask()
       
    72 // ProcessTask
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 void SConMetadata::ProcessTask( CSConTask& aTask, RFs& aFs )
       
    76     {
       
    77     TRACE_FUNC_ENTRY;
       
    78     TInt err(KErrNone);
       
    79     if ( aTask.GetServiceId() == EGetMetadata )
       
    80         {
       
    81         LOGGER_WRITE_1( "SConMetadata::ProcessTask() : file %S",
       
    82             &aTask.iGetMetadataParams->iFilename );
       
    83         
       
    84 #ifdef _DEBUG
       
    85         LOGGER_WRITE( "start.. " );
       
    86         TTimeIntervalMicroSeconds sec;
       
    87         TTime start;
       
    88         TTime end;
       
    89         start.HomeTime();
       
    90 #endif
       
    91         
       
    92         TParsePtrC filename( aTask.iGetMetadataParams->iFilename );
       
    93         
       
    94         if ( filename.Ext().CompareF( KJpgExt ) == 0
       
    95             || filename.Ext().CompareF( KJpegExt ) == 0 )
       
    96             {
       
    97             // jpg file, try to read exif
       
    98             LOGGER_WRITE( "jpg file, Try to read exif" );
       
    99             TRAP( err, ReadExifDataL( aTask, aFs ) );
       
   100             }
       
   101         else if ( filename.Ext().CompareF( KMp4Ext ) == 0
       
   102             || filename.Ext().CompareF( K3gpExt ) == 0 )
       
   103         	{
       
   104         	LOGGER_WRITE( "Try to read video" );
       
   105         	TRAP( err, GetVideoMetadataL( aTask, aFs ) );
       
   106         	}
       
   107         else if ( filename.Ext().CompareF( KAacExt ) == 0
       
   108             || filename.Ext().CompareF( KM4aExt ) == 0
       
   109             || filename.Ext().CompareF( KMp3Ext ) == 0
       
   110             || filename.Ext().CompareF( KWmaExt ) == 0 )
       
   111             {
       
   112 
       
   113             // audio file, try to read audio
       
   114             LOGGER_WRITE( "Try to read audio" );
       
   115             TRAP( err, GetAudioMetadataL( aTask ) );
       
   116             }
       
   117         else
       
   118             {
       
   119             LOGGER_WRITE( "File extension not supported" );
       
   120             err = KErrNotSupported;
       
   121             }
       
   122         
       
   123 #ifdef _DEBUG
       
   124         end.HomeTime();
       
   125         sec = end.MicroSecondsFrom( start );
       
   126         
       
   127         LOGGER_WRITE_1( "trapErr %d", err );
       
   128         LOGGER_WRITE_1( "duration: %Ld", sec.Int64() );
       
   129 #endif
       
   130         }
       
   131     else
       
   132         {
       
   133         LOGGER_WRITE( "SConMetadata::ProcessTask() : not supported" );
       
   134         err = KErrNotSupported;
       
   135         }
       
   136     
       
   137     LOGGER_WRITE( "SConMetadata::ProcessTask() : CompleteTask" );
       
   138     
       
   139     TInt progress( KSConCodeTaskCompleted );        
       
   140     TBool complete ( ETrue );
       
   141     switch( err )
       
   142         {
       
   143         case KErrNone :
       
   144             progress =  KSConCodeTaskCompleted;
       
   145             break;
       
   146         case KErrNotFound :
       
   147         case KErrBadName :
       
   148             progress =  KSConCodeNotFound;
       
   149             break;
       
   150         default :
       
   151             progress = KSConCodeConflict;
       
   152             break;
       
   153         }
       
   154         
       
   155     aTask.SetCompleteValue( complete );
       
   156     aTask.SetProgressValue( progress );
       
   157     TRACE_FUNC_EXIT;
       
   158     }
       
   159 
       
   160 // -----------------------------------------------------------------------------
       
   161 // SConMetadata::GetAudioMetadataL()
       
   162 // Read audio metadata
       
   163 // -----------------------------------------------------------------------------
       
   164 //
       
   165 void SConMetadata::GetAudioMetadataL( CSConTask& aTask )
       
   166     {
       
   167     TRACE_FUNC_ENTRY;
       
   168     CMetaDataUtility* metadataUtil = CMetaDataUtility::NewL();
       
   169     CleanupStack::PushL( metadataUtil );
       
   170     
       
   171     LOGGER_WRITE( "SConMetadata::GetAudioMetadataL() : OpenFileL" );
       
   172     metadataUtil->OpenFileL( aTask.iGetMetadataParams->iFilename );
       
   173     
       
   174     TInt count = metadataUtil->MetaDataCount();
       
   175     LOGGER_WRITE_1( "SConMetadata::GetAudioMetadataL() : MetaDataCount %d", count );
       
   176     if ( count > 0 )
       
   177         {
       
   178         const CMetaDataFieldContainer& fields = metadataUtil->MetaDataFieldsL();
       
   179         count = fields.Count();
       
   180         
       
   181         CBufFlat* buffer = CBufFlat::NewL( KBufferSize );
       
   182         CleanupStack::PushL( buffer );
       
   183         buffer->Reset();
       
   184         
       
   185         
       
   186         TInt offset(0);
       
   187         // write object header
       
   188         // Item type (1 byte) + Version (1 byte) = 2 bytes
       
   189         buffer->ExpandL( offset, 2 );
       
   190     
       
   191         // header id
       
   192         TUint8 value( KSconMetadataHeaderAudio );
       
   193         buffer->Write( offset, TPtrC8(&value, 1) );
       
   194         offset++;
       
   195         
       
   196         // header version
       
   197         value = KSconMetadataHeaderVersion;
       
   198         buffer->Write( offset, TPtrC8(&value, 1) );
       
   199         offset++;
       
   200         
       
   201         // Add ID3 field
       
   202         value = metadataUtil->ID3Version();
       
   203         AppendTUintDataFieldL( buffer, value, KSconAudioID3Version );
       
   204         
       
   205         TMetaDataFieldId fieldId;
       
   206         TPtrC fieldData;
       
   207         
       
   208         for ( TInt i = 0; i < count; i++ )
       
   209             {
       
   210             // get field id
       
   211             fields.FieldIdAt( i , fieldId );
       
   212             LOGGER_WRITE_2( "AudioFieldId( %d ): 0x%02x", i, fieldId );
       
   213             TUint8 sconFieldId = AudioFieldId( fieldId );
       
   214             if ( sconFieldId == KSconAudioJpeg )
       
   215                 {
       
   216                 TPtrC8 field8( fields.Field8( fieldId ) );
       
   217                 AppendByteDataFieldL(
       
   218                     buffer,
       
   219                     field8,
       
   220                     AudioFieldId( fieldId ) );
       
   221                 }
       
   222             else if ( sconFieldId > 0 )
       
   223                 {
       
   224                 // get field data and add UTF-8 formatted text to buffer
       
   225                 fieldData.Set( fields.At( i , fieldId ) );
       
   226                 AppendUtf8DataFieldL( buffer, fieldData, sconFieldId );
       
   227                 }
       
   228             else
       
   229                 {
       
   230                 LOGGER_WRITE("Unknown field skipped");
       
   231                 }
       
   232             }
       
   233         
       
   234         if ( buffer->Size() > 0 )
       
   235             {
       
   236             LOGGER_WRITE_1( "SConMetadata::GetAudioMetadataL() : buffer->Size() %d", buffer->Size() );
       
   237             if ( aTask.iGetMetadataParams->iData )
       
   238                 {
       
   239                 delete aTask.iGetMetadataParams->iData;
       
   240                 aTask.iGetMetadataParams->iData = NULL;
       
   241                 }
       
   242             //Initialize the task data buffer
       
   243             aTask.iGetMetadataParams->iData = HBufC8::NewL( buffer->Size() );
       
   244             TPtr8 dataPtr = aTask.iGetMetadataParams->iData->Des();
       
   245             
       
   246             buffer->Read( 0, dataPtr, buffer->Size() );
       
   247             LOGGER_WRITE_1( "SConMetadata::GetAudioMetadataL() dataPtr len: %d", dataPtr.Length());
       
   248             }
       
   249         CleanupStack::PopAndDestroy( buffer );
       
   250         }
       
   251     
       
   252     CleanupStack::PopAndDestroy( metadataUtil );
       
   253     
       
   254     TRACE_FUNC_EXIT;
       
   255     }
       
   256 
       
   257 // -----------------------------------------------------------------------------
       
   258 // SConMetadata::GetVideoMetadataL()
       
   259 // Read video metadata
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 void SConMetadata::GetVideoMetadataL( CSConTask& aTask, RFs& aFs )
       
   263 	{
       
   264 	TRACE_FUNC_ENTRY;
       
   265 	CBufFlat* buffer = CBufFlat::NewL( KBufferSize );
       
   266     CleanupStack::PushL( buffer );
       
   267     buffer->Reset();
       
   268     
       
   269     TInt offset(0);
       
   270     // write object header
       
   271     // Item type (1 byte) + Version (1 byte) = 2 bytes
       
   272     buffer->ExpandL( offset, 2 );
       
   273 
       
   274     // header id
       
   275     TUint8 value( KSconMetadataHeaderVideo );
       
   276     buffer->Write( offset, TPtrC8(&value, 1) );
       
   277     offset++;
       
   278     
       
   279     // header version
       
   280     value = KSconMetadataHeaderVersion;
       
   281     buffer->Write( offset, TPtrC8(&value, 1) );
       
   282     offset++;
       
   283     
       
   284 	
       
   285 	CSConVideoParser* videoParser = CSConVideoParser::NewLC();
       
   286 	
       
   287 	videoParser->OpenFileL( aFs, aTask.iGetMetadataParams->iFilename );
       
   288 	LOGGER_WRITE( "Open completed" );
       
   289 	
       
   290 	const TUint KFormatMaxLength = 100;
       
   291 	TBuf<KFormatMaxLength> formatMimeType;
       
   292     formatMimeType.Copy( videoParser->VideoFormatMimeTypeL() );
       
   293     LOGGER_WRITE_1( "formatMimeType: %S", &formatMimeType);
       
   294     AppendUtf8DataFieldL( buffer, formatMimeType, KSconVideoFormat );
       
   295 	
       
   296     // we can't use TReal format, so convert frame rate to frames/ms (or 1000 frames/s)
       
   297 	TReal32 frameRate = videoParser->VideoFrameRateL();
       
   298 	const TUint KFrameRateMultiplier = 1000;
       
   299     TInt frm = frameRate * KFrameRateMultiplier; 
       
   300     LOGGER_WRITE_1( "frameRate: %f", frameRate );
       
   301     LOGGER_WRITE_1( "frm: %d", frm );
       
   302     AppendTUintDataFieldL( buffer, frm, KSconVideoFrameRate );
       
   303     
       
   304     TSize size;
       
   305     videoParser->VideoFrameSizeL( size );
       
   306     LOGGER_WRITE_2( "VideoFrameSizeL: %d, %d", size.iWidth, size.iHeight);
       
   307     AppendTUintDataFieldL( buffer, size.iWidth, KSconVideoFrameSizeWidth );
       
   308     AppendTUintDataFieldL( buffer, size.iHeight, KSconVideoFrameSizeHeight );
       
   309     
       
   310 
       
   311 
       
   312     const TUint8 KSconVideoAudioStreamMimetype	( 0x09 );
       
   313     const TUint8 KSconVideoVideoStreamMimetype	( 0x0a );
       
   314     
       
   315     TInt videoBitRate =  videoParser->VideoBitRateL();
       
   316     LOGGER_WRITE_1( "videoBitRate: %d", videoBitRate);
       
   317     AppendTUintDataFieldL( buffer, videoBitRate, KSconVideoVideoBitRate );
       
   318     
       
   319 	TInt audioBitRate = videoParser->AudioBitRateL();
       
   320 	LOGGER_WRITE_1( "audioBitRate: %d", audioBitRate);
       
   321 	AppendTUintDataFieldL( buffer, audioBitRate, KSconVideoAudioBitRate );
       
   322 
       
   323 	TInt durationMs = videoParser->DurationL();
       
   324 	LOGGER_WRITE_1( "duration ms: %d", durationMs);
       
   325 	AppendTUintDataFieldL( buffer, durationMs, KSconVideoDuration );
       
   326 	
       
   327 	TPtrC8 thumbnail = videoParser->Thumbnail();
       
   328 	if ( thumbnail.Length() > 0 )
       
   329 	    {
       
   330 	    AppendByteDataFieldL( buffer, thumbnail, KSconVideoThumbnail );
       
   331 	    }
       
   332 	
       
   333 	TPtrC audioMimeType = videoParser->AudioMimeTypeL();
       
   334 	if ( audioMimeType.Length() > 0 )
       
   335 		{
       
   336 		AppendUtf8DataFieldL( buffer, audioMimeType, KSconVideoAudioStreamMimetype );
       
   337 		}
       
   338 	
       
   339 	TPtrC videoMimeType = videoParser->VideoMimeTypeL();
       
   340 	if ( videoMimeType.Length() > 0 )
       
   341 		{
       
   342 		AppendUtf8DataFieldL( buffer, formatMimeType, KSconVideoVideoStreamMimetype );
       
   343 		}
       
   344 	
       
   345 	CleanupStack::PopAndDestroy( videoParser );
       
   346 	LOGGER_WRITE( "videoParser deleted" );
       
   347 	
       
   348 	
       
   349 	if ( buffer->Size() > 0 )
       
   350         {
       
   351         if ( aTask.iGetMetadataParams->iData )
       
   352             {
       
   353             delete aTask.iGetMetadataParams->iData;
       
   354             aTask.iGetMetadataParams->iData = NULL;
       
   355             }
       
   356         //Initialize the task data buffer
       
   357         aTask.iGetMetadataParams->iData = HBufC8::NewL( buffer->Size() );
       
   358         TPtr8 dataPtr = aTask.iGetMetadataParams->iData->Des();
       
   359         
       
   360         buffer->Read( 0, dataPtr, buffer->Size() );
       
   361         }
       
   362     CleanupStack::PopAndDestroy( buffer );
       
   363 	
       
   364 	
       
   365     TRACE_FUNC_EXIT;
       
   366 	}
       
   367 
       
   368 // -----------------------------------------------------------------------------
       
   369 // SConMetadata::AudioFieldId()
       
   370 // Map TMetaDataFieldId to KSconAudio field id
       
   371 // -----------------------------------------------------------------------------
       
   372 //
       
   373 TUint8 SConMetadata::AudioFieldId( const TMetaDataFieldId fieldId )
       
   374     {
       
   375     TUint8 ret(NULL);
       
   376     switch( fieldId )
       
   377         {
       
   378         case EMetaDataSongTitle :
       
   379             ret = KSconAudioTitle;
       
   380             break;
       
   381         case EMetaDataArtist :
       
   382             ret = KSconAudioArtist;
       
   383             break;
       
   384         case EMetaDataAlbum :
       
   385             ret = KSconAudioAlbum;
       
   386             break;
       
   387         case EMetaDataYear :
       
   388             ret = KSconAudioYear;
       
   389             break;
       
   390         case EMetaDataComment :
       
   391             ret = KSconAudioComment;
       
   392             break;
       
   393         case EMetaDataAlbumTrack :
       
   394             ret = KSconAudioAlbumTrack;
       
   395             break;
       
   396         case EMetaDataGenre :
       
   397             ret = KSconAudioGenre;
       
   398             break;
       
   399         case EMetaDataComposer :
       
   400             ret = KSconAudioComposer;
       
   401             break;
       
   402         case EMetaDataCopyright :
       
   403             ret = KSconAudioCopyright;
       
   404             break;
       
   405         case EMetaDataOriginalArtist :
       
   406             ret = KSconAudioOriginalArtist;
       
   407             break;
       
   408         case EMetaDataUrl :
       
   409             ret = KSconAudioUrl;
       
   410             break;
       
   411         case EMetaDataUserUrl :
       
   412             ret = KSconAudioUserUrl;
       
   413             break;
       
   414         case EMetaDataJpeg :
       
   415             ret = KSconAudioJpeg;
       
   416             break;
       
   417         case EMetaDataVendor :
       
   418             ret = KSconAudioVendor;
       
   419             break;
       
   420         case EMetaDataRating :
       
   421             ret = KSconAudioRating;
       
   422             break;
       
   423         case EMetaDataUniqueFileIdentifier :
       
   424             ret = KSconAudioUniqueFileIdentifier;
       
   425             break;
       
   426         case EMetaDataDuration :
       
   427             ret = KSconAudioDuration;
       
   428             break;
       
   429         case EMetaDataDate :
       
   430             ret = KSconAudioDate;
       
   431             break;
       
   432         case EMetaDataUnsyncLyrics:
       
   433             ret = KSconAudioUnsyncLyrics;
       
   434             break;
       
   435         case EMetaDataProtected:
       
   436             ret = KSconAudioProtected;
       
   437             break;
       
   438         default :
       
   439             LOGGER_WRITE( "SConMetadata::AudioFieldId : ERR field not defined!" );
       
   440             break;
       
   441         }
       
   442     return ret;
       
   443     }
       
   444 
       
   445 
       
   446 // -----------------------------------------------------------------------------
       
   447 // SConMetadata::GetExifTagL( CExifRead* aReader, const TUint8 aTagID )
       
   448 // This function is used to read exif data that might leave.
       
   449 // -----------------------------------------------------------------------------
       
   450 //
       
   451 HBufC8* SConMetadata::GetExifTagL( CExifRead* aReader, const TUint8 aTagID )
       
   452     {
       
   453     TRACE_FUNC_ENTRY;
       
   454     LOGGER_WRITE_1( " aTagID: 0x%02x", aTagID );
       
   455     HBufC8* tempBuf( NULL );
       
   456     
       
   457     switch( aTagID )
       
   458         {
       
   459         case KSconExifThumbnail:
       
   460             tempBuf = aReader->GetThumbnailL();
       
   461             break;
       
   462         case KSconExifDescription:
       
   463             tempBuf = aReader->GetImageDescriptionL();
       
   464             break;
       
   465         case KSconExifMake:
       
   466             tempBuf = aReader->GetMakeL();
       
   467             break;
       
   468         case KSconExifModel:
       
   469             tempBuf = aReader->GetModelL();
       
   470             break;
       
   471         case KSconExifDateTime:
       
   472             tempBuf = aReader->GetDateTimeL();
       
   473             break;
       
   474         case KSconExifSoftware:
       
   475             tempBuf = aReader->GetSoftwareL();
       
   476             break;
       
   477         case KSconExifCopyright:
       
   478             tempBuf = aReader->GetCopyrightL();
       
   479             break;
       
   480         case KSconExifIsoSpeedRatings:
       
   481             tempBuf = aReader->GetIsoSpeedRatingsL();
       
   482             if ( tempBuf )
       
   483                 {
       
   484                 TInt isoSpeed = ReadTUint32( tempBuf->Des() );
       
   485                 LOGGER_WRITE_1(" isoSpeed: %d", isoSpeed);
       
   486                 delete tempBuf;
       
   487                 
       
   488                 const TInt maxLength(5);
       
   489                 // no need to push on cleanupstack as leave cannot
       
   490                 // happen before returning tempBuf.
       
   491                 tempBuf = HBufC8::NewL(maxLength);
       
   492                 TPtr8 temp = tempBuf->Des();
       
   493                 temp.Num( isoSpeed );
       
   494                 }
       
   495             break;
       
   496         case KSconExifDateTimeOriginal:
       
   497             tempBuf = aReader->GetDateTimeOriginalL();
       
   498             break;
       
   499         case KSconExifDateTimeDigitized:
       
   500             tempBuf = aReader->GetDateTimeDigitizedL();
       
   501             break;
       
   502         case KSconExifMakerNote:
       
   503             // makernote contents are up to the manufacturer
       
   504             // not needed.
       
   505             User::Leave( KErrNotSupported );
       
   506             break;
       
   507         case KSconExifUserComment:
       
   508             tempBuf = aReader->GetUserCommentL();
       
   509             break;
       
   510         case KSconExifRelatedSoundFile:
       
   511             tempBuf = aReader->GetRelatedSoundFileL();
       
   512             break;
       
   513         default:
       
   514             User::Leave( KErrNotSupported );
       
   515         }
       
   516     TRACE_FUNC_EXIT;
       
   517     return tempBuf;
       
   518     }
       
   519 
       
   520 // -----------------------------------------------------------------------------
       
   521 // SConMetadata::ReadTUint32()
       
   522 // Convert 8-bit binary data to unsigned integer 
       
   523 // -----------------------------------------------------------------------------
       
   524 //
       
   525 TUint32 SConMetadata::ReadTUint32( const TDesC8& aData )
       
   526     {
       
   527     TRACE_FUNC_ENTRY;
       
   528     TUint32 result = 0;
       
   529     TUint8 c;
       
   530     
       
   531     for (TInt i=aData.Length()-1; i>=0; i--)
       
   532         {
       
   533         c = aData[i];
       
   534         result = (result << 8) | c;
       
   535         }
       
   536     
       
   537     LOGGER_WRITE_1( "SConMetadata::ReadTUint32() : returned %d ", result );
       
   538     return result;
       
   539     }
       
   540 
       
   541 // -----------------------------------------------------------------------------
       
   542 // SConMetadata::GetFileDataLC()
       
   543 // Read data from file
       
   544 // -----------------------------------------------------------------------------
       
   545 //
       
   546 HBufC8* SConMetadata::GetFileDataLC( const TDesC& aFilename, RFs& aFs )
       
   547 	{
       
   548 	TRACE_FUNC_ENTRY;
       
   549     RFile file;
       
   550     
       
   551     User::LeaveIfError( file.Open( aFs, aFilename,
       
   552         EFileRead | EFileShareReadersOnly ) );
       
   553     CleanupClosePushL( file );
       
   554     
       
   555     LOGGER_WRITE( "SConMetadata::GetFileDataLC() : file opened" );
       
   556     
       
   557     TInt dataSize(0);
       
   558     ContentAccess::CContent* content;
       
   559     content = ContentAccess::CContent::NewLC( file );
       
   560     ContentAccess::CData* data = content->OpenContentLC( ContentAccess::EPeek );
       
   561     data->DataSizeL(dataSize);
       
   562     
       
   563     LOGGER_WRITE( "SConMetadata::GetFileDataLC() : content opened" );
       
   564     // Read 64k from the beginning of the file
       
   565     if ( dataSize > KJpegLoadBufferSize )
       
   566         {
       
   567         dataSize = KJpegLoadBufferSize;
       
   568         }
       
   569     HBufC8* readBuffer = HBufC8::NewLC( dataSize );
       
   570     TPtr8 readPtr = readBuffer->Des();
       
   571     User::LeaveIfError( data->Read( readPtr, dataSize ) );
       
   572     
       
   573     LOGGER_WRITE( "SConMetadata::GetFileDataLC() : data readed" );
       
   574     CleanupStack::Pop( readBuffer );
       
   575     CleanupStack::PopAndDestroy( data );
       
   576     CleanupStack::PopAndDestroy( content );
       
   577     CleanupStack::PopAndDestroy( &file );
       
   578     
       
   579     CleanupStack::PushL( readBuffer );
       
   580     TRACE_FUNC_EXIT;
       
   581     return readBuffer;
       
   582 	}
       
   583 
       
   584 // -----------------------------------------------------------------------------
       
   585 // SConMetadata::ReadExifDataL()
       
   586 // Read Exif data
       
   587 // -----------------------------------------------------------------------------
       
   588 //
       
   589 void SConMetadata::ReadExifDataL( CSConTask& aTask, RFs& aFs )
       
   590     {
       
   591     TRACE_FUNC_ENTRY;
       
   592     
       
   593     // read data from file
       
   594     HBufC8* jpegReadBuffer = GetFileDataLC( aTask.iGetMetadataParams->iFilename, aFs );
       
   595     
       
   596     CExifRead* reader = CExifRead::NewL(
       
   597         *jpegReadBuffer, CExifRead::ENoJpeg | CExifRead::ENoTagChecking );
       
   598     
       
   599     LOGGER_WRITE( "SConMetadata::ReadExifDataL() : reader created" );
       
   600     CleanupStack::PopAndDestroy( jpegReadBuffer );
       
   601     CleanupStack::PushL( reader );
       
   602     
       
   603 
       
   604     CBufFlat* buffer = CBufFlat::NewL( KBufferSize );
       
   605     CleanupStack::PushL( buffer );
       
   606     buffer->Reset();
       
   607     
       
   608     
       
   609     TInt offset(0);
       
   610     // header id (1 byte) + head.version (1 byte) = 2 bytes
       
   611     
       
   612     buffer->ExpandL( offset, 2 );
       
   613     
       
   614     // header id
       
   615     TUint8 value( KSconMetadataHeaderExif );
       
   616     buffer->Write( offset, TPtrC8(&value, 1) );
       
   617     offset++;
       
   618     
       
   619     // header version
       
   620     value = KSconMetadataHeaderVersion;
       
   621     buffer->Write( offset, TPtrC8(&value, 1) );
       
   622     offset++;
       
   623     
       
   624     
       
   625     HBufC8* tempBuf(NULL);
       
   626     
       
   627     TInt err;
       
   628     
       
   629     for ( TInt tagID = KSconExifThumbnail; tagID < KSconExifGpsVersion; tagID++ )
       
   630         {
       
   631         // GetExifTagL function is used only to tags that leaves if data is not found
       
   632         TRAP( err, tempBuf = GetExifTagL( reader, tagID ) );
       
   633         if ( !err )
       
   634             {
       
   635             LOGGER_WRITE("write to buffer");
       
   636             CleanupStack::PushL( tempBuf );
       
   637             AppendByteDataFieldL( buffer, tempBuf->Des(), tagID );
       
   638             CleanupStack::PopAndDestroy( tempBuf );
       
   639             tempBuf = NULL;
       
   640             }
       
   641         else
       
   642             {
       
   643             LOGGER_WRITE_1( "GetExifTagL Leave code %d", err );
       
   644             }
       
   645         }
       
   646     
       
   647     
       
   648     TUint16 value16a;
       
   649     TUint32 value32a;
       
   650     TUint32 value32b;
       
   651     TInt32 val32a;
       
   652     TInt32 val32b;
       
   653     
       
   654     // Orientation
       
   655     err = reader->GetOrientation( value16a );
       
   656     if ( !err )
       
   657         {
       
   658         AppendTUintDataFieldL( buffer, value16a, KSconExifOrientation );
       
   659         }
       
   660     
       
   661     // XResolution
       
   662     err = reader->GetXResolution( value32a, value32b );
       
   663     if ( !err )
       
   664         {
       
   665         AppendTUintDataFieldL( buffer, value32a, KSconExifXResolution1 );
       
   666         AppendTUintDataFieldL( buffer, value32b, KSconExifXResolution2 );
       
   667         }
       
   668     
       
   669     // YResolution
       
   670     err = reader->GetYResolution( value32a, value32b );
       
   671     if ( !err )
       
   672         {
       
   673         AppendTUintDataFieldL( buffer, value32a, KSconExifYResolution1 );
       
   674         AppendTUintDataFieldL( buffer, value32b, KSconExifYResolution2 );
       
   675         }
       
   676     
       
   677     // ResolutionUnit
       
   678     err = reader->GetResolutionUnit( value16a );
       
   679     if ( !err )
       
   680         {
       
   681         AppendTUintDataFieldL( buffer, value16a, KSconExifResolutionUnit );
       
   682         }
       
   683     
       
   684     // YCbCrPositioning
       
   685     err = reader->GetYCbCrPositioning( value16a );
       
   686     if ( !err )
       
   687         {
       
   688         AppendTUintDataFieldL( buffer, value16a, KSconExifYCbCrPositioning );
       
   689         }
       
   690     
       
   691     // YCbCrPositioning
       
   692     err = reader->GetYCbCrPositioning( value16a );
       
   693     if ( !err )
       
   694         {
       
   695         AppendTUintDataFieldL( buffer, value16a, KSconExifYCbCrPositioning );
       
   696         }
       
   697     
       
   698     
       
   699     // ExposureTime
       
   700     err = reader->GetExposureTime( value32a, value32b );
       
   701     if ( !err )
       
   702         {
       
   703         AppendTUintDataFieldL( buffer, value32a, KSconExifExposureTime1 );
       
   704         AppendTUintDataFieldL( buffer, value32b, KSconExifExposureTime2 );
       
   705         }
       
   706     
       
   707     // ComponentsConfiguration
       
   708     TUint8 value8a;
       
   709     TUint8 value8b;
       
   710     TUint8 value8c;
       
   711     TUint8 value8d;
       
   712     err = reader->GetComponentsConfiguration( value8a, value8b, value8c, value8d );
       
   713     if ( !err )
       
   714         {
       
   715         TInt offset;
       
   716         offset = buffer->Size();
       
   717         
       
   718         // field ID (1 byte) + field lenght (4 bytes) + field data (4bytes) = 9 bytes
       
   719         buffer->ExpandL( offset, 9 );
       
   720         
       
   721         // field id (one byte)
       
   722         TUint8 fieldId( KSconExifComponentsConfiguration );
       
   723         buffer->Write( offset, TPtrC8( &fieldId, 1 ) );
       
   724         offset++;
       
   725         
       
   726         // field lenght
       
   727         WriteTUint32( buffer, offset, 4);
       
   728         offset += 4;
       
   729         
       
   730         buffer->Write( offset, TPtrC8(&value8a, 1) );
       
   731         offset++;
       
   732         buffer->Write( offset, TPtrC8(&value8b, 1) );
       
   733         offset++;
       
   734         buffer->Write( offset, TPtrC8(&value8c, 1) );
       
   735         offset++;
       
   736         buffer->Write( offset, TPtrC8(&value8d, 1) );
       
   737         offset++;
       
   738         }
       
   739     
       
   740     // Flash
       
   741     err = reader->GetFlash( value16a );
       
   742     if ( !err )
       
   743         {
       
   744         AppendTUintDataFieldL( buffer, value16a, KSconExifFlash );
       
   745         }
       
   746     
       
   747     // ColorSpace
       
   748     err = reader->GetColorSpace( value16a );
       
   749     if ( !err )
       
   750         {
       
   751         AppendTUintDataFieldL( buffer, value16a, KSconExifColorSpace );
       
   752         }
       
   753     
       
   754     // PixelXDimension
       
   755     err = reader->GetPixelXDimension( value32a );
       
   756     if ( !err )
       
   757         {
       
   758         AppendTUintDataFieldL( buffer, value32a, KSconExifPixelXDimension );
       
   759         }
       
   760     
       
   761     // PixelYDimension
       
   762     err = reader->GetPixelYDimension( value32a );
       
   763     if ( !err )
       
   764         {
       
   765         AppendTUintDataFieldL( buffer, value32a, KSconExifPixelYDimension );
       
   766         }
       
   767     
       
   768     // ExposureMode
       
   769     err = reader->GetExposureMode( value16a );
       
   770     if ( !err )
       
   771         {
       
   772         AppendTUintDataFieldL( buffer, value16a, KSconExifExposureMode );
       
   773         }
       
   774     
       
   775     // WhiteBalance
       
   776     err = reader->GetWhiteBalance( value16a );
       
   777     if ( !err )
       
   778         {
       
   779         AppendTUintDataFieldL( buffer, value16a, KSconExifWhiteBalance );
       
   780         }
       
   781     
       
   782     // SceneCaptureType
       
   783     err = reader->GetSceneCaptureType( value16a );
       
   784     if ( !err )
       
   785         {
       
   786         AppendTUintDataFieldL( buffer, value16a, KSconExifSceneCaptureType );
       
   787         }
       
   788     
       
   789     // ExposureProgram
       
   790     err = reader->GetExposureProgram( value16a );
       
   791     if ( !err )
       
   792         {
       
   793         AppendTUintDataFieldL( buffer, value16a, KSconExifExposureProgram );
       
   794         }
       
   795     
       
   796     // GetApertureValue
       
   797     err = reader->GetApertureValue( value32a, value32b );
       
   798     if ( !err )
       
   799         {
       
   800         AppendTUintDataFieldL( buffer, value32a, KSconExifApertureValue1 );
       
   801         AppendTUintDataFieldL( buffer, value32b, KSconExifApertureValue2 );
       
   802         }
       
   803     
       
   804     // GetExposureBiasValue
       
   805     err = reader->GetExposureBiasValue( val32a, val32b );
       
   806     if ( !err )
       
   807         {
       
   808         value32a = val32a;
       
   809         value32b = val32b;
       
   810         AppendTUintDataFieldL( buffer, value32a, KSconExifExposureBiasValue1 );
       
   811         AppendTUintDataFieldL( buffer, value32b, KSconExifExposureBiasValue2 );
       
   812         }
       
   813     
       
   814     // GetMeteringMode
       
   815     err = reader->GetMeteringMode( value16a );
       
   816     if ( !err )
       
   817         {
       
   818         AppendTUintDataFieldL( buffer, value16a, KSconExifMeteringMode );
       
   819         }
       
   820     
       
   821     // GetLightSource
       
   822     err = reader->GetLightSource( value16a );
       
   823     if ( !err )
       
   824         {
       
   825         AppendTUintDataFieldL( buffer, value16a, KSconExifLightSource );
       
   826         }
       
   827     
       
   828     // GetFileSource
       
   829     TInt8 val8;
       
   830     err = reader->GetFileSource( val8 );
       
   831     if ( !err )
       
   832         {
       
   833         value8a = val8;
       
   834         AppendTUintDataFieldL( buffer, value8a, KSconExifFileSource );
       
   835         }
       
   836     
       
   837     // GetDigitalZoomRatio
       
   838     err = reader->GetDigitalZoomRatio( value32a, value32b );
       
   839     if ( !err )
       
   840         {
       
   841         AppendTUintDataFieldL( buffer, value32a, KSconExifDigitalZoomRatio1 );
       
   842         AppendTUintDataFieldL( buffer, value32b, KSconExifDigitalZoomRatio2 );
       
   843         }
       
   844     
       
   845     // GetContrast
       
   846     err = reader->GetContrast( value16a );
       
   847     if ( !err )
       
   848         {
       
   849         AppendTUintDataFieldL( buffer, value16a, KSconExifContrast );
       
   850         }
       
   851     
       
   852     // GetSaturation
       
   853     err = reader->GetSaturation( value16a );
       
   854     if ( !err )
       
   855         {
       
   856         AppendTUintDataFieldL( buffer, value16a, KSconExifSaturation );
       
   857         }
       
   858     
       
   859     // GetSharpness
       
   860     err = reader->GetSharpness( value16a );
       
   861     if ( !err )
       
   862         {
       
   863         AppendTUintDataFieldL( buffer, value16a, KSconExifSharpness );
       
   864         }
       
   865     
       
   866     // GetExifVersion
       
   867     err = reader->GetExifVersion( value32a );
       
   868     if ( !err )
       
   869         {
       
   870         AppendTUintDataFieldL( buffer, value32a, KSconExifExifVersion );
       
   871         }
       
   872     
       
   873     // GetFlashPixVersion
       
   874     err = reader->GetFlashPixVersion( value32a );
       
   875     if ( !err )
       
   876         {
       
   877         AppendTUintDataFieldL( buffer, value32a, KSconExifFlashPixVersion );
       
   878         }
       
   879     
       
   880     // GetThumbnailXResolution
       
   881     err = reader->GetThumbnailXResolution( value32a, value32b );
       
   882     if ( !err )
       
   883         {
       
   884         AppendTUintDataFieldL( buffer, value32a, KSconExifThumbXResolution1 );
       
   885         AppendTUintDataFieldL( buffer, value32b, KSconExifThumbXResolution2 );
       
   886         }
       
   887     
       
   888     // GetThumbnailYResolution
       
   889     err = reader->GetThumbnailYResolution( value32a, value32b );
       
   890     if ( !err )
       
   891         {
       
   892         AppendTUintDataFieldL( buffer, value32a, KSconExifThumbYResolution1 );
       
   893         AppendTUintDataFieldL( buffer, value32b, KSconExifThumbYResolution2 );
       
   894         }
       
   895     
       
   896     // GetThumbnailResolutionUnit
       
   897     err = reader->GetThumbnailResolutionUnit( value16a );
       
   898     if ( !err )
       
   899         {
       
   900         AppendTUintDataFieldL( buffer, value16a, KSconExifThumbResolutionUnit );
       
   901         }
       
   902     
       
   903     // GetThumbnailCompression
       
   904     err = reader->GetThumbnailCompression( value16a );
       
   905     if ( !err )
       
   906         {
       
   907         AppendTUintDataFieldL( buffer, value16a, KSconExifThumbCompression );
       
   908         }
       
   909     
       
   910     // GetJpegInterchangeFormat
       
   911     err = reader->GetJpegInterchangeFormat( value32a );
       
   912     if ( !err )
       
   913         {
       
   914         AppendTUintDataFieldL( buffer, value32a, KSconExifThumbJpegInterchangeFormat );
       
   915         }
       
   916     
       
   917     // GetJpegInterchangeFormatLength
       
   918     err = reader->GetJpegInterchangeFormatLength( value32a );
       
   919     if ( !err )
       
   920         {
       
   921         AppendTUintDataFieldL( buffer, value32a, KSconExifThumbJpegInterchangeFormatLength );
       
   922         }
       
   923     
       
   924     // GetShutterSpeedValue
       
   925     err = reader->GetShutterSpeedValue( val32a, val32b );
       
   926     if ( !err )
       
   927         {
       
   928         value32a = val32a;
       
   929         value32b = val32b;
       
   930         AppendTUintDataFieldL( buffer, value32a, KSconExifShutterSpeedValue1 );
       
   931         AppendTUintDataFieldL( buffer, value32b, KSconExifShutterSpeedValue2 );
       
   932         }
       
   933     
       
   934     // GetBrightnessValue
       
   935     err = reader->GetBrightnessValue( val32a, val32b );
       
   936     if ( !err )
       
   937         {
       
   938         value32a = val32a;
       
   939         value32b = val32b;
       
   940         AppendTUintDataFieldL( buffer, value32a, KSconExifBrightnessValue1 );
       
   941         AppendTUintDataFieldL( buffer, value32b, KSconExifBrightnessValue2 );
       
   942         }
       
   943     
       
   944     // GetCustomRendered
       
   945     err = reader->GetCustomRendered( value16a );
       
   946     if ( !err )
       
   947         {
       
   948         AppendTUintDataFieldL( buffer, value16a, KSconExifCustomRendered );
       
   949         }
       
   950     
       
   951     // GetGainControl
       
   952     err = reader->GetGainControl( value16a );
       
   953     if ( !err )
       
   954         {
       
   955         AppendTUintDataFieldL( buffer, value16a, KSconExifGainControl );
       
   956         }
       
   957     
       
   958     // GetGpsVersion
       
   959     err = reader->GetGpsVersion( value32a );
       
   960     if ( !err )
       
   961         {
       
   962         AppendTUintDataFieldL( buffer, value32a, KSconExifGpsVersion );
       
   963         }
       
   964     
       
   965     // Get GPS coordinates
       
   966     const TUint KCoordinatesMaxLength = 50;
       
   967     TBuf<KCoordinatesMaxLength> gpsInfo;
       
   968     // Latidute
       
   969     err = GetExifGPSLatitudeL( *reader, gpsInfo );
       
   970     if ( !err )
       
   971     	{
       
   972     	AppendUtf8DataFieldL( buffer, gpsInfo ,KSconExifGPSLatitude );
       
   973     	}
       
   974     
       
   975     // Longitude
       
   976     err = GetExifGPSLongitudeL( *reader, gpsInfo );
       
   977     if ( !err )
       
   978     	{
       
   979     	AppendUtf8DataFieldL( buffer, gpsInfo ,KSconExifGPSLongitude );
       
   980     	}
       
   981     
       
   982     // Altidute
       
   983     err = GetExifGPSAltiduteL( *reader, gpsInfo );
       
   984     if ( !err )
       
   985     	{
       
   986     	AppendUtf8DataFieldL( buffer, gpsInfo ,KSconExifGPSAltitude );
       
   987     	}
       
   988     
       
   989     LOGGER_WRITE( "SConMetadata::ReadExifDataL() : All data collected" );
       
   990     
       
   991     if ( buffer->Size() > 0 )
       
   992         {
       
   993         LOGGER_WRITE_1( "SConMetadata::ReadExifDataL() : buffer->Size() %d", buffer->Size() );
       
   994         if ( aTask.iGetMetadataParams->iData )
       
   995             {
       
   996             delete aTask.iGetMetadataParams->iData;
       
   997             aTask.iGetMetadataParams->iData = NULL;
       
   998             }
       
   999         //Initialize the task data buffer
       
  1000         aTask.iGetMetadataParams->iData = HBufC8::NewL( buffer->Size() );
       
  1001         TPtr8 dataPtr = aTask.iGetMetadataParams->iData->Des();
       
  1002         
       
  1003         buffer->Read( 0, dataPtr, buffer->Size() );
       
  1004         LOGGER_WRITE_1( "SConMetadata::ReadExifDataL() dataPtr len: %d", dataPtr.Length());
       
  1005         }
       
  1006     CleanupStack::PopAndDestroy( buffer );
       
  1007     
       
  1008     LOGGER_WRITE( "SConMetadata::ReadExifDataL() : task updated" );
       
  1009     
       
  1010     CleanupStack::PopAndDestroy( reader );
       
  1011     TRACE_FUNC_EXIT;
       
  1012     }
       
  1013 
       
  1014 // -----------------------------------------------------------------------------
       
  1015 // void SConMetadata::ConvertRationalTag( const CExifTag& aTag, TDes& aPosDegrees )
       
  1016 // parses degrees, minutes and seconds from CExifTag and converts it to string format
       
  1017 // -----------------------------------------------------------------------------
       
  1018 //
       
  1019 TInt SConMetadata::ConvertRationalTag( const CExifTag& aTag, TDes& aPosDegrees )
       
  1020 	{
       
  1021 	TRACE_FUNC_ENTRY;
       
  1022 	TInt numer(0);
       
  1023 	TInt denom(0);
       
  1024 	TReal64 degrees(0);
       
  1025 	TReal64 minutes(0);
       
  1026 	TReal64 seconds(0);
       
  1027 	
       
  1028 	const TUint8* ratData = aTag.Data().Ptr();
       
  1029 	for ( TUint y=0; y < aTag.TagInfo().iDataCount; y++ )
       
  1030 		{
       
  1031 		numer = 0;
       
  1032 		denom = 0;
       
  1033 		Mem::Copy(&numer, ratData + ((y * 2) * sizeof(numer)), sizeof(numer));
       
  1034 		Mem::Copy(&denom, ratData + (((y * 2) + 1) * sizeof(numer)), sizeof(denom));	
       
  1035 		if (denom != 0)
       
  1036 		    {
       
  1037             if ( y == 0 )// degrees
       
  1038                 {
       
  1039                 degrees = numer/denom;
       
  1040                 }
       
  1041             else if ( y == 1 )// minutes
       
  1042                 {
       
  1043                 minutes = numer/denom;
       
  1044                 }
       
  1045             else if ( y == 2 )// seconds
       
  1046                 {
       
  1047                 seconds = numer/denom;
       
  1048                 }
       
  1049 		    }
       
  1050 		}
       
  1051 	_LIT(KFormat, "%.0f°%.0f'%.2f\"" );
       
  1052 	aPosDegrees.Format( KFormat, degrees, minutes, seconds );
       
  1053 	TRACE_FUNC_EXIT;
       
  1054 	return KErrNone;
       
  1055 	}
       
  1056 
       
  1057 // -----------------------------------------------------------------------------
       
  1058 // void SConMetadata::GetExifGPSLatitudeL( CExifRead& aExifRead, TDes& aLatitude )
       
  1059 // Read latidute from ExifReader 
       
  1060 // -----------------------------------------------------------------------------
       
  1061 //
       
  1062 TInt SConMetadata::GetExifGPSLatitudeL( CExifRead& aExifRead, TDes& aLatitude )
       
  1063 	{
       
  1064 	TRACE_FUNC_ENTRY;
       
  1065 	TInt ret(KErrNone);
       
  1066 	if ( aExifRead.TagExists( KGPSLatitudeRef, EIfdGps )
       
  1067 		&& aExifRead.TagExists( KGPSLatitude, EIfdGps) )
       
  1068 		{
       
  1069 		// get latidute
       
  1070 		const CExifTag* lat = aExifRead.GetTagL( 
       
  1071 				EIfdGps, 
       
  1072 				KGPSLatitude );
       
  1073 		User::LeaveIfError( ConvertRationalTag( *lat, aLatitude ) );
       
  1074 		if ( aLatitude.Length()+2 > aLatitude.MaxLength() )
       
  1075 			{
       
  1076 			User::Leave( KErrTooBig );
       
  1077 			}
       
  1078 		
       
  1079 		// south or north
       
  1080 		const CExifTag* latRef = aExifRead.GetTagL( 
       
  1081 				EIfdGps, 
       
  1082 				KGPSLatitudeRef );
       
  1083 		_LIT8( KNorthTagDef8, "N" );
       
  1084 		_LIT( KNorth, "N " );
       
  1085 		_LIT( KSouth, "S " );
       
  1086 		if ( latRef->Data().Find( KNorthTagDef8 ) != KErrNotFound )
       
  1087 			{
       
  1088 			aLatitude.Insert( 0, KNorth );
       
  1089 			}
       
  1090 		else
       
  1091 			{
       
  1092 			aLatitude.Insert( 0, KSouth );
       
  1093 			}
       
  1094 		}
       
  1095 	else
       
  1096 		{
       
  1097 		ret=KErrNotFound;
       
  1098 		}
       
  1099 	TRACE_FUNC_EXIT;
       
  1100 	return ret;
       
  1101 	}
       
  1102 
       
  1103 // -----------------------------------------------------------------------------
       
  1104 // void SConMetadata::GetExifGPSLongitudeL( CExifRead& aExifRead, TDes& aLongitude )
       
  1105 // Read longitude from ExifReader 
       
  1106 // -----------------------------------------------------------------------------
       
  1107 //
       
  1108 TInt SConMetadata::GetExifGPSLongitudeL( CExifRead& aExifRead, TDes& aLongitude )
       
  1109 	{
       
  1110 	TRACE_FUNC_ENTRY;
       
  1111 	TInt ret(KErrNone);
       
  1112 	if ( aExifRead.TagExists( KGPSLongitudeRef, EIfdGps )
       
  1113 		&& aExifRead.TagExists( KGPSLongitude, EIfdGps) )
       
  1114 		{
       
  1115 		// get longitude
       
  1116 		const CExifTag* lon = aExifRead.GetTagL( 
       
  1117 				EIfdGps, 
       
  1118 				KGPSLongitude );
       
  1119 		User::LeaveIfError( ConvertRationalTag( *lon, aLongitude ) );
       
  1120 		if ( aLongitude.Length()+2 > aLongitude.MaxLength() )
       
  1121 			{
       
  1122 			User::Leave( KErrTooBig );
       
  1123 			}
       
  1124 		
       
  1125 		// east or west
       
  1126 		const CExifTag* lonref = aExifRead.GetTagL( 
       
  1127 				EIfdGps, 
       
  1128 				KGPSLongitudeRef );
       
  1129 		_LIT8( KEastTagDef8, "E" );
       
  1130 		_LIT( KEast, "E " );
       
  1131 		_LIT( KWest, "W " );
       
  1132 		if ( lonref->Data().Find( KEastTagDef8 ) != KErrNotFound )
       
  1133 			{
       
  1134 			aLongitude.Insert( 0, KEast );
       
  1135 			}
       
  1136 		else
       
  1137 			{
       
  1138 			aLongitude.Insert( 0, KWest );
       
  1139 			}
       
  1140 		}
       
  1141 	else
       
  1142 		{
       
  1143 		ret = KErrNotFound;
       
  1144 		}
       
  1145 	TRACE_FUNC_EXIT;
       
  1146 	return ret;
       
  1147 	}
       
  1148 
       
  1149 // -----------------------------------------------------------------------------
       
  1150 // void SConMetadata::GetExifGPSAltiduteL( CExifRead& aExifRead, TDes& aAltidute )
       
  1151 // Read altidute from ExifReader 
       
  1152 // -----------------------------------------------------------------------------
       
  1153 //
       
  1154 TInt SConMetadata::GetExifGPSAltiduteL( CExifRead& aExifRead, TDes& aAltidute )
       
  1155 	{
       
  1156 	TRACE_FUNC_ENTRY;
       
  1157 	
       
  1158 	TInt ret(KErrNone);
       
  1159 	if ( aExifRead.TagExists( KGPSAltitudeRef, EIfdGps )
       
  1160 		&& aExifRead.TagExists( KGPSAltitude, EIfdGps) )
       
  1161 		{
       
  1162 		if ( aAltidute.MaxLength() < 5 )
       
  1163 			{
       
  1164 			User::Leave( KErrTooBig );
       
  1165 			}
       
  1166 		
       
  1167 		// get altidute
       
  1168 		const CExifTag* alt = aExifRead.GetTagL( 
       
  1169 				EIfdGps, 
       
  1170 				KGPSAltitude );
       
  1171 		const TUint8* ratData = alt->Data().Ptr();
       
  1172 		
       
  1173 		TInt numer;
       
  1174 		TInt denom;
       
  1175 		Mem::Copy(&numer, ratData , sizeof(numer));
       
  1176 		Mem::Copy(&denom, ratData + (sizeof(numer)), sizeof(denom));
       
  1177 		
       
  1178 		TReal32 tmp = numer / denom;
       
  1179 		
       
  1180 		// sea level
       
  1181 		const CExifTag* altref = aExifRead.GetTagL( 
       
  1182 				EIfdGps, 
       
  1183 				KGPSAltitudeRef );
       
  1184 		_LIT8( KAltSealevelDef8, "1" );
       
  1185 		if ( altref->Data().Find( KAltSealevelDef8 ) != KErrNotFound )
       
  1186 			{
       
  1187 			// seaLevelReference -> negative value
       
  1188 			tmp *= -1;
       
  1189 			}
       
  1190 		TRealFormat format;
       
  1191 		format.iType = KRealFormatFixed;
       
  1192 		format.iPlaces=1;
       
  1193 		User::LeaveIfError( aAltidute.Num( tmp, format ) );
       
  1194 		}
       
  1195 	else
       
  1196 		{
       
  1197 		ret = KErrNotFound;
       
  1198 		}
       
  1199 	TRACE_FUNC_EXIT;
       
  1200 	return ret;
       
  1201 	}
       
  1202 
       
  1203 // -----------------------------------------------------------------------------
       
  1204 // void SConMetadata::AppendUtf8DataFieldL( CBufFlat* aBuffer,
       
  1205 //     const TPtrC aAppendData, const TUint8 aFieldId )
       
  1206 // Write 8bit field id value, data length (32bit) and UTF8 data to buffer 
       
  1207 // -----------------------------------------------------------------------------
       
  1208 //
       
  1209 void SConMetadata::AppendUtf8DataFieldL( CBufFlat* aBuffer,
       
  1210     const TPtrC aAppendData, const TUint8 aFieldId )
       
  1211     {
       
  1212     TRACE_FUNC_ENTRY;
       
  1213     LOGGER_WRITE_1( "aFieldId: 0x%02x", aFieldId);
       
  1214     HBufC8* tempBuf = HBufC8::NewLC( aAppendData.Size() );
       
  1215     TPtr8 temp = tempBuf->Des();
       
  1216     
       
  1217     CnvUtfConverter::ConvertFromUnicodeToUtf8( temp, aAppendData );
       
  1218     LOGGER_WRITE_1( "lenght: %d", temp.Length() );
       
  1219     
       
  1220     if ( temp.Length() > KFieldMaxLength )
       
  1221         {
       
  1222         LOGGER_WRITE("Data length is too big, field skipped");
       
  1223         CleanupStack::PopAndDestroy( tempBuf );
       
  1224         return;
       
  1225         }
       
  1226     
       
  1227     TInt offset;
       
  1228     offset = aBuffer->Size();
       
  1229     // field ID (1 byte) + field lenght (4 bytes) + field data
       
  1230     aBuffer->ExpandL( offset, temp.Length() + 5 );
       
  1231     
       
  1232     // field id (one byte)
       
  1233     aBuffer->Write( offset, TPtrC8(&aFieldId, 1) );
       
  1234     offset++;
       
  1235     
       
  1236     WriteTUint32( aBuffer, offset, temp.Length());
       
  1237     offset += 4;
       
  1238     
       
  1239     // field data
       
  1240     aBuffer->Write( offset, temp, temp.Length() );
       
  1241     offset += temp.Length();
       
  1242     
       
  1243     CleanupStack::PopAndDestroy( tempBuf );
       
  1244     
       
  1245     TRACE_FUNC_EXIT;
       
  1246     }
       
  1247 
       
  1248 // -----------------------------------------------------------------------------
       
  1249 // void SConMetadata::AppendByteDataFieldL( CBufFlat* aBuffer,
       
  1250 //     const TPtrC8 aAppendData, const TUint8 aFieldId )
       
  1251 // Write 8bit field id value, data length (32bit) and n*8bit data to buffer 
       
  1252 // -----------------------------------------------------------------------------
       
  1253 //
       
  1254 void SConMetadata::AppendByteDataFieldL( CBufFlat* aBuffer,
       
  1255     const TPtrC8 aAppendData, const TUint8 aFieldId )
       
  1256     {
       
  1257     TRACE_FUNC_ENTRY;
       
  1258     LOGGER_WRITE_1( "aFieldId: 0x%02x", aFieldId);
       
  1259     LOGGER_WRITE_1( "lenght: %d", aAppendData.Length() );
       
  1260     if ( aAppendData.Length() > KFieldMaxLength )
       
  1261         {
       
  1262         LOGGER_WRITE("Data length is too big, field skipped");
       
  1263         return;
       
  1264         }
       
  1265     TInt offset;
       
  1266     offset = aBuffer->Size();
       
  1267     
       
  1268     // field id (1) + field len (4) + datalen = 5 + datalen
       
  1269     aBuffer->ExpandL( offset, aAppendData.Length() + 5 );
       
  1270     
       
  1271     // field id (one byte)
       
  1272     aBuffer->Write( offset, TPtrC8(&aFieldId, 1) );
       
  1273     offset++;
       
  1274     
       
  1275     // field data length (32bit unsigned integer, two byte)
       
  1276     WriteTUint32( aBuffer, offset, aAppendData.Length() );
       
  1277     offset += 4;
       
  1278     
       
  1279     // field data
       
  1280     aBuffer->Write( offset, aAppendData );
       
  1281     offset += aAppendData.Length();
       
  1282     
       
  1283     TRACE_FUNC_EXIT;
       
  1284     }
       
  1285 
       
  1286 // -----------------------------------------------------------------------------
       
  1287 // void SConMetadata::AppendTUintDataFieldL( CBufFlat* aBuffer,
       
  1288 //     const TUint32 aValue, const TUint8 aFieldId )
       
  1289 // Write 8bit field id value, data length (16bit) and n*8bit data to buffer 
       
  1290 // -----------------------------------------------------------------------------
       
  1291 //
       
  1292 void SConMetadata::AppendTUintDataFieldL( CBufFlat* aBuffer,
       
  1293     TUint32 aValue, const TUint8 aFieldId )
       
  1294     {
       
  1295     TRACE_FUNC_ENTRY;
       
  1296     LOGGER_WRITE_1( "aFieldId: 0x%02x", aFieldId);
       
  1297     LOGGER_WRITE_1( "aValue dec: %u", aValue);
       
  1298     TInt offset;
       
  1299     offset = aBuffer->Size();
       
  1300     TInt dataLen(1);
       
  1301     TUint8 temp[4];
       
  1302     TInt i(0);
       
  1303     
       
  1304     temp[i] = aValue & 0xFF;
       
  1305     
       
  1306     aValue >>= 8;
       
  1307     while( aValue > 0 )
       
  1308         {
       
  1309         i++;
       
  1310         temp[i] = aValue & 0xFF;
       
  1311         aValue >>= 8;
       
  1312         dataLen++;
       
  1313         }
       
  1314     // field id (1) + field len (4) + datalen = 5 + datalen
       
  1315     aBuffer->ExpandL( offset, 5 + dataLen );
       
  1316     
       
  1317     // field id (one byte)
       
  1318     aBuffer->Write( offset, TPtrC8(&aFieldId, 1) );
       
  1319     offset++;
       
  1320     
       
  1321     // field data length (32bit unsigned integer, two byte)
       
  1322     WriteTUint32( aBuffer, offset, dataLen );
       
  1323     offset += 4;
       
  1324     
       
  1325     // field data
       
  1326     for( TInt i = dataLen-1; i>=0; i-- )
       
  1327         {
       
  1328         aBuffer->Write( offset, TPtrC8(&temp[i], 1) );
       
  1329         offset++;
       
  1330         }
       
  1331     
       
  1332     TRACE_FUNC_EXIT;
       
  1333     }
       
  1334 
       
  1335 // -----------------------------------------------------------------------------
       
  1336 // void SConMetadata::WriteTUint32( CBufFlat* aBuffer, TInt offset, TUint32 aValue )
       
  1337 // Write 32bit unsigned integer value to buffer.
       
  1338 // -----------------------------------------------------------------------------
       
  1339 //
       
  1340 void SConMetadata::WriteTUint32( CBufFlat* aBuffer, TInt offset, TUint32 aValue )
       
  1341     {
       
  1342     TUint8 temp[4];
       
  1343     TInt i(0);
       
  1344     
       
  1345     temp[i] = aValue & 0xFF;
       
  1346     
       
  1347     aValue >>= 8;
       
  1348     for ( TInt i=1; i<4; i++ )
       
  1349         {
       
  1350         temp[i] = aValue & 0xFF;
       
  1351         aValue >>= 8;
       
  1352         }
       
  1353     
       
  1354     // high to low
       
  1355     for ( TInt i=3; i>=0; i-- )
       
  1356         {
       
  1357         aBuffer->Write( offset, TPtrC8(&temp[i], 1) );
       
  1358         offset++;
       
  1359         }
       
  1360     }
       
  1361 
       
  1362 // End of file