imagingmodules/exiflib/src/ExifCore.cpp
changeset 0 469c91dae73b
equal deleted inserted replaced
-1:000000000000 0:469c91dae73b
       
     1 /*
       
     2 * Copyright (c) 2003, 2004 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:  The core service class for handling Exif v2.2 File Format.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "ExifIfd.h"
       
    21 #include "ExifCore.h"
       
    22 #include "ExifReadImpl.h"
       
    23 
       
    24 // ============================ MEMBER FUNCTIONS ===============================
       
    25 
       
    26 // -----------------------------------------------------------------------------
       
    27 // CExifCore::CExifCore
       
    28 // C++ default constructor can NOT contain any code, that
       
    29 // might leave.
       
    30 // -----------------------------------------------------------------------------
       
    31 //
       
    32 CExifCore::CExifCore()
       
    33     {
       
    34     }
       
    35 
       
    36 // -----------------------------------------------------------------------------
       
    37 // CExifCore::ConstructL
       
    38 // Symbian 2nd phase constructor can leave.
       
    39 // -----------------------------------------------------------------------------
       
    40 //
       
    41 void CExifCore::ConstructL()
       
    42     {
       
    43     CreateIfdL( EIfd0 );
       
    44     CreateIfdL( EIfdExif);
       
    45     }
       
    46 
       
    47 // -----------------------------------------------------------------------------
       
    48 // CExifCore::NewL
       
    49 // Two-phased constructor.
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 CExifCore* CExifCore::NewL()
       
    53     {
       
    54     CExifCore* self = new( ELeave ) CExifCore();
       
    55     CleanupStack::PushL( self );
       
    56     self->ConstructL();
       
    57     CleanupStack::Pop();    
       
    58     return self;
       
    59     }
       
    60 
       
    61 // Destructor
       
    62 CExifCore::~CExifCore()
       
    63     {
       
    64     for ( TUint i = 0; i < KIfdNo; ++i )
       
    65         {
       
    66         if ( iIfdArray[i] )
       
    67             {
       
    68             delete iIfdArray[i];
       
    69             }
       
    70         }
       
    71     }
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CExifCore::InsertTagL
       
    75 // Inserts the given tag into the specified IFD structure.
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 void CExifCore::InsertTagL( TExifIfdType aIfdType, CExifTagImpl* aExifTag, TBool aCheckValidity )
       
    79     {
       
    80     LOGTEXT3( _L( "ExifLib: CExifCore::InsertTagL() entering: aIfdType=0x%x, aCheckValidity=%d" ), aIfdType, aCheckValidity);
       
    81     switch ( aIfdType )
       
    82         {
       
    83         case EIfd0:
       
    84         case EIfdExif:
       
    85         case EIfd1:
       
    86         case EIfdGps:
       
    87         case EIfdIntOp:
       
    88             if ( aCheckValidity && ( !TagIsValid( aExifTag->TagInfo(), aIfdType ) ) )
       
    89                 {
       
    90                 LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrNotSupported" ));
       
    91                 User::Leave( KErrNotSupported );
       
    92                 }
       
    93             if ( !iIfdArray[aIfdType] )
       
    94                 {
       
    95                 // Since a new IFD should be created, 6 bytes more than tag
       
    96                 // size is required. 
       
    97                 // Check if it exceeds 64K bytes after insertion.
       
    98                 if ( App1Size() + aExifTag->Size() + 6 > KMaxApp1Size )
       
    99                     {
       
   100                     LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrOverflow (>KMaxApp1Size)1" ));
       
   101                     User::Leave( KErrOverflow );
       
   102                     }
       
   103                 CreateIfdL( aIfdType ); 
       
   104                 TRAPD( error, iIfdArray[aIfdType]->InsertTagL( aExifTag, aCheckValidity ) );
       
   105                 if ( error != KErrNone )
       
   106                     {
       
   107                     delete( iIfdArray[aIfdType] );
       
   108                     iIfdArray[aIfdType] = 0;
       
   109                     LOGTEXT2( _L( "ExifLib: CExifCore::InsertTagL() Leaving: error=%d" ), error );
       
   110                     User::Leave( error );
       
   111                     }
       
   112                 }
       
   113             else
       
   114                 {
       
   115                 // Check if it exceeds 64K bytes after insertion.
       
   116                 if ( !( TagExists( aExifTag->Id(), aIfdType ) ) && 
       
   117                     ( App1Size() + aExifTag->Size() > KMaxApp1Size ) )
       
   118                     {
       
   119                     LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrOverflow (>KMaxApp1Size)2" ));
       
   120                     User::Leave( KErrOverflow );
       
   121                     }
       
   122                 iIfdArray[aIfdType]->InsertTagL( aExifTag, aCheckValidity );
       
   123                 }
       
   124             break;
       
   125         default:
       
   126             {
       
   127             LOGTEXT( _L( "ExifLib: CExifCore::InsertTagL() Leaving: KErrArgument" ));
       
   128             User::Leave( KErrArgument );
       
   129             }
       
   130         }
       
   131     }
       
   132 
       
   133 // -----------------------------------------------------------------------------
       
   134 // CExifCore::SetTagDataL
       
   135 // Sets the given 8-bit integer to the data of tag specified by the given tag ID
       
   136 // -----------------------------------------------------------------------------
       
   137 //
       
   138 void CExifCore::SetTagDataL( TUint16 aTagId, TInt8 aTagData )
       
   139     {
       
   140     CExifTag::TExifTagDataType tagType = CExifTag::ETagUndefined;
       
   141     // Total tag data size = 1 bytes.
       
   142     TUint32 tagCount = 1;
       
   143     TExifIfdType ifdType = EIfdExif;
       
   144     HBufC8* buffer = HBufC8::NewL( 1 );
       
   145     CleanupStack::PushL( buffer );
       
   146     buffer->Des().SetLength( 1 );
       
   147     switch ( aTagId )
       
   148         {
       
   149         case KIdFileSource:
       
   150             break;
       
   151         default:
       
   152             {
       
   153             LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) aTagId=0x%x" ), aTagId);
       
   154             User::Leave( KErrNotSupported );
       
   155             }
       
   156         }
       
   157     *REINTERPRET_CAST( TInt8*, CONST_CAST( TUint8*, buffer->Ptr() ) ) 
       
   158         = aTagData;
       
   159     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   160     CleanupStack::Pop( buffer );
       
   161     CleanupStack::PushL( tag );
       
   162     InsertTagL( ifdType, tag, ETrue );
       
   163     CleanupStack::Pop();
       
   164     }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // CExifCore::SetTagDataL
       
   168 // Sets the given 16-bit unsigned integer to the data of a tag specified by the 
       
   169 // given tag ID.
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 void CExifCore::SetTagDataL( TUint16 aTagId, TUint16 aTagData )
       
   173     {
       
   174     CExifTag::TExifTagDataType tagType = CExifTag::ETagShort;
       
   175     // Total tag data size = 2 bytes.
       
   176     // Since tag data type is 2-byte type, tagCount = 1.
       
   177     TUint32 tagCount = 1;
       
   178     TExifIfdType ifdType = EIfdExif;
       
   179     HBufC8* buffer = HBufC8::NewL( 2 );
       
   180     buffer->Des().SetLength( 2 );
       
   181     CleanupStack::PushL( buffer );
       
   182     switch ( aTagId )
       
   183         {
       
   184         case KIdCompression:
       
   185         case KIdOrientation:
       
   186         case KIdResolutionUnit:
       
   187         case KIdYCbCrPositioning:
       
   188             ifdType = EIfd0;
       
   189             break;
       
   190         case KIdFlash:
       
   191         case KIdColorSpace:
       
   192         case KIdExposureMode:
       
   193         case KIdWhiteBalance:
       
   194         case KIdSceneCaptureType:
       
   195         case KIdExposureProgram:
       
   196         case KIdMeteringMode:
       
   197         case KIdLightSource:
       
   198         case KIdContrast:
       
   199         case KIdSaturation:
       
   200         case KIdSharpness:
       
   201         case KIdCustomRendered:
       
   202         case KIdGainControl:
       
   203             break;
       
   204         default:
       
   205             {
       
   206             LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) 16 aTagId=0x%x" ), aTagId);
       
   207             User::Leave( KErrNotSupported );
       
   208             }
       
   209         }
       
   210     TExifCommon::SetUint16( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
       
   211     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   212     CleanupStack::Pop( buffer );
       
   213     CleanupStack::PushL( tag );
       
   214     InsertTagL( ifdType, tag, ETrue );
       
   215     CleanupStack::Pop();
       
   216     }
       
   217 
       
   218 // -----------------------------------------------------------------------------
       
   219 // CExifCore::SetTagDataL
       
   220 // Sets the given 32-bit integer to the data of tag specified by given tag ID
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 void CExifCore::SetTagDataL( TUint16 aTagId, TUint32 aTagData )
       
   224     {
       
   225     CExifTag::TExifTagDataType tagType = CExifTag::ETagLong;
       
   226 
       
   227     // Total tag data size = 4 bytes.
       
   228     // If the tag data type is one of 4-byte types, tagCount = 1.
       
   229     // If the tag data type is one of 1-byte types, tagCount = 4.
       
   230     TUint32 tagCount = 1;
       
   231     TExifIfdType ifdType = EIfdExif;
       
   232     HBufC8* buffer = HBufC8::NewL(4 ); 
       
   233     buffer->Des().SetLength(4 );
       
   234     
       
   235     CleanupStack::PushL( buffer );
       
   236     switch ( aTagId )
       
   237         {
       
   238         case KIdExifIfdPointer:
       
   239         case KIdGpsIfdPointer:
       
   240             ifdType = EIfd0;
       
   241             break;
       
   242         case KIdIntOpIfdPointer:
       
   243         case KIdPixelXDimension:
       
   244         case KIdPixelYDimension:
       
   245             break;
       
   246         case KIdComponentsConfiguration:
       
   247         case KIdExifVersion:
       
   248         case KIdFlashPixVersion:
       
   249             tagType = CExifTag::ETagUndefined;
       
   250             tagCount = 4;
       
   251             break;
       
   252         case KIdGpsVersion:
       
   253             tagType = CExifTag::ETagByte;
       
   254             tagCount = 4;
       
   255             ifdType = EIfdGps;
       
   256             break;
       
   257         default:
       
   258             {
       
   259             LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) 32 aTagId=0x%x" ), aTagId);
       
   260             User::Leave( KErrNotSupported );
       
   261             }
       
   262         }
       
   263     TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
       
   264     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   265     CleanupStack::Pop( buffer );
       
   266     CleanupStack::PushL( tag );
       
   267     InsertTagL( ifdType, tag, ETrue );
       
   268     CleanupStack::Pop();
       
   269     }
       
   270 
       
   271 // -----------------------------------------------------------------------------
       
   272 // CExifCore::SetTagDataL
       
   273 // Sets the given data buffer to the data of a tag specified by the given tag ID
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 void CExifCore::SetTagDataL( TUint16 aTagId, const TDesC8& aTagData )
       
   277     {
       
   278     if ( !aTagData.Length() )
       
   279         {
       
   280         User::Leave( KErrArgument );
       
   281         }
       
   282     CExifTag::TExifTagDataType tagType = CExifTag::ETagAscii;
       
   283     TUint32 tagCount = aTagData.Length();
       
   284     TExifIfdType ifdType = EIfd0;
       
   285     switch ( aTagId )
       
   286         {
       
   287         case KIdImageDescription:
       
   288         case KIdMake:
       
   289         case KIdModel:
       
   290         case KIdSoftware:
       
   291         case KIdCopyright:
       
   292             break;
       
   293         case KIdTransferFunction:
       
   294             tagType = CExifTag::ETagShort;
       
   295             tagCount /= 2;
       
   296             break;
       
   297         case KIdDateTime:
       
   298             break;
       
   299         case KIdIsoSpeedRatings:
       
   300             tagType = CExifTag::ETagShort;
       
   301             tagCount /= 2;
       
   302             ifdType = EIfdExif;
       
   303             break;
       
   304         case KIdDateTimeOriginal:
       
   305         case KIdDateTimeDigitized:
       
   306         case KIdRelatedSoundFile:
       
   307             ifdType = EIfdExif;
       
   308             break;
       
   309         case KIdMakerNote:
       
   310         case KIdUserComment:
       
   311             tagType = CExifTag::ETagUndefined;
       
   312             ifdType = EIfdExif;
       
   313             break;
       
   314         default:
       
   315             {
       
   316             LOGTEXT2( _L( "ExifLib: CExifCore::SetTagDataL() Leave( KErrNotSupported ) C8 aTagId=0x%x" ), aTagId);
       
   317             User::Leave( KErrNotSupported );
       
   318             }
       
   319         }
       
   320     // Check if ASCII string terminates with NULL character.
       
   321     // If not add NULL.
       
   322     HBufC8* buffer = NULL;
       
   323     if ( ( tagType == CExifTag::ETagAscii ) && 
       
   324         ( aTagData.Ptr()[aTagData.Length() - 1] ) )
       
   325         {
       
   326         ++tagCount;
       
   327         buffer = HBufC8::NewL( aTagData.Length() + 1 );
       
   328         buffer->Des().Copy( aTagData );
       
   329         *( CONST_CAST( TUint8*, buffer->Des().Ptr() ) + 
       
   330             aTagData.Length() ) = NULL;
       
   331         buffer->Des().SetLength( aTagData.Length() + 1 );
       
   332         }
       
   333     else
       
   334         {
       
   335         buffer = aTagData.AllocL();
       
   336         }
       
   337     CleanupStack::PushL( buffer );
       
   338     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   339     CleanupStack::Pop();
       
   340     CleanupStack::PushL( tag );
       
   341     InsertTagL( ifdType, tag, ETrue );
       
   342     CleanupStack::Pop();
       
   343     }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CExifCore::SetTagDataL
       
   347 // Sets the given 64-bit (2 x 32-bit ) unsigned integers to the data of a tag 
       
   348 // specified by the given tag ID.
       
   349 // -----------------------------------------------------------------------------
       
   350 //
       
   351 void CExifCore::SetTagDataL( 
       
   352     TUint16 aTagId, 
       
   353     TUint32 aNumerator, 
       
   354     TUint32 aDenominator )
       
   355     {
       
   356     CExifTag::TExifTagDataType tagType = CExifTag::ETagRational;
       
   357 
       
   358     // Total tag data size = 8 bytes.
       
   359     // Since tag data type is 8-byte type, tagCount = 1.
       
   360     TUint32 tagCount = 1;
       
   361     TExifIfdType ifdType = EIfd0;
       
   362     HBufC8* buffer = HBufC8::NewL( 8 );
       
   363     buffer->Des().SetLength( 8 );
       
   364     CleanupStack::PushL( buffer );
       
   365     switch ( aTagId )
       
   366         {
       
   367         case KIdXResolution:
       
   368         case KIdYResolution:
       
   369             break;
       
   370         case KIdExposureTime:
       
   371         case KIdApertureValue:
       
   372         case KIdDigitalZoomRatio:
       
   373             ifdType = EIfdExif;
       
   374             break;
       
   375         default:
       
   376             User::Leave( KErrNotSupported );
       
   377         }
       
   378     TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aNumerator );
       
   379     TExifCommon::SetUint32( 
       
   380         CONST_CAST( TUint8*, buffer->Ptr() + 4 ), aDenominator );
       
   381     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   382     CleanupStack::Pop( buffer );
       
   383     CleanupStack::PushL( tag );
       
   384     InsertTagL( ifdType, tag, ETrue );
       
   385     CleanupStack::Pop();
       
   386     }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CExifCore::SetTagDataL
       
   390 // Sets the given 64-bit (2 x 32-bit ) integers to the data of a tag specified 
       
   391 // by the given tag ID.
       
   392 // -----------------------------------------------------------------------------
       
   393 //
       
   394 void CExifCore::SetTagDataL( 
       
   395     TUint16 aTagId, 
       
   396     TInt32 aNumerator, 
       
   397     TInt32 aDenominator )
       
   398     {
       
   399     CExifTag::TExifTagDataType tagType = CExifTag::ETagSrational;
       
   400     // Total tag data size = 8 bytes.
       
   401     // Since tag data type is 8-byte type, tagCount = 1.
       
   402     TUint32 tagCount = 1;
       
   403     TExifIfdType ifdType = EIfdExif;
       
   404     HBufC8* buffer = HBufC8::NewL( 8 );
       
   405     buffer->Des().SetLength( 8 );
       
   406     CleanupStack::PushL( buffer );
       
   407     switch ( aTagId )
       
   408         {
       
   409         case KIdExposureBiasValue:
       
   410         case KIdShutterSpeedValue:
       
   411         case KIdBrightnessValue:
       
   412             break;
       
   413         default:
       
   414             User::Leave( KErrNotSupported );
       
   415         }
       
   416     TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aNumerator );
       
   417     TExifCommon::SetUint32( 
       
   418         CONST_CAST( TUint8*, buffer->Ptr() + 4 ), aDenominator );
       
   419     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   420     CleanupStack::Pop( buffer );
       
   421     CleanupStack::PushL( tag );
       
   422     InsertTagL( ifdType, tag, ETrue );
       
   423     CleanupStack::Pop();
       
   424     }
       
   425 
       
   426 // -----------------------------------------------------------------------------
       
   427 // CExifCore::SetThumbnailTagDataL
       
   428 // Sets the given 16-bit unsigned integer to the data of a thumbnail (IFD1) tag 
       
   429 // specified by the given tag ID.
       
   430 // -----------------------------------------------------------------------------
       
   431 //
       
   432 void CExifCore::SetThumbnailTagDataL( TUint16 aTagId, TUint16 aTagData )
       
   433     {
       
   434     CExifTag::TExifTagDataType tagType = CExifTag::ETagShort;
       
   435     TUint32 tagCount = 1;
       
   436     HBufC8* buffer = HBufC8::NewL( 2 );
       
   437     buffer->Des().SetLength( 2 );
       
   438     CleanupStack::PushL( buffer );
       
   439     switch ( aTagId )
       
   440         {
       
   441         case KIdCompression:
       
   442         case KIdResolutionUnit:
       
   443             break;
       
   444         default:
       
   445             User::Leave( KErrNotSupported );
       
   446         }
       
   447     TExifCommon::SetUint16( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
       
   448     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   449     CleanupStack::Pop( buffer );
       
   450     CleanupStack::PushL( tag );
       
   451     InsertTagL( EIfd1, tag, ETrue );
       
   452     CleanupStack::Pop();
       
   453     }
       
   454 
       
   455 // -----------------------------------------------------------------------------
       
   456 // CExifCore::SetThumbnailTagDataL
       
   457 // Sets the given 32-bit unsigned integer to the data of a thumbnail (IFD1) tag 
       
   458 // specified by the given tag ID,
       
   459 // -----------------------------------------------------------------------------
       
   460 //
       
   461 void CExifCore::SetThumbnailTagDataL( TUint16 aTagId, TUint32 aTagData )
       
   462     {
       
   463     CExifTag::TExifTagDataType tagType = CExifTag::ETagLong;
       
   464     TUint32 tagCount = 1;
       
   465     HBufC8* buffer = HBufC8::NewL( 4 );
       
   466     buffer->Des().SetLength( 4 );
       
   467     CleanupStack::PushL( buffer );
       
   468     switch ( aTagId )
       
   469         {
       
   470         case KIdJpegInterchangeFormat:
       
   471         case KIdJpegInterchangeFormatLength:
       
   472             break;
       
   473         default:
       
   474             User::Leave( KErrNotSupported );
       
   475         }
       
   476     TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aTagData );
       
   477     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   478     CleanupStack::Pop( buffer );
       
   479     CleanupStack::PushL( tag );
       
   480     InsertTagL( EIfd1, tag, ETrue );
       
   481     CleanupStack::Pop();
       
   482     }
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CExifCore::SetThumbnailTagDataL
       
   486 // Sets the given 64-bit (2 x 32-bit ) unsigned integers to the data of a 
       
   487 // thumbnail (IFD1) tag specified by the given tag ID.
       
   488 // -----------------------------------------------------------------------------
       
   489 //
       
   490 void CExifCore::SetThumbnailTagDataL( 
       
   491     TUint16 aTagId, 
       
   492     TUint32 aNumerator, 
       
   493     TUint32 aDenominator )
       
   494     {
       
   495     CExifTag::TExifTagDataType tagType = CExifTag::ETagRational;
       
   496     TUint32 tagCount = 1;
       
   497     HBufC8* buffer = HBufC8::NewL( 8 );
       
   498     buffer->Des().SetLength( 8 );
       
   499     CleanupStack::PushL( buffer );
       
   500     switch ( aTagId )
       
   501         {
       
   502         case KIdXResolution:
       
   503         case KIdYResolution:
       
   504             break;
       
   505         default:
       
   506             User::Leave( KErrNotSupported );
       
   507         }
       
   508     TExifCommon::SetUint32( CONST_CAST( TUint8*, buffer->Ptr() ), aNumerator );
       
   509     TExifCommon::SetUint32( 
       
   510         CONST_CAST( TUint8*, buffer->Ptr() + 4 ), aDenominator );
       
   511     CExifTagImpl* tag = CExifTagImpl::NewL( aTagId, tagType, tagCount, buffer, ETrue );
       
   512     CleanupStack::Pop( buffer );
       
   513     CleanupStack::PushL( tag );
       
   514     InsertTagL( EIfd1, tag, ETrue );
       
   515     CleanupStack::Pop();
       
   516     }
       
   517 
       
   518 // -----------------------------------------------------------------------------
       
   519 // CExifCore::GetTagData
       
   520 // Gets the 8-bit integer data of a tag specified by the given tag ID.
       
   521 // -----------------------------------------------------------------------------
       
   522 //
       
   523 TInt CExifCore::GetTagData( TUint16 aTagId, TInt8& aTagData ) const
       
   524     {
       
   525     TExifIfdType ifdType = EIfdExif;
       
   526     switch ( aTagId )
       
   527         {
       
   528         case KIdFileSource:
       
   529             break;
       
   530         default:
       
   531             return KErrNotSupported;
       
   532         }
       
   533     const CExifTagImpl* tag = NULL;
       
   534     TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
       
   535     if ( ( error ) || ( !tag ) )
       
   536         {
       
   537         return KErrNotFound;
       
   538         }
       
   539     TPtrC8 tagData = tag->Data();
       
   540     aTagData = *REINTERPRET_CAST( TInt8*, CONST_CAST( TUint8*, tagData.Ptr() ) );
       
   541     return KErrNone;
       
   542     }
       
   543 
       
   544 // -----------------------------------------------------------------------------
       
   545 // CExifCore::GetTagData
       
   546 // Gets the 16-bit unsigned integer data of a tag specified by the given tag ID.
       
   547 // -----------------------------------------------------------------------------
       
   548 //
       
   549 TInt CExifCore::GetTagData( TUint16 aTagId, TUint16& aTagData ) const
       
   550     {
       
   551     TExifIfdType ifdType = EIfdExif;
       
   552     switch ( aTagId )
       
   553         {
       
   554         case KIdFlash:
       
   555         case KIdColorSpace:
       
   556         case KIdExposureMode:
       
   557         case KIdWhiteBalance:
       
   558         case KIdSceneCaptureType:
       
   559         case KIdExposureProgram:
       
   560         case KIdMeteringMode:
       
   561         case KIdLightSource:
       
   562         case KIdContrast:
       
   563         case KIdSaturation:
       
   564         case KIdSharpness:
       
   565         case KIdCustomRendered:
       
   566         case KIdGainControl:
       
   567             break;
       
   568         case KIdOrientation:
       
   569         case KIdResolutionUnit:
       
   570         case KIdYCbCrPositioning:
       
   571             ifdType = EIfd0;
       
   572             break;
       
   573         default:
       
   574             return KErrNotSupported;
       
   575         }
       
   576     const CExifTagImpl* tag = NULL;
       
   577     TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
       
   578     if ( ( error ) || ( !tag ) )
       
   579         {
       
   580         return KErrNotFound;
       
   581         }
       
   582     TPtrC8 tagData = tag->Data();
       
   583     TRAP( error, aTagData = TExifCommon::Uint16L( 
       
   584         CONST_CAST( TUint8*, tagData.Ptr() ) ) );
       
   585     return error;
       
   586     }
       
   587 
       
   588 // -----------------------------------------------------------------------------
       
   589 // CExifCore::GetTagData
       
   590 // Gets the 32-bit unsigned integer data of a tag specified by the given tag ID.
       
   591 // -----------------------------------------------------------------------------
       
   592 //
       
   593 TInt CExifCore::GetTagData( TUint16 aTagId, TUint32& aTagData ) const
       
   594     {
       
   595     TExifIfdType ifdType = EIfdExif;
       
   596     switch ( aTagId )
       
   597         {
       
   598         case KIdComponentsConfiguration:
       
   599         case KIdPixelXDimension:
       
   600         case KIdPixelYDimension:
       
   601         case KIdExifVersion:
       
   602         case KIdFlashPixVersion:
       
   603         case KIdIntOpIfdPointer:
       
   604             break;
       
   605         case KIdGpsVersion:
       
   606             ifdType = EIfdGps;
       
   607             break;
       
   608         case KIdExifIfdPointer:
       
   609         case KIdGpsIfdPointer:
       
   610             ifdType = EIfd0;
       
   611             break;
       
   612         default:
       
   613             return KErrNotSupported;
       
   614         }
       
   615     CExifTagImpl* tag = NULL;
       
   616     TRAPD( error, tag = 
       
   617         CONST_CAST( CExifTagImpl*, GetTagL( ifdType, aTagId ) ) );
       
   618     if ( ( error ) || ( !tag ) )
       
   619         {
       
   620         return KErrNotFound;
       
   621         }
       
   622     TPtrC8 tagData = tag->Data();
       
   623     if ( tagData.Length() == 2)
       
   624         {
       
   625         TRAP( error, aTagData = STATIC_CAST( TUint32, 
       
   626             TExifCommon::Uint16L( CONST_CAST( TUint8*, tagData.Ptr() ) ) ) );
       
   627         }
       
   628     else
       
   629         {
       
   630         TRAP( error, aTagData = TExifCommon::Uint32L( 
       
   631             CONST_CAST( TUint8*, tagData.Ptr() ) ) );
       
   632         }
       
   633     return error;
       
   634     }
       
   635 
       
   636 // -----------------------------------------------------------------------------
       
   637 // CExifCore::GetTagDataL
       
   638 // Gets the data buffer of a tag specified by the given tag ID.
       
   639 // -----------------------------------------------------------------------------
       
   640 //
       
   641 HBufC8* CExifCore::GetTagDataL( TUint16 aTagId ) const
       
   642     {
       
   643     TExifIfdType ifdType = EIfd0;
       
   644     switch ( aTagId )
       
   645         {
       
   646         case KIdImageDescription:
       
   647         case KIdMake:
       
   648         case KIdModel:
       
   649         case KIdTransferFunction:
       
   650         case KIdDateTime:
       
   651         case KIdSoftware:
       
   652         case KIdCopyright:
       
   653             break;
       
   654         case KIdIsoSpeedRatings:
       
   655         case KIdDateTimeOriginal:
       
   656         case KIdDateTimeDigitized:
       
   657         case KIdMakerNote:
       
   658         case KIdUserComment:
       
   659         case KIdRelatedSoundFile:
       
   660             ifdType = EIfdExif;
       
   661             break;
       
   662         default:
       
   663             User::Leave( KErrNotSupported );
       
   664         }
       
   665     const CExifTagImpl* tag = GetTagL( ifdType, aTagId );
       
   666     
       
   667     return tag->Data().AllocL();
       
   668     }
       
   669 
       
   670 // -----------------------------------------------------------------------------
       
   671 // CExifCore::GetTagData
       
   672 // Gets the 64-bit (2 x 32-bit) unsigned integer data of a tag specified by the 
       
   673 // given tag ID.
       
   674 // -----------------------------------------------------------------------------
       
   675 //
       
   676 TInt CExifCore::GetTagData( 
       
   677     TUint16 aTagId, 
       
   678     TUint32& aNumerator, 
       
   679     TUint32& aDenominator ) const
       
   680     {
       
   681     TExifIfdType ifdType = EIfd0;
       
   682     switch ( aTagId )
       
   683         {
       
   684         case KIdXResolution:
       
   685         case KIdYResolution:
       
   686             break;
       
   687         case KIdExposureTime:
       
   688         case KIdApertureValue:
       
   689         case KIdDigitalZoomRatio:
       
   690             ifdType = EIfdExif;
       
   691             break;
       
   692         default:
       
   693             return KErrNotSupported;
       
   694         }
       
   695     const CExifTagImpl* tag = NULL;
       
   696     TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
       
   697     if ( ( error ) || ( !tag ) )
       
   698         {
       
   699         return KErrNotFound;
       
   700         }
       
   701     
       
   702     TPtrC8 tagData = tag->Data();
       
   703     TRAP( error, aNumerator = TExifCommon::Uint32L( 
       
   704         CONST_CAST( TUint8*, tagData.Ptr() ) ) );
       
   705     if ( error )
       
   706         {
       
   707         return error;
       
   708         }
       
   709     TRAP( error, aDenominator = TExifCommon::Uint32L( 
       
   710         CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ) );
       
   711     
       
   712     return error;
       
   713     }
       
   714 
       
   715 // -----------------------------------------------------------------------------
       
   716 // CExifCore::GetTagData
       
   717 // Gets the 64-bit (2 x 32-bit) integer data of tag specified by the given tag 
       
   718 // ID
       
   719 // -----------------------------------------------------------------------------
       
   720 //
       
   721 TInt CExifCore::GetTagData( 
       
   722     TUint16 aTagId, 
       
   723     TInt32& aNumerator, 
       
   724     TInt32& aDenominator ) const
       
   725     {
       
   726     TExifIfdType ifdType = EIfdExif;
       
   727     switch ( aTagId )
       
   728         {
       
   729         case KIdExposureBiasValue:
       
   730         case KIdShutterSpeedValue:
       
   731         case KIdBrightnessValue:
       
   732             break;
       
   733         default:
       
   734             return KErrNotSupported;
       
   735         }
       
   736     const CExifTagImpl* tag = NULL;
       
   737     TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
       
   738     if ( ( error ) || ( !tag ) )
       
   739         {
       
   740         return KErrNotFound;
       
   741         }
       
   742     
       
   743     TPtrC8 tagData = tag->Data();
       
   744     TRAP( error, aNumerator = TExifCommon::Int32L( 
       
   745         CONST_CAST( TUint8*, tagData.Ptr() ) ) );
       
   746     if ( error ) 
       
   747         {
       
   748         return error;
       
   749         }
       
   750     TRAP( error, aDenominator = TExifCommon::Int32L( 
       
   751         CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ));
       
   752     
       
   753     return error;
       
   754     }
       
   755 
       
   756 // -----------------------------------------------------------------------------
       
   757 // CExifCore::GetThumbnailTagData
       
   758 // Gets the 16-bit unsigned integer data of a thumbnail (IFD1) tag specified by 
       
   759 // the given tag ID.
       
   760 // -----------------------------------------------------------------------------
       
   761 //
       
   762 TInt CExifCore::GetThumbnailTagData( TUint16 aTagId, TUint16& aTagData ) const
       
   763     {
       
   764     LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData TUint16 entering" ));
       
   765     TExifIfdType ifdType = EIfd1;
       
   766     switch ( aTagId )
       
   767         {
       
   768         case KIdResolutionUnit:
       
   769         case KIdCompression:
       
   770             break;
       
   771         default:
       
   772             LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotSupported" ));
       
   773             return KErrNotSupported;
       
   774         }
       
   775     const CExifTagImpl* tag = NULL;
       
   776     TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
       
   777     if ( ( error ) || ( !tag ) )
       
   778         {
       
   779         LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotFound" ));
       
   780         return KErrNotFound;
       
   781         }
       
   782     TPtrC8 tagData = tag->Data();
       
   783     TRAP( error, aTagData = TExifCommon::Uint16L( 
       
   784         CONST_CAST( TUint8*, tagData.Ptr() ) ) );
       
   785     LOGTEXT2( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: error=%d" ), error);
       
   786     return error;
       
   787     }
       
   788 
       
   789 // -----------------------------------------------------------------------------
       
   790 // CExifCore::GetThumbnailTagData
       
   791 // Gets the 32-bit unsigned integer data of a thumbnail (IFD1) tag specified by 
       
   792 // the given tag ID.
       
   793 // -----------------------------------------------------------------------------
       
   794 //
       
   795 TInt CExifCore::GetThumbnailTagData( TUint16 aTagId, TUint32& aTagData ) const
       
   796     {
       
   797     LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData TUint32 entering" ));
       
   798     TExifIfdType ifdType = EIfd1;
       
   799     switch ( aTagId )
       
   800         {
       
   801         case KIdJpegInterchangeFormat:
       
   802         case KIdJpegInterchangeFormatLength:
       
   803             break;
       
   804         default:
       
   805             LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotSupported" ));
       
   806             return KErrNotSupported;
       
   807         }
       
   808     CExifTagImpl* tag = NULL;
       
   809     TRAPD( error, tag = CONST_CAST( CExifTagImpl*, GetTagL( ifdType, aTagId ) ) );
       
   810     if ( ( error ) || ( !tag ) )
       
   811         {
       
   812         LOGTEXT( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: KErrNotFound" ));
       
   813         return KErrNotFound;
       
   814         }
       
   815     TPtrC8 tagData = tag->Data();
       
   816     TRAP( error, aTagData = TExifCommon::Uint32L( 
       
   817         CONST_CAST( TUint8*, tagData.Ptr() ) ) );
       
   818     LOGTEXT2( _L( "ExifLib: CExifCore::GetThumbnailTagData returning: error=%d" ), error);
       
   819     return error;
       
   820     }
       
   821 
       
   822 // -----------------------------------------------------------------------------
       
   823 // CExifCore::GetThumbnailTagData
       
   824 // Gets the 64-bit (2 x 32-bit) unsigned integer data of a thumbnail (IFD1) tag 
       
   825 // specified by the given tag ID.
       
   826 // -----------------------------------------------------------------------------
       
   827 //
       
   828 TInt CExifCore::GetThumbnailTagData( 
       
   829     TUint16 aTagId, 
       
   830     TUint32& aNumerator, 
       
   831     TUint32& aDenominator ) const
       
   832     {
       
   833     TExifIfdType ifdType = EIfd1;
       
   834     switch ( aTagId )
       
   835         {
       
   836         case KIdXResolution:
       
   837         case KIdYResolution:
       
   838             break;
       
   839         default:
       
   840             return KErrNotSupported;
       
   841         }
       
   842     const CExifTagImpl* tag = NULL;
       
   843     TRAPD( error, tag = GetTagL( ifdType, aTagId ) );
       
   844     if ( ( error ) || ( !tag ) )
       
   845         {
       
   846         return KErrNotFound;
       
   847         }
       
   848     
       
   849     TPtrC8 tagData = tag->Data();
       
   850     TRAP( error, aNumerator = 
       
   851         TExifCommon::Uint32L( CONST_CAST( TUint8*, tagData.Ptr() ) ) );
       
   852     if ( error )
       
   853         {
       
   854         return error;
       
   855         }
       
   856     TRAP( error, aDenominator = 
       
   857         TExifCommon::Uint32L( CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ) );
       
   858     
       
   859     return error;
       
   860     }
       
   861 
       
   862 // -----------------------------------------------------------------------------
       
   863 // CExifCore::GetTagL
       
   864 // Gets the tag instance having the given tag ID from the specified IFD 
       
   865 // structure
       
   866 // -----------------------------------------------------------------------------
       
   867 //
       
   868 const CExifTagImpl* CExifCore::GetTagL( 
       
   869     TExifIfdType aIfdType, TUint16 aTagId ) const
       
   870     {
       
   871     switch ( aIfdType )
       
   872         {
       
   873         case EIfd0:
       
   874         case EIfdExif:
       
   875         case EIfd1:
       
   876         case EIfdGps:
       
   877         case EIfdIntOp:
       
   878             if ( !iIfdArray[aIfdType] )
       
   879                 {
       
   880                 User::Leave( KErrNotFound );
       
   881                 }
       
   882             return iIfdArray[aIfdType]->GetTagL( aTagId );
       
   883         default:
       
   884             User::Leave( KErrArgument );
       
   885         }
       
   886     return 0;
       
   887     }
       
   888 
       
   889 // -----------------------------------------------------------------------------
       
   890 // CExifCore::DeleteTag
       
   891 // Removes the tag instance having the given tag ID from the specified IFD 
       
   892 // structure
       
   893 // -----------------------------------------------------------------------------
       
   894 //
       
   895 TInt CExifCore::DeleteTag( TExifIfdType aIfdType, TUint16 aTagId )
       
   896     {
       
   897     switch ( aIfdType )
       
   898         {
       
   899         case EIfd0:
       
   900         case EIfdExif:
       
   901         case EIfd1:
       
   902         case EIfdGps:
       
   903         case EIfdIntOp:
       
   904             {
       
   905             if ( !iIfdArray[aIfdType] )
       
   906                 {
       
   907                 return KErrNotFound;
       
   908                 }
       
   909             TInt error = iIfdArray[aIfdType]->DeleteTag( aTagId );
       
   910             if ( error )
       
   911                 {
       
   912                 return error;
       
   913                 }
       
   914             if ( iIfdArray[aIfdType]->Size() )
       
   915                 {
       
   916                 return KErrNone;
       
   917                 }
       
   918             return DeleteIfd( aIfdType );
       
   919             }
       
   920         default:
       
   921             return KErrArgument;
       
   922         }
       
   923     }
       
   924 
       
   925 // -----------------------------------------------------------------------------
       
   926 // CExifCore::GetTagIdsL
       
   927 // Gets the tag IDs and the number of tags in the specified IFD structure.
       
   928 // -----------------------------------------------------------------------------
       
   929 //
       
   930 TUint16* CExifCore::GetTagIdsL( TExifIfdType aIfdType, TInt& aNoTags ) const
       
   931     {
       
   932     switch ( aIfdType )
       
   933         {
       
   934         case EIfd0:
       
   935         case EIfdExif:
       
   936         case EIfd1:
       
   937         case EIfdGps:
       
   938         case EIfdIntOp:
       
   939             if ( !iIfdArray[aIfdType] )
       
   940                 {
       
   941                 User::Leave( KErrNotFound );
       
   942                 }
       
   943             return iIfdArray[aIfdType]->GetTagIdsL( aNoTags );
       
   944         default:
       
   945             User::Leave( KErrArgument );
       
   946         }
       
   947     return 0;
       
   948     }
       
   949 
       
   950 // -----------------------------------------------------------------------------
       
   951 // CExifCore::iExifCore->CreateIfdL
       
   952 // Instantiates the specified IFD structure.
       
   953 // -----------------------------------------------------------------------------
       
   954 //
       
   955 void CExifCore::CreateIfdL( TExifIfdType aIfdType )
       
   956     {
       
   957     if ( App1Size() > ( KMaxApp1Size - 6 ) )
       
   958         {
       
   959         User::Leave( KErrOverflow );
       
   960         }
       
   961     switch ( aIfdType )
       
   962         {
       
   963         case EIfd0:
       
   964         case EIfdExif:
       
   965         case EIfd1:
       
   966         case EIfdGps:
       
   967         case EIfdIntOp:
       
   968             iIfdArray[aIfdType] = CExifIfd::NewBaseL( aIfdType );
       
   969             break;
       
   970         default:
       
   971             User::Leave( KErrArgument );
       
   972         }
       
   973     }
       
   974 
       
   975 // -----------------------------------------------------------------------------
       
   976 // CExifCore::DeleteIfd
       
   977 // Removes the specified IFD structure and all its tags.
       
   978 // -----------------------------------------------------------------------------
       
   979 //
       
   980 TInt CExifCore::DeleteIfd( TExifIfdType aIfdType )
       
   981     {
       
   982     switch ( aIfdType )
       
   983         {
       
   984         case EIfd0:
       
   985             break;
       
   986         case EIfdExif:
       
   987             break;
       
   988         case EIfd1:
       
   989             iIfdArray[EIfd0]->SetNextIfdOffset( 0 );
       
   990             break;
       
   991         case EIfdGps:
       
   992             iIfdArray[EIfd0]->DeleteTag( KIdGpsIfdPointer );
       
   993             break;
       
   994         case EIfdIntOp:
       
   995             iIfdArray[EIfdExif]->DeleteTag( KIdIntOpIfdPointer );
       
   996             break;
       
   997         default:
       
   998             return KErrArgument;
       
   999         }
       
  1000     if ( iIfdArray[aIfdType] )
       
  1001         {
       
  1002         delete ( iIfdArray[aIfdType] );
       
  1003         iIfdArray[aIfdType] = 0;
       
  1004         return KErrNone;
       
  1005         }
       
  1006     else
       
  1007         {
       
  1008         return KErrNotFound;
       
  1009         }
       
  1010     }
       
  1011 
       
  1012 // -----------------------------------------------------------------------------
       
  1013 // CExifCore::GetIfdTypesL
       
  1014 // Gets the IFD types and number of IFDs in the file format.
       
  1015 // -----------------------------------------------------------------------------
       
  1016 //
       
  1017 TExifIfdType* CExifCore::GetIfdTypesL( TInt& aNoIfd ) const
       
  1018     {
       
  1019     TInt noIfd = 0;
       
  1020     TUint i = 0;
       
  1021     for ( i = 0; i < KIfdNo; ++i )
       
  1022         {
       
  1023         if ( iIfdArray[i] )
       
  1024             {
       
  1025             ++noIfd;
       
  1026             }
       
  1027         }
       
  1028     if ( !noIfd )
       
  1029         {
       
  1030         User::Leave( KErrNotFound );
       
  1031         }
       
  1032 
       
  1033     TExifIfdType* ifdTypes = STATIC_CAST( TExifIfdType*, 
       
  1034         User::AllocL( sizeof( TExifIfdType ) * noIfd ) );
       
  1035     aNoIfd = noIfd;
       
  1036     noIfd = 0;
       
  1037     for ( i=EIfd0; i<=EIfdIntOp; ++i )
       
  1038         {
       
  1039         if ( iIfdArray[i] )
       
  1040             {
       
  1041             ifdTypes[noIfd] = STATIC_CAST( TExifIfdType, i );
       
  1042             ++noIfd;
       
  1043             }
       
  1044         }
       
  1045     return ifdTypes;
       
  1046     }
       
  1047 
       
  1048 // -----------------------------------------------------------------------------
       
  1049 // CExifCore::GetThumbnailL
       
  1050 // Gets the Exif thumbnail image data from the IFD1 structure.
       
  1051 // -----------------------------------------------------------------------------
       
  1052 //
       
  1053 HBufC8* CExifCore::GetThumbnailL() const
       
  1054     {
       
  1055     if ( !iIfdArray[EIfd1] )
       
  1056         {
       
  1057         User::Leave( KErrNotFound );
       
  1058         }
       
  1059 
       
  1060     TDesC8* thumbnailData = NULL;
       
  1061     User::LeaveIfError( ( STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] ) )->
       
  1062         GetThumbnailData( thumbnailData ) );
       
  1063 
       
  1064     // Next check needed when option ENoTagChecking is used
       
  1065     if ( !thumbnailData )
       
  1066         {
       
  1067         User::Leave( KErrNotFound );
       
  1068         }
       
  1069 
       
  1070     return thumbnailData->AllocL();
       
  1071     }
       
  1072 
       
  1073 // -----------------------------------------------------------------------------
       
  1074 // CExifCore::InsertThumbnailL
       
  1075 // Inserts/Updates the given Exif thumbnail image data in the IFD1 structure.
       
  1076 // -----------------------------------------------------------------------------
       
  1077 //
       
  1078 void CExifCore::InsertThumbnailL( TDesC8* aThumbnailData )
       
  1079     {
       
  1080     if ( STATIC_CAST( TUint, App1Size() + aThumbnailData->Length() ) > 
       
  1081         KMaxApp1Size )
       
  1082         {
       
  1083         User::Leave( KErrOverflow );
       
  1084         }
       
  1085 
       
  1086     TUint8* jpgStartPtr = CONST_CAST( TUint8*, aThumbnailData->Ptr() );
       
  1087     TUint8* jpgEndPtr = jpgStartPtr + aThumbnailData->Length();
       
  1088 
       
  1089     jpgStartPtr = TExifCommon::LocateJpegMarkerPtr( 
       
  1090         KSoi, jpgStartPtr, jpgEndPtr );
       
  1091     if( !jpgStartPtr )
       
  1092         {
       
  1093         User::Leave( KErrCorrupt );
       
  1094         }
       
  1095 
       
  1096     jpgStartPtr = TExifCommon::LocateJpegMarkerPtr( 
       
  1097         KSof0, jpgStartPtr, jpgEndPtr );
       
  1098     if( !jpgStartPtr )
       
  1099         {
       
  1100         User::Leave( KErrCorrupt );
       
  1101         }
       
  1102 
       
  1103     jpgStartPtr = TExifCommon::LocateJpegMarkerPtr( 
       
  1104         KEoi, jpgStartPtr, jpgEndPtr );
       
  1105     if( !jpgStartPtr )
       
  1106         {
       
  1107         User::Leave( KErrCorrupt );
       
  1108         }
       
  1109 
       
  1110     if ( !iIfdArray[EIfd1] )
       
  1111         {
       
  1112         CreateIfdL( EIfd1 );
       
  1113         }
       
  1114     User::LeaveIfError( ( STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] ) )->
       
  1115         SetThumbnailData( aThumbnailData ) );
       
  1116     }
       
  1117 
       
  1118 // -----------------------------------------------------------------------------
       
  1119 // CExifCore::RemoveThumbnail
       
  1120 // Removes the Exif thumbnail image data from the IFD1 structure.
       
  1121 // -----------------------------------------------------------------------------
       
  1122 //
       
  1123 TInt CExifCore::RemoveThumbnail()
       
  1124     {
       
  1125     if ( !iIfdArray[EIfd1] )
       
  1126         {
       
  1127         return KErrNotFound;
       
  1128         }
       
  1129     return 
       
  1130         ( STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] ) )->RemoveThumbnailData();
       
  1131     }
       
  1132 
       
  1133 
       
  1134 // -----------------------------------------------------------------------------
       
  1135 // CExifCore::WriteExifDataL
       
  1136 // Writes the Exif data to the given descriptor starting from the specified 
       
  1137 // position/offset.
       
  1138 // -----------------------------------------------------------------------------
       
  1139 //
       
  1140 void CExifCore::WriteExifDataL( HBufC8*& aExifData, TUint& aPos )
       
  1141     {
       
  1142     // Ensure byte alignment
       
  1143     if ( ( aExifData->Length() - aPos ) % 2 > 0 )
       
  1144         {
       
  1145         User::Leave( KErrGeneral );
       
  1146         }
       
  1147     TUint16* exifDataPtr = REINTERPRET_CAST( TUint16*, 
       
  1148         CONST_CAST( TUint8*, aExifData->Ptr() ) + aPos );
       
  1149     WriteExifHeaderL( exifDataPtr, aPos );
       
  1150     WriteIfdL( exifDataPtr, EIfd0, aPos );
       
  1151     WriteIfdL( exifDataPtr, EIfdExif, aPos );
       
  1152     WriteIfdL( exifDataPtr, EIfdGps, aPos );
       
  1153     WriteIfdL( exifDataPtr, EIfdIntOp, aPos );
       
  1154     WriteIfdL( exifDataPtr, EIfd1, aPos );
       
  1155     }
       
  1156 
       
  1157 // -----------------------------------------------------------------------------
       
  1158 // CExifCore::WriteJpegHeaderL
       
  1159 // Writes the Jpeg header to the given descriptor starting from the specified 
       
  1160 // position/offset.
       
  1161 // -----------------------------------------------------------------------------
       
  1162 //
       
  1163 void CExifCore::WriteJpegHeaderL( HBufC8*& aExifData, TUint& aPos )
       
  1164     {
       
  1165     if ( ( aExifData->Length() - aPos ) % 2 > 0 )
       
  1166         {
       
  1167         User::Leave( KErrGeneral );
       
  1168         }
       
  1169     TUint16* exifDataPtr = REINTERPRET_CAST( TUint16*, 
       
  1170         CONST_CAST( TUint8*, aExifData->Ptr() ) + aPos );
       
  1171     *exifDataPtr = KSoiRev;
       
  1172     aPos+=2;
       
  1173     }
       
  1174 
       
  1175 // -----------------------------------------------------------------------------
       
  1176 // CExifCore::Finalize
       
  1177 // Finalizes the Exif data to ensure the validity, updates the internal offsets.
       
  1178 // -----------------------------------------------------------------------------
       
  1179 //
       
  1180 TInt CExifCore::Finalize()
       
  1181     {
       
  1182     TInt error = 0;
       
  1183     TUint32 ifdOffset = FindIfdOffset( EIfdExif );
       
  1184     TRAP( error, SetTagDataL( KIdExifIfdPointer, ifdOffset ) );
       
  1185     if ( error )
       
  1186         {
       
  1187         return error;
       
  1188         }
       
  1189 
       
  1190     ifdOffset = FindIfdOffset( EIfdGps );
       
  1191     if ( ifdOffset )
       
  1192         {
       
  1193         TRAP( error, SetTagDataL( KIdGpsIfdPointer, ifdOffset ) );
       
  1194         if ( error )
       
  1195             {
       
  1196             return error;
       
  1197             }
       
  1198         }
       
  1199     else
       
  1200         {
       
  1201         DeleteTag( EIfd0, KIdGpsIfdPointer );
       
  1202         }
       
  1203     
       
  1204     ifdOffset = FindIfdOffset( EIfdIntOp );
       
  1205     if ( ifdOffset )
       
  1206         {
       
  1207         TRAP( error, SetTagDataL( KIdIntOpIfdPointer, ifdOffset ) );
       
  1208         if ( error )
       
  1209             {
       
  1210             return error;
       
  1211             }
       
  1212         }
       
  1213     else
       
  1214         {
       
  1215         DeleteTag( EIfdExif, KIdIntOpIfdPointer );
       
  1216         }
       
  1217     
       
  1218     if ( iIfdArray[EIfd1] )
       
  1219         {
       
  1220         if ( !STATIC_CAST( CExifIfd1*, iIfdArray[EIfd1] )->ThumbnailSize() )
       
  1221             {
       
  1222             DeleteIfd( EIfd1 );
       
  1223             iIfdArray[EIfd0]->SetNextIfdOffset( 0 );
       
  1224             }
       
  1225         else
       
  1226             {
       
  1227             ifdOffset = FindIfdOffset( EIfd1 );
       
  1228             iIfdArray[EIfd0]->SetNextIfdOffset( ifdOffset );
       
  1229             TRAP( error, SetThumbnailTagDataL( KIdJpegInterchangeFormat, 
       
  1230                 STATIC_CAST( TUint32, ifdOffset + iIfdArray[EIfd1]->Size() ) ) );
       
  1231             if ( error )
       
  1232                 {
       
  1233                 return error;
       
  1234                 }
       
  1235             TRAP( error, SetThumbnailTagDataL( KIdJpegInterchangeFormatLength, 
       
  1236                 STATIC_CAST( TUint32, STATIC_CAST( CExifIfd1*, 
       
  1237                 iIfdArray[EIfd1] )->ThumbnailSize() ) ) );
       
  1238             if ( error )
       
  1239                 {
       
  1240                 return error;
       
  1241                 }
       
  1242             TRAP( error, SetThumbnailTagDataL( KIdCompression, KCompressed ) );
       
  1243             if ( error )
       
  1244                 {
       
  1245                 return error;
       
  1246                 }
       
  1247             }
       
  1248         }
       
  1249         
       
  1250     return KErrNone;
       
  1251     }
       
  1252 
       
  1253 // -----------------------------------------------------------------------------
       
  1254 // CExifCore::TotalSize
       
  1255 // Returns the total size of the Exif file format in bytes.
       
  1256 // -----------------------------------------------------------------------------
       
  1257 //
       
  1258 TUint CExifCore::TotalSize() const
       
  1259     {
       
  1260     return ( App1Size() + 4 + JpegSize() );
       
  1261     }
       
  1262 
       
  1263 // -----------------------------------------------------------------------------
       
  1264 // CExifCore::JpegSize
       
  1265 // Returns the size of the Jpeg image in the Exif file format, excluding SOI 
       
  1266 // and APP markers in bytes.
       
  1267 // -----------------------------------------------------------------------------
       
  1268 //
       
  1269 TUint CExifCore::JpegSize() const
       
  1270     {
       
  1271     return iJpgEndOffset - iJpgStartOffset;
       
  1272     }
       
  1273 
       
  1274 // -----------------------------------------------------------------------------
       
  1275 // CExifCore::App1Size
       
  1276 // Returns the size of the APP1 marker, which includes the Exif-specific data 
       
  1277 // in bytes
       
  1278 // -----------------------------------------------------------------------------
       
  1279 //
       
  1280 TUint16 CExifCore::App1Size() const
       
  1281     {
       
  1282     TUint16 app1Size = 0;
       
  1283     if ( iIfdArray[EIfd0] )
       
  1284         {
       
  1285         app1Size = STATIC_CAST( TUint16, app1Size + iIfdArray[EIfd0]->Size() );
       
  1286         }
       
  1287     if ( iIfdArray[EIfdExif] )
       
  1288         {
       
  1289         app1Size = 
       
  1290             STATIC_CAST( TUint16, app1Size + iIfdArray[EIfdExif]->Size() );
       
  1291         }
       
  1292     if ( iIfdArray[EIfd1] )
       
  1293         {
       
  1294         app1Size = STATIC_CAST( TUint16, app1Size + iIfdArray[EIfd1]->Size() );
       
  1295         app1Size = STATIC_CAST( TUint16, app1Size + ( STATIC_CAST( CExifIfd1*, 
       
  1296             iIfdArray[EIfd1] )->ThumbnailSize() ) );
       
  1297         }
       
  1298     if ( iIfdArray[EIfdGps] )
       
  1299         {
       
  1300         app1Size  = 
       
  1301             STATIC_CAST( TUint16, app1Size + iIfdArray[EIfdGps]->Size() );
       
  1302         }
       
  1303     if ( iIfdArray[EIfdIntOp] )
       
  1304         {
       
  1305         app1Size = 
       
  1306             STATIC_CAST( TUint16, app1Size + iIfdArray[EIfdIntOp]->Size() );
       
  1307         }
       
  1308     return STATIC_CAST( TUint16, app1Size + 16 );
       
  1309     }
       
  1310 
       
  1311 // -----------------------------------------------------------------------------
       
  1312 // CExifCore::IsValid
       
  1313 // Checks if the Exif data is in valid Exif v2.2 format and contains all 
       
  1314 // mandatory information.
       
  1315 // -----------------------------------------------------------------------------
       
  1316 //
       
  1317 TBool CExifCore::IsValid() const
       
  1318     {
       
  1319     if ( (!iIfdArray[EIfd0] ) || (!iIfdArray[EIfdExif] ) )
       
  1320         {
       
  1321         return EFalse;
       
  1322         }
       
  1323 
       
  1324     if ( !iIfdArray[EIfd0]->IsValid() )
       
  1325         {
       
  1326         return EFalse;
       
  1327         }
       
  1328 
       
  1329     if ( !iIfdArray[EIfdExif]->IsValid() )
       
  1330         {
       
  1331         return EFalse;
       
  1332         }
       
  1333 
       
  1334     if ( iIfdArray[EIfd1] )
       
  1335         {
       
  1336         if ( !iIfdArray[EIfd1]->IsValid() )
       
  1337             {
       
  1338             return EFalse;
       
  1339             }
       
  1340         }
       
  1341     if ( iIfdArray[EIfdGps] )
       
  1342         {
       
  1343         if ( !iIfdArray[EIfdGps]->IsValid() )
       
  1344             {
       
  1345             return EFalse;
       
  1346             }
       
  1347         TRAPD( error, GetTagL( EIfd0, KIdGpsIfdPointer ) );
       
  1348         if ( error )
       
  1349             {
       
  1350             return EFalse;
       
  1351             }
       
  1352         }
       
  1353 
       
  1354     if ( iIfdArray[EIfdIntOp] )
       
  1355         {
       
  1356         if ( !iIfdArray[EIfdIntOp]->IsValid() )
       
  1357             {
       
  1358             return EFalse;
       
  1359             }
       
  1360         TRAPD( error, GetTagL( EIfdExif, KIdIntOpIfdPointer ) );
       
  1361         if ( error )
       
  1362             {
       
  1363             return EFalse;
       
  1364             }
       
  1365         }
       
  1366 
       
  1367     return ETrue;
       
  1368     }
       
  1369 
       
  1370 // -----------------------------------------------------------------------------
       
  1371 // CExifCore::TagIsValid
       
  1372 // Checks if the specified tag information conforms to the Full Validity 
       
  1373 // characteristics (Data count is correct, data type matches tag ID and data 
       
  1374 // value falls into the predefined range).
       
  1375 // -----------------------------------------------------------------------------
       
  1376 //
       
  1377 TBool CExifCore::TagIsValid( TExifTagInfo aTagInfo, TExifIfdType aIfdType ) const
       
  1378     {
       
  1379     LOGTEXT3( _L( "ExifLib: CExifCore::TagIsValid() entering: aIfdType=0x%x, aTagInfo.iId=0x%x" ), aIfdType, aTagInfo.iId );
       
  1380     TInt noTags = 0;
       
  1381     const TReferenceTag* tags = NULL;
       
  1382     switch ( aIfdType )
       
  1383         {
       
  1384         case EIfd0:
       
  1385             noTags = KNoIfd0Tags;
       
  1386             tags = ifd0Tags;
       
  1387             break;
       
  1388         case EIfdExif:
       
  1389             noTags = KNoIfdExifTags;
       
  1390             tags = ifdExifTags;
       
  1391             break;
       
  1392         case EIfd1:
       
  1393             noTags = KNoIfd1Tags;
       
  1394             tags = ifd1Tags;
       
  1395             break;
       
  1396         case EIfdGps:
       
  1397             noTags = KNoIfdGpsTags;
       
  1398             tags = ifdGpsTags;
       
  1399             break;
       
  1400         case EIfdIntOp:
       
  1401             noTags = KNoIfdIntOpTags;
       
  1402             tags = ifdIntOpTags;
       
  1403             break;
       
  1404         default:
       
  1405             return EFalse;
       
  1406         }
       
  1407 
       
  1408     TInt k = 0;
       
  1409     TBool found = EFalse;
       
  1410     for ( k = 0; ( k < noTags ) && ( !found ); ++k )
       
  1411         {
       
  1412         if ( tags[k].iId == aTagInfo.iId )
       
  1413             {
       
  1414             found = ETrue;
       
  1415             }
       
  1416         }
       
  1417 
       
  1418     if ( !found )
       
  1419         {
       
  1420         LOGTEXT( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse (tag not found)" ));
       
  1421         return EFalse;
       
  1422         }
       
  1423     // k locates the item next to the found item. Make it locate the found.
       
  1424     --k;
       
  1425 
       
  1426     if ( tags[k].iDataType != TReferenceTag::ETagLongOrShort )
       
  1427         {
       
  1428         if ( tags[k].iDataType != aTagInfo.iDataType )
       
  1429             {
       
  1430             LOGTEXT2( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse 1 aTagInfo.iDataType=0x%x" ), aTagInfo.iDataType );
       
  1431             return EFalse;
       
  1432             }
       
  1433         }
       
  1434     else if ( ( aTagInfo.iDataType != CExifTag::ETagShort ) && 
       
  1435         ( aTagInfo.iDataType != CExifTag::ETagLong ) )
       
  1436         {
       
  1437         LOGTEXT2( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse 2 aTagInfo.iDataType=0x%x" ), aTagInfo.iDataType );
       
  1438         return EFalse;
       
  1439         }
       
  1440     else
       
  1441         {
       
  1442         // Nothing to check for this case!
       
  1443         }
       
  1444 
       
  1445     if ( tags[k].iDataCount != KAny )
       
  1446         {
       
  1447         if ( tags[k].iDataCount != aTagInfo.iDataCount )
       
  1448             {
       
  1449             LOGTEXT2( _L( "ExifLib: CExifCore::TagIsValid() returning EFalse aTagInfo.iDataCount=0x%x" ), aTagInfo.iDataCount );
       
  1450             return EFalse;
       
  1451             }
       
  1452         }
       
  1453 
       
  1454     LOGTEXT( _L( "ExifLib: CExifCore::TagIsValid() returning ETrue" ));
       
  1455     return ETrue;
       
  1456     }
       
  1457 
       
  1458 // -----------------------------------------------------------------------------
       
  1459 // CExifCore::IfdExists
       
  1460 // Checks if the specified IFD structure exists in the Exif data.
       
  1461 // -----------------------------------------------------------------------------
       
  1462 //
       
  1463 TBool CExifCore::IfdExists( TExifIfdType aIfdType ) const
       
  1464     {
       
  1465     if ( iIfdArray[aIfdType] )
       
  1466         {
       
  1467         return ETrue;
       
  1468         }
       
  1469     return EFalse;
       
  1470     }
       
  1471 
       
  1472 // -----------------------------------------------------------------------------
       
  1473 // CExifCore::TagExists
       
  1474 // Checks if the tag having the given tag ID exists in the specified IFD 
       
  1475 // structure
       
  1476 // -----------------------------------------------------------------------------
       
  1477 //
       
  1478 TBool CExifCore::TagExists( TUint16 aTagId, TExifIfdType aIfdType ) const
       
  1479     {
       
  1480     if ( iIfdArray[aIfdType] )
       
  1481         {
       
  1482         return iIfdArray[aIfdType]->TagExists( aTagId );
       
  1483         }
       
  1484     return EFalse;
       
  1485     }
       
  1486 
       
  1487 // -----------------------------------------------------------------------------
       
  1488 // CExifCore::SetJpgOffsets
       
  1489 // Sets the given Jpeg data start and end offsets.
       
  1490 // -----------------------------------------------------------------------------
       
  1491 //
       
  1492 void CExifCore::SetJpgOffsets( TUint32 aJpgStartOffset, TUint32 aJpgEndOffset )
       
  1493     {
       
  1494     iJpgStartOffset = aJpgStartOffset;
       
  1495     iJpgEndOffset = aJpgEndOffset;
       
  1496     }
       
  1497 
       
  1498 // -----------------------------------------------------------------------------
       
  1499 // CExifCore::GetJpegData
       
  1500 // Gets the pure Jpeg image data excluding the SOI and APP1 markers.
       
  1501 // -----------------------------------------------------------------------------
       
  1502 //
       
  1503 TInt CExifCore::GetJpegData( TPtr8 aJpgPointer ) const
       
  1504     {
       
  1505     if ( !iJpgStartOffset )
       
  1506         {
       
  1507         return KErrGeneral;
       
  1508         }
       
  1509 
       
  1510     TUint8* jpgStartPtr = CONST_CAST( TUint8*, iDataStartPtr + iJpgStartOffset );
       
  1511     if ( *jpgStartPtr != KMarkerStart )
       
  1512         {
       
  1513         return KErrGeneral;
       
  1514         }
       
  1515     aJpgPointer.Copy( jpgStartPtr, JpegSize() );
       
  1516     return KErrNone;
       
  1517     }
       
  1518 
       
  1519 // -----------------------------------------------------------------------------
       
  1520 // CExifCore::SetDataStartPtr
       
  1521 // Sets the Exif data start pointer.
       
  1522 // -----------------------------------------------------------------------------
       
  1523 //
       
  1524 void CExifCore::SetDataStartPtr( const TUint8* aPtr )
       
  1525     {
       
  1526     iDataStartPtr = aPtr;
       
  1527     }
       
  1528 
       
  1529 // -----------------------------------------------------------------------------
       
  1530 // CExifCore::WriteExifHeaderL
       
  1531 // Writes the Exif header to the location, which is defined by the given pointer 
       
  1532 // and the offset.
       
  1533 // -----------------------------------------------------------------------------
       
  1534 //
       
  1535 void CExifCore::WriteExifHeaderL( TUint16*& aExifDataPtr, TUint& aPos )
       
  1536     {
       
  1537     if ( !aExifDataPtr )
       
  1538         {
       
  1539         User::Leave( KErrGeneral );
       
  1540         }
       
  1541     *aExifDataPtr++ = KApp1Rev;
       
  1542     TUint16 app1Size = App1Size();
       
  1543     *REINTERPRET_CAST( TUint8*, aExifDataPtr ) = STATIC_CAST( TUint8, 
       
  1544         app1Size >> 8 ); 
       
  1545     *( REINTERPRET_CAST( TUint8*, aExifDataPtr ) + 1 ) = STATIC_CAST( 
       
  1546         TUint8, app1Size ); 
       
  1547     ++aExifDataPtr;
       
  1548     TExifCommon::SetUint32( REINTERPRET_CAST( TUint8*, aExifDataPtr ), 
       
  1549         KExifIdentifierRev );
       
  1550     aExifDataPtr+=2;
       
  1551     *aExifDataPtr++ = KExifPad;
       
  1552     *aExifDataPtr++ = KLittleEndian;
       
  1553     *aExifDataPtr++ = KExifDummyRev;
       
  1554     TExifCommon::SetUint32( REINTERPRET_CAST( TUint8*, aExifDataPtr ), 
       
  1555         KHeaderOffset );
       
  1556     aExifDataPtr+=2;
       
  1557     aPos = 20;
       
  1558     }
       
  1559 
       
  1560 // -----------------------------------------------------------------------------
       
  1561 // CExifCore::WriteIfdl
       
  1562 // Writes the specified IFD data to the location, which is defined by the given 
       
  1563 // pointer and the offset.
       
  1564 // -----------------------------------------------------------------------------
       
  1565 //
       
  1566 void CExifCore::WriteIfdL( 
       
  1567     TUint16*& aExifDataPtr, 
       
  1568     TExifIfdType aIfdType, 
       
  1569     TUint& aPos )
       
  1570     {
       
  1571     if ( !aExifDataPtr )
       
  1572         {
       
  1573         User::Leave( KErrGeneral );
       
  1574         }
       
  1575     if ( iIfdArray[aIfdType] )
       
  1576         {
       
  1577         iIfdArray[aIfdType]->WriteTagsL( aExifDataPtr, aPos );
       
  1578         if ( aIfdType == EIfd1 )
       
  1579             {
       
  1580             (STATIC_CAST( CExifIfd1*, iIfdArray[aIfdType] ) )->WriteThumbnailL( 
       
  1581                 REINTERPRET_CAST( TUint8*&, aExifDataPtr ), aPos );
       
  1582             }
       
  1583         }
       
  1584     }
       
  1585 
       
  1586 // -----------------------------------------------------------------------------
       
  1587 // CExifCore::FindIfdOffset
       
  1588 // Returns the offset of the specified IFD structure in the Exif data.
       
  1589 // -----------------------------------------------------------------------------
       
  1590 //
       
  1591 TUint32 CExifCore::FindIfdOffset( TExifIfdType aIfdType ) const
       
  1592     {
       
  1593     if ( !iIfdArray[aIfdType] )
       
  1594         {
       
  1595         return 0;
       
  1596         }
       
  1597     TUint32 offset = 8;
       
  1598     switch ( aIfdType )
       
  1599         {
       
  1600         case EIfd0:
       
  1601             break;
       
  1602         case EIfdExif:
       
  1603             offset += ( iIfdArray[EIfd0]->Size() );
       
  1604             break;
       
  1605         case EIfd1:
       
  1606             offset += ( iIfdArray[EIfd0]->Size() + iIfdArray[EIfdExif]->Size() );
       
  1607             if ( iIfdArray[EIfdGps] )
       
  1608                 {
       
  1609                 offset += iIfdArray[EIfdGps]->Size();
       
  1610                 }
       
  1611             if ( iIfdArray[EIfdIntOp] )
       
  1612                 {
       
  1613                 offset += iIfdArray[EIfdIntOp]->Size();
       
  1614                 }
       
  1615             break;
       
  1616         case EIfdGps:
       
  1617             offset += ( iIfdArray[EIfd0]->Size() + iIfdArray[EIfdExif]->Size() );
       
  1618             break;
       
  1619         case EIfdIntOp:
       
  1620             offset += ( iIfdArray[EIfd0]->Size() + iIfdArray[EIfdExif]->Size() );
       
  1621             if ( iIfdArray[EIfdGps] )
       
  1622                 {
       
  1623                 offset += iIfdArray[EIfdGps]->Size();
       
  1624                 }
       
  1625             break;
       
  1626         default:
       
  1627             return 0;
       
  1628         }
       
  1629     return offset;
       
  1630     }
       
  1631