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