imagingmodules/exiflib/src/ExifModify.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:  Exif v2.2 file format modifier API implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "ExifModifyImpl.h"
       
    21 #include "ExifReadImpl.h"
       
    22 #include "ExifTagImpl.h"
       
    23 #include "ExifCore.h"
       
    24 #include "ExifCommon.h"
       
    25 
       
    26 // ============================ CLASS CExifModify ==============================
       
    27 // ============================ MEMBER FUNCTIONS ===============================
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // CExifModify::NewL
       
    31 // Two-phased constructor.
       
    32 // -----------------------------------------------------------------------------
       
    33 //
       
    34 EXPORT_C CExifModify* CExifModify::NewL( 
       
    35     const TDesC8& aExifData, 
       
    36     CExifModify::TOperationMode aOperationMode )
       
    37     {
       
    38     return CExifModifyImpl::NewL( aExifData, STATIC_CAST( TBool, 
       
    39         aOperationMode ), CExifModify::ENoOptions );
       
    40     }
       
    41 
       
    42 EXPORT_C CExifModify* CExifModify::NewL( 
       
    43     const TDesC8& aExifData, 
       
    44     CExifModify::TOperationMode aOperationMode,
       
    45     TUint aExifModifyOption )
       
    46     {
       
    47     return CExifModifyImpl::NewL( aExifData, STATIC_CAST( TBool, 
       
    48         aOperationMode ), aExifModifyOption );
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CExifModify::NewL
       
    53 // Two-phased constructor.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 EXPORT_C CExifModify* CExifModify::NewL()
       
    57     {
       
    58     return CExifModifyImpl::NewL();
       
    59     }
       
    60 
       
    61 // Destructor
       
    62 CExifModify::~CExifModify()
       
    63     {
       
    64     }
       
    65 
       
    66 
       
    67 // ============================ CLASS CExifModifyImpl ==========================
       
    68 // ============================ MEMBER FUNCTIONS ===============================
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CExifModifyImpl::CExifModifyImpl
       
    72 // C++ default constructor can NOT contain any code, that
       
    73 // might leave.
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 CExifModifyImpl::CExifModifyImpl()
       
    77     {
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CExifModifyImpl::ConstructL
       
    82 // Symbian 2nd phase constructor can leave.
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 void CExifModifyImpl::ConstructL( const TDesC8& aInData, TBool aCreate, TUint aExifModifyOption )
       
    86     {
       
    87     iExifModifyOption = aExifModifyOption;
       
    88     TUint readOption = CExifRead::ENoOptions;
       
    89     if ( aExifModifyOption & CExifModify::ENoJpegParsing )
       
    90         {
       
    91         readOption |= CExifRead::EFastJpegParsing;
       
    92         }
       
    93     if ( aExifModifyOption & CExifModify::ENoTagChecking )
       
    94         {
       
    95         readOption |= CExifRead::ENoTagChecking;
       
    96         }
       
    97     iExifRead = CExifReadImpl::NewL( aInData, aCreate, readOption );
       
    98     iExifCore = iExifRead->iExifCore; 
       
    99 
       
   100     if ( !aCreate )
       
   101         {
       
   102         if ( iExifCore->IfdExists( EIfdGps ) )
       
   103             {
       
   104             iExifCore->SetTagDataL( KIdGpsVersion, KGpsVersion );
       
   105             }
       
   106         }
       
   107     iExifCore->SetTagDataL( KIdExifVersion, KExifVersion );
       
   108     iExifCore->SetTagDataL( KIdFlashPixVersion, KFlashPixVersion );
       
   109 
       
   110     // Keep some data from the beginning, middle and end for cross-checking.
       
   111     iCrossCheckLength = aInData.Length();
       
   112     iCrossCheckBegin = TExifCommon::Uint32L( 
       
   113         CONST_CAST( TUint8*, aInData.Ptr() ) );
       
   114     iCrossCheckMiddle = TExifCommon::Uint32L( 
       
   115         CONST_CAST( TUint8*, aInData.Ptr() ) + aInData.Length() / 2 );
       
   116     iCrossCheckEnd = TExifCommon::Uint32L( 
       
   117         CONST_CAST( TUint8*, aInData.Ptr() ) + aInData.Length() - 5 );
       
   118 
       
   119     User::LeaveIfError( iExifCore->Finalize() );
       
   120     }
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // CExifModifyImpl::ConstructL
       
   124 // Symbian 2nd phase constructor can leave.
       
   125 // -----------------------------------------------------------------------------
       
   126 //
       
   127 void CExifModifyImpl::ConstructL()
       
   128     {
       
   129     iExifModifyOption = CExifModify::ENoOptions;
       
   130     iExifRead = CExifReadImpl::NewL();
       
   131     iExifCore = iExifRead->iExifCore; 
       
   132 
       
   133     iExifCore->SetTagDataL( KIdExifVersion, KExifVersion );
       
   134     iExifCore->SetTagDataL( KIdFlashPixVersion, KFlashPixVersion );
       
   135 
       
   136     // No cross-checking since there is no input data.
       
   137     iCrossCheckLength = 0;
       
   138 
       
   139     User::LeaveIfError( iExifCore->Finalize() );
       
   140     }
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // CExifModifyImpl::NewL
       
   144 // Two-phased constructor.
       
   145 // -----------------------------------------------------------------------------
       
   146 //
       
   147 CExifModifyImpl* CExifModifyImpl::NewL( const TDesC8& aExifData, TBool aCreate, TUint aExifModifyOption )
       
   148     {
       
   149     CExifModifyImpl* self = new( ELeave ) CExifModifyImpl();
       
   150     CleanupStack::PushL( self ); 
       
   151     self->ConstructL( aExifData, aCreate, aExifModifyOption );
       
   152     CleanupStack::Pop();
       
   153     return self;
       
   154     }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CExifModifyImpl::NewL
       
   158 // Two-phased constructor.
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 CExifModifyImpl* CExifModifyImpl::NewL()
       
   162     {
       
   163     CExifModifyImpl* self = new( ELeave ) CExifModifyImpl();
       
   164     CleanupStack::PushL( self ); 
       
   165     self->ConstructL();
       
   166     CleanupStack::Pop();
       
   167     return self;
       
   168     }
       
   169 
       
   170 // Destructor
       
   171 CExifModifyImpl::~CExifModifyImpl()
       
   172     {
       
   173     if ( iExifRead )
       
   174         {
       
   175         delete iExifRead;
       
   176         }
       
   177     }
       
   178 
       
   179 // -----------------------------------------------------------------------------
       
   180 // CExifModifyImpl::Reader
       
   181 // Returns a constant pointer to a CExifRead instance that can be used to 
       
   182 // parse the associated Exif image.
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 const CExifRead* CExifModifyImpl::Reader() const
       
   186     {
       
   187     return iExifRead;
       
   188     }
       
   189 
       
   190 // -----------------------------------------------------------------------------
       
   191 // CExifModifyImpl::SetTagL
       
   192 // Inserts/Updates the given tag in the specified IFD structure of the Exif data
       
   193 // -----------------------------------------------------------------------------
       
   194 //
       
   195 void CExifModifyImpl::SetTagL( 
       
   196     TExifIfdType aIfdType, 
       
   197     TExifTagInfo aExifTagInfo, 
       
   198     const TDesC8& aTagData )
       
   199     {
       
   200     if ( !iExifCore )
       
   201         {
       
   202         User::Leave( KErrGeneral );
       
   203         }
       
   204 
       
   205     // Check if ASCII string terminates with NULL character.
       
   206     // If not add NULL.
       
   207     HBufC8* buffer = NULL;
       
   208     if ( ( aExifTagInfo.iDataType == CExifTag::ETagAscii ) && 
       
   209         ( aTagData.Ptr()[aTagData.Length() - 1] ) )
       
   210         {
       
   211         ++aExifTagInfo.iDataCount;
       
   212         buffer = HBufC8::NewL( aTagData.Length() + 1 );
       
   213         buffer->Des().Copy( aTagData );
       
   214         *( CONST_CAST( TUint8*, buffer->Des().Ptr() ) + 
       
   215             aTagData.Length() ) = NULL;
       
   216         buffer->Des().SetLength( aTagData.Length() + 1  );
       
   217         }
       
   218     else
       
   219         {
       
   220         buffer = aTagData.AllocL();
       
   221         }
       
   222     CleanupStack::PushL( buffer );
       
   223     CExifTagImpl* tag = NULL;
       
   224     if ( iExifModifyOption & CExifModify::ENoTagChecking )
       
   225         {
       
   226         tag = CExifTagImpl::NewL( aExifTagInfo, buffer, EFalse );
       
   227         }
       
   228     else
       
   229         {
       
   230         tag = CExifTagImpl::NewL( aExifTagInfo, buffer, ETrue );
       
   231         }
       
   232     CleanupStack::Pop( buffer );
       
   233     CleanupStack::PushL( tag );
       
   234 
       
   235     switch ( tag->TagInfo().iId )
       
   236         {
       
   237         case KIdExifIfdPointer:
       
   238         case KIdGpsIfdPointer:
       
   239         case KIdIntOpIfdPointer:
       
   240         case KIdJpegInterchangeFormat:
       
   241         case KIdJpegInterchangeFormatLength:
       
   242         case KIdExifVersion:
       
   243         case KIdGpsVersion:
       
   244         case KIdFlashPixVersion:
       
   245         case KIdCompression:
       
   246             User::Leave( KErrNotSupported );
       
   247         default:
       
   248             break;
       
   249         }
       
   250 
       
   251     if ( iExifModifyOption & CExifModify::ENoTagChecking )
       
   252         {
       
   253         iExifCore->InsertTagL( aIfdType, tag, EFalse );
       
   254         }
       
   255     else
       
   256         {
       
   257         iExifCore->InsertTagL( aIfdType, tag, ETrue );
       
   258         }
       
   259     CleanupStack::Pop( tag );
       
   260     if ( aIfdType == EIfdGps )
       
   261         {
       
   262         iExifCore->SetTagDataL( KIdGpsVersion, KGpsVersion );
       
   263         }
       
   264     TInt error = iExifCore->Finalize();
       
   265     if ( error )
       
   266         {
       
   267         iExifCore->DeleteTag( aIfdType, aExifTagInfo.iId );
       
   268         User::Leave( error );
       
   269         }
       
   270     }
       
   271 
       
   272 // -----------------------------------------------------------------------------
       
   273 // CExifModifyImpl::DeleteTag
       
   274 // Removes the tag with the given tag ID from the specified IFD structure in 
       
   275 // the Exif data.
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 TInt CExifModifyImpl::DeleteTag( TExifIfdType aIfdType, TUint16 aTagId )
       
   279     {
       
   280     if ( !iExifCore )
       
   281         {
       
   282         return KErrGeneral;
       
   283         }
       
   284 
       
   285     switch ( aTagId )
       
   286         {
       
   287         case KIdExifIfdPointer:
       
   288         case KIdGpsIfdPointer:
       
   289         case KIdIntOpIfdPointer:
       
   290         case KIdJpegInterchangeFormat:
       
   291         case KIdJpegInterchangeFormatLength:
       
   292         case KIdExifVersion:
       
   293         case KIdGpsVersion:
       
   294         case KIdFlashPixVersion:
       
   295         case KIdCompression:
       
   296             return KErrNotSupported;
       
   297         default:
       
   298             if ( !TExifCommon::IsValidTagId( aTagId ) )
       
   299                 {
       
   300                 return KErrNotSupported;
       
   301                 }
       
   302         }
       
   303 
       
   304     TInt error = iExifCore->DeleteTag( aIfdType, aTagId );
       
   305     if ( error )
       
   306         {
       
   307         return error;
       
   308         }
       
   309     return iExifCore->Finalize();
       
   310     }
       
   311 
       
   312 // -----------------------------------------------------------------------------
       
   313 // CExifModifyImpl::DeleteIfd
       
   314 // Removes the specified IFD structure and all its tags from the Exif data.
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 TInt CExifModifyImpl::DeleteIfd( TExifIfdType aIfdType )
       
   318     {
       
   319     if ( !iExifCore )
       
   320         {
       
   321         return KErrGeneral;
       
   322         }
       
   323 
       
   324     if ( ( aIfdType == EIfd0 ) || ( aIfdType == EIfdExif ) )
       
   325         {
       
   326         return KErrArgument;
       
   327         }
       
   328 
       
   329     TInt error = iExifCore->DeleteIfd( aIfdType );
       
   330     if ( error )
       
   331         {
       
   332         return error;
       
   333         }
       
   334     return iExifCore->Finalize();
       
   335     }
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // CExifModifyImpl::SetThumbnailL
       
   339 // Inserts/Updates the given thumbnail Jpeg image data into the 1st IFD 
       
   340 // structure in the Exif data.
       
   341 // -----------------------------------------------------------------------------
       
   342 //
       
   343 void CExifModifyImpl::SetThumbnailL( const TDesC8& aThumbnailData )
       
   344     {
       
   345     if ( !iExifCore )
       
   346         {
       
   347         User::Leave( KErrGeneral );
       
   348         }
       
   349     TDesC8* data = aThumbnailData.AllocL();
       
   350     CleanupStack::PushL( data );
       
   351     iExifCore->InsertThumbnailL( data );
       
   352     CleanupStack::Pop( data );
       
   353     TInt error = iExifCore->Finalize();
       
   354     if ( error )
       
   355         {
       
   356         iExifCore->RemoveThumbnail();
       
   357         User::Leave( error );
       
   358         }
       
   359     }
       
   360 
       
   361 // -----------------------------------------------------------------------------
       
   362 // CExifModifyImpl::RemoveThumbnail
       
   363 // Removes the thumbnail Jpeg image data from the 1st IFD structure in the Exif 
       
   364 // data.
       
   365 // -----------------------------------------------------------------------------
       
   366 //
       
   367 TInt CExifModifyImpl::RemoveThumbnail()
       
   368     {
       
   369     if ( !iExifCore )
       
   370         {
       
   371         return KErrGeneral;
       
   372         }
       
   373     
       
   374     TInt error = iExifCore->RemoveThumbnail();
       
   375     if ( error )
       
   376         {
       
   377         return error;
       
   378         }
       
   379     return iExifCore->Finalize();
       
   380     }
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // CExifModifyImpl::WriteDataL
       
   384 // Flushes the Exif data into the given data buffer, and releases the internal 
       
   385 // structures.
       
   386 // -----------------------------------------------------------------------------
       
   387 //
       
   388 HBufC8* CExifModifyImpl::WriteDataL( const TDesC8& aInData )
       
   389     {
       
   390     if ( !iExifCore )
       
   391         {
       
   392         User::Leave( KErrGeneral );
       
   393         }
       
   394 
       
   395     // Input Jpeg or Exif data is provided at instantiation (or not)
       
   396     TBool inputProvidedEarly = iCrossCheckLength; 
       
   397 
       
   398     // Input Jpeg or Exif data is provided for this function (or not)
       
   399     TBool inputProvidedLate = aInData.Length();
       
   400 
       
   401     if ( inputProvidedEarly )
       
   402         {
       
   403         if ( inputProvidedLate )
       
   404             {
       
   405             // Cross-check. Check if content of aInData is identical with 
       
   406             // the descriptor provided during instantiation.
       
   407             if ( aInData.Length() != iCrossCheckLength )
       
   408                 {
       
   409                 User::Leave(KErrArgument);
       
   410                 }
       
   411             TUint32 crossCheck = TExifCommon::Uint32L( 
       
   412                 CONST_CAST( TUint8*, aInData.Ptr() ) );
       
   413             if ( crossCheck != iCrossCheckBegin )
       
   414                 {
       
   415                 User::Leave(KErrArgument);
       
   416                 }
       
   417             crossCheck = TExifCommon::Uint32L( 
       
   418                 CONST_CAST( TUint8*, aInData.Ptr() + aInData.Length() / 2 ) );
       
   419             if ( crossCheck != iCrossCheckMiddle )
       
   420                 {
       
   421                 User::Leave(KErrArgument);
       
   422                 }
       
   423             crossCheck = TExifCommon::Uint32L( 
       
   424                 CONST_CAST( TUint8*, aInData.Ptr() + aInData.Length() - 5 ) );
       
   425             if ( crossCheck != iCrossCheckEnd )
       
   426                 {
       
   427                 User::Leave(KErrArgument);
       
   428                 }
       
   429             }
       
   430         }
       
   431     else
       
   432         {
       
   433         if ( inputProvidedLate )
       
   434             {
       
   435             iExifRead->ParseJpegDataL( aInData );
       
   436             }
       
   437         }
       
   438 
       
   439     User::LeaveIfError( iExifCore->Finalize() );    
       
   440 
       
   441     if ( !iExifCore->IsValid() )
       
   442         {
       
   443         User::Leave( KErrNotReady );
       
   444         }
       
   445 
       
   446     TUint totalSize = 0;
       
   447     if ( inputProvidedLate )
       
   448         {
       
   449         iExifCore->SetDataStartPtr( CONST_CAST( TUint8*, aInData.Ptr() ) );
       
   450         totalSize = iExifCore->TotalSize();
       
   451         }
       
   452     else
       
   453         {
       
   454         totalSize = iExifCore->App1Size() + 2;
       
   455         }
       
   456     // Allocation amount is even for 2-byte alignment
       
   457     HBufC8* exifData = HBufC8::NewLC( totalSize + ( totalSize % 2 ) );
       
   458     exifData->Des().SetLength( totalSize + ( totalSize % 2 ) );
       
   459     TUint pos = 0;
       
   460     if ( inputProvidedLate )
       
   461         {
       
   462         iExifCore->WriteJpegHeaderL( exifData, pos );
       
   463         iExifCore->WriteExifDataL( exifData, pos );
       
   464         TPtr8 ptr( CONST_CAST( TUint8*, exifData->Ptr() ) + pos, 
       
   465             iExifCore->JpegSize() );
       
   466         User::LeaveIfError( iExifCore->GetJpegData( ptr ) );
       
   467         }
       
   468     else
       
   469         {
       
   470         iExifCore->WriteExifDataL( exifData, pos );
       
   471         }
       
   472     exifData->Des().SetLength( totalSize );
       
   473     CleanupStack::Pop();
       
   474     return exifData;
       
   475     }
       
   476 
       
   477 // -----------------------------------------------------------------------------
       
   478 // CExifModifyImpl::SetImageDescriptionL
       
   479 // Inserts/Updates given ImageDescription in the Exif data.
       
   480 // -----------------------------------------------------------------------------
       
   481 //
       
   482 void CExifModifyImpl::SetImageDescriptionL( const TDesC8& aImageDescription )
       
   483     {
       
   484     if ( !iExifCore )
       
   485         {
       
   486         User::Leave( KErrGeneral );
       
   487         }
       
   488 
       
   489     iExifCore->SetTagDataL( KIdImageDescription, aImageDescription );
       
   490     }
       
   491 
       
   492 // -----------------------------------------------------------------------------
       
   493 // CExifModifyImpl::SetMakeL
       
   494 // Inserts/Updates given Make in the Exif data.
       
   495 // -----------------------------------------------------------------------------
       
   496 //
       
   497 void CExifModifyImpl::SetMakeL( const TDesC8& aMake )
       
   498     {
       
   499     if ( !iExifCore )
       
   500         {
       
   501         User::Leave( KErrGeneral );
       
   502         }
       
   503 
       
   504     iExifCore->SetTagDataL( KIdMake, aMake );
       
   505     }
       
   506 
       
   507 // -----------------------------------------------------------------------------
       
   508 // CExifModifyImpl::SetModelL
       
   509 // Inserts/Updates given Model in the Exif data.
       
   510 // -----------------------------------------------------------------------------
       
   511 //
       
   512 void CExifModifyImpl::SetModelL( const TDesC8& aModel )
       
   513     {
       
   514     if ( !iExifCore )
       
   515         {
       
   516         User::Leave( KErrGeneral );
       
   517         }
       
   518 
       
   519     iExifCore->SetTagDataL( KIdModel, aModel );
       
   520     }
       
   521 
       
   522 // -----------------------------------------------------------------------------
       
   523 // CExifModifyImpl::SetOrientationL
       
   524 // Inserts/Updates given Orientation in the Exif data.
       
   525 // -----------------------------------------------------------------------------
       
   526 //
       
   527 void CExifModifyImpl::SetOrientationL( TUint16 aOrientation )
       
   528     {
       
   529     if ( !iExifCore )
       
   530         {
       
   531         User::Leave( KErrGeneral );
       
   532         }
       
   533 
       
   534     iExifCore->SetTagDataL( KIdOrientation, aOrientation );
       
   535     }
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // CExifModifyImpl::SetXResolutionL
       
   539 // Inserts/Updates given X Resolution in the Exif data.
       
   540 // -----------------------------------------------------------------------------
       
   541 //
       
   542 void CExifModifyImpl::SetXResolutionL( 
       
   543     TUint32 aXResolution1, 
       
   544     TUint32 aXResolution2 )
       
   545     {
       
   546     if ( !iExifCore )
       
   547         {
       
   548         User::Leave( KErrGeneral );
       
   549         }
       
   550 
       
   551     iExifCore->SetTagDataL( KIdXResolution, aXResolution1, aXResolution2 );
       
   552     }
       
   553 
       
   554 // -----------------------------------------------------------------------------
       
   555 // CExifModifyImpl::SetYResolutionL
       
   556 // Inserts/Updates given Y Resolution in the Exif data.
       
   557 // -----------------------------------------------------------------------------
       
   558 //
       
   559 void CExifModifyImpl::SetYResolutionL( 
       
   560     TUint32 aYResolution1, 
       
   561     TUint32 aYResolution2 )
       
   562     {
       
   563     if ( !iExifCore )
       
   564         {
       
   565         User::Leave( KErrGeneral );
       
   566         }
       
   567 
       
   568     iExifCore->SetTagDataL( KIdYResolution, aYResolution1, aYResolution2 );
       
   569     }
       
   570 
       
   571 // -----------------------------------------------------------------------------
       
   572 // CExifModifyImpl::SetResolutionUnitL
       
   573 // Inserts/Updates given Resolution Unit in the Exif data.
       
   574 // -----------------------------------------------------------------------------
       
   575 //
       
   576 void CExifModifyImpl::SetResolutionUnitL( TUint16 aResolutionUnit )
       
   577     {
       
   578     if ( !iExifCore )
       
   579         {
       
   580         User::Leave( KErrGeneral );
       
   581         }
       
   582 
       
   583     iExifCore->SetTagDataL( KIdResolutionUnit, aResolutionUnit );
       
   584     }
       
   585 
       
   586 // -----------------------------------------------------------------------------
       
   587 // CExifModifyImpl::SetTransferFunctionL
       
   588 // Inserts/Updates given Transfer Function in the Exif data.
       
   589 // -----------------------------------------------------------------------------
       
   590 //
       
   591 void CExifModifyImpl::SetTransferFunctionL( const TDesC8& aTransferFunction )
       
   592     {
       
   593     if ( !iExifCore )
       
   594         {
       
   595         User::Leave( KErrGeneral );
       
   596         }
       
   597 
       
   598     iExifCore->SetTagDataL( KIdTransferFunction, aTransferFunction );
       
   599     }
       
   600 
       
   601 // -----------------------------------------------------------------------------
       
   602 // CExifModifyImpl::SetDateTimeL
       
   603 // Inserts/Updates given Date Time in the Exif data.
       
   604 // -----------------------------------------------------------------------------
       
   605 //
       
   606 void CExifModifyImpl::SetDateTimeL( const TDesC8& aDateTime )
       
   607     {
       
   608     if ( !iExifCore )
       
   609         {
       
   610         User::Leave( KErrGeneral );
       
   611         }
       
   612 
       
   613     iExifCore->SetTagDataL( KIdDateTime, aDateTime );
       
   614     }
       
   615 
       
   616 // -----------------------------------------------------------------------------
       
   617 // CExifModifyImpl::SetYCbCrPositioningL
       
   618 // Inserts/Updates given YCbCr Positioning in the Exif data.
       
   619 // -----------------------------------------------------------------------------
       
   620 //
       
   621 void CExifModifyImpl::SetYCbCrPositioningL( TUint16 aYCbCrPositioning )
       
   622     {
       
   623     if ( !iExifCore )
       
   624         {
       
   625         User::Leave( KErrGeneral );
       
   626         }
       
   627 
       
   628     iExifCore->SetTagDataL( KIdYCbCrPositioning, aYCbCrPositioning );
       
   629     }
       
   630 
       
   631 // -----------------------------------------------------------------------------
       
   632 // CExifModifyImpl::SetSoftwareL
       
   633 // Inserts/Updates given Software in the Exif data.
       
   634 // -----------------------------------------------------------------------------
       
   635 //
       
   636 void CExifModifyImpl::SetSoftwareL( const TDesC8& aSoftware )
       
   637     {
       
   638     if ( !iExifCore )
       
   639         {
       
   640         User::Leave( KErrGeneral );
       
   641         }
       
   642 
       
   643     iExifCore->SetTagDataL( KIdSoftware, aSoftware );
       
   644     }
       
   645 
       
   646 // -----------------------------------------------------------------------------
       
   647 // CExifModifyImpl::SetCopyrightL
       
   648 // Inserts/Updates given Copyright in the Exif data.
       
   649 // -----------------------------------------------------------------------------
       
   650 //
       
   651 void CExifModifyImpl::SetCopyrightL( const TDesC8& aCopyright )
       
   652     {
       
   653     if ( !iExifCore )
       
   654         {
       
   655         User::Leave( KErrGeneral );
       
   656         }
       
   657 
       
   658     iExifCore->SetTagDataL( KIdCopyright, aCopyright );
       
   659     }
       
   660 
       
   661 // -----------------------------------------------------------------------------
       
   662 // CExifModifyImpl::SetExposureTimeL
       
   663 // Inserts/Updates given Exposure Time in the Exif data.
       
   664 // -----------------------------------------------------------------------------
       
   665 //
       
   666 void CExifModifyImpl::SetExposureTimeL( 
       
   667     TUint32 aExposureTime1, 
       
   668     TUint32 aExposureTime2 )
       
   669     {
       
   670     if ( !iExifCore )
       
   671         {
       
   672         User::Leave( KErrGeneral );
       
   673         }
       
   674 
       
   675     iExifCore->SetTagDataL( KIdExposureTime, aExposureTime1, aExposureTime2 );
       
   676     }
       
   677 
       
   678 // -----------------------------------------------------------------------------
       
   679 // CExifModifyImpl::SetComponentsConfigurationL
       
   680 // Inserts/Updates given Components Configuration in the Exif data.
       
   681 // -----------------------------------------------------------------------------
       
   682 //
       
   683 void CExifModifyImpl::SetComponentsConfigurationL( 
       
   684     TUint8 aFirstComponent, TUint8 aSecondComponent, 
       
   685     TUint8 aThirdComponent, TUint8 aFourthComponent ) 
       
   686     {
       
   687     if ( !iExifCore )
       
   688         {
       
   689         User::Leave( KErrGeneral );
       
   690         }
       
   691 
       
   692     TUint32 componentsConfiguration = ( aFourthComponent << 24 ) + 
       
   693         ( aThirdComponent << 16 ) + ( aSecondComponent << 8 ) + aFirstComponent;
       
   694     iExifCore->SetTagDataL( KIdComponentsConfiguration, 
       
   695         componentsConfiguration );
       
   696     }
       
   697 
       
   698 // -----------------------------------------------------------------------------
       
   699 // CExifModifyImpl::SetFlashL
       
   700 // Inserts/Updates given Flash in the Exif data.
       
   701 // -----------------------------------------------------------------------------
       
   702 //
       
   703 void CExifModifyImpl::SetFlashL( TUint16 aFlash )
       
   704     {
       
   705     if ( !iExifCore )
       
   706         {
       
   707         User::Leave( KErrGeneral );
       
   708         }
       
   709 
       
   710     iExifCore->SetTagDataL( KIdFlash, aFlash );
       
   711     }
       
   712 
       
   713 // -----------------------------------------------------------------------------
       
   714 // CExifModifyImpl::SetColorSpaceL
       
   715 // Inserts/Updates given Color Space in the Exif data.
       
   716 // -----------------------------------------------------------------------------
       
   717 //
       
   718 void CExifModifyImpl::SetColorSpaceL( TUint16 aColorSpace )
       
   719     {
       
   720     if ( !iExifCore )
       
   721         {
       
   722         User::Leave( KErrGeneral );
       
   723         }
       
   724 
       
   725     iExifCore->SetTagDataL( KIdColorSpace, aColorSpace );
       
   726     }
       
   727 
       
   728 // -----------------------------------------------------------------------------
       
   729 // CExifModifyImpl::SetPixelXDimensionL
       
   730 // Inserts/Updates given Pixel X Dimension in the Exif data.
       
   731 // -----------------------------------------------------------------------------
       
   732 //
       
   733 void CExifModifyImpl::SetPixelXDimensionL( TUint32 aPixelXDimension )
       
   734     {
       
   735     if ( !iExifCore )
       
   736         {
       
   737         User::Leave( KErrGeneral );
       
   738         }
       
   739 
       
   740     iExifCore->SetTagDataL( KIdPixelXDimension, aPixelXDimension );
       
   741     }
       
   742 
       
   743 // -----------------------------------------------------------------------------
       
   744 // CExifModifyImpl::SetPixelYDimensionL
       
   745 // Inserts/Updates given Pixel Y Dimension in the Exif data.
       
   746 // -----------------------------------------------------------------------------
       
   747 //
       
   748 void CExifModifyImpl::SetPixelYDimensionL( TUint32 aPixelYDimension )
       
   749     {
       
   750     if ( !iExifCore )
       
   751         {
       
   752         User::Leave( KErrGeneral );
       
   753         }
       
   754 
       
   755     iExifCore->SetTagDataL( KIdPixelYDimension, aPixelYDimension );
       
   756     }
       
   757 
       
   758 // -----------------------------------------------------------------------------
       
   759 // CExifModifyImpl::SetExposureModeL
       
   760 // Inserts/Updates given Exposure Mode in the Exif data.
       
   761 // -----------------------------------------------------------------------------
       
   762 //
       
   763 void CExifModifyImpl::SetExposureModeL( TUint16 aExposureMode )
       
   764     {
       
   765     if ( !iExifCore )
       
   766         {
       
   767         User::Leave( KErrGeneral );
       
   768         }
       
   769 
       
   770     iExifCore->SetTagDataL( KIdExposureMode, aExposureMode );
       
   771     }
       
   772 
       
   773 // -----------------------------------------------------------------------------
       
   774 // CExifModifyImpl::SetWhiteBalanceL
       
   775 // Inserts/Updates given White Balance in the Exif data.
       
   776 // -----------------------------------------------------------------------------
       
   777 //
       
   778 void CExifModifyImpl::SetWhiteBalanceL( TUint16 aWhiteBalance )
       
   779     {
       
   780     if ( !iExifCore )
       
   781         {
       
   782         User::Leave( KErrGeneral );
       
   783         }
       
   784 
       
   785     iExifCore->SetTagDataL( KIdWhiteBalance, aWhiteBalance );
       
   786     }
       
   787 
       
   788 // -----------------------------------------------------------------------------
       
   789 // CExifModifyImpl::SetSceneCaptureTypeL
       
   790 // Inserts/Updates given Scene Capture Type in the Exif data.
       
   791 // -----------------------------------------------------------------------------
       
   792 //
       
   793 void CExifModifyImpl::SetSceneCaptureTypeL( TUint16 aSceneCaptureType )
       
   794     {
       
   795     if ( !iExifCore )
       
   796         {
       
   797         User::Leave( KErrGeneral );
       
   798         }
       
   799 
       
   800     iExifCore->SetTagDataL( KIdSceneCaptureType, aSceneCaptureType );
       
   801     }
       
   802 
       
   803 // -----------------------------------------------------------------------------
       
   804 // CExifModifyImpl::SetExposureProgramL
       
   805 // Inserts/Updates given Exposure Program in the Exif data.
       
   806 // -----------------------------------------------------------------------------
       
   807 //
       
   808 void CExifModifyImpl::SetExposureProgramL( TUint16 aExposureProgram )
       
   809     {
       
   810     if ( !iExifCore )
       
   811         {
       
   812         User::Leave( KErrGeneral );
       
   813         }
       
   814 
       
   815     iExifCore->SetTagDataL( KIdExposureProgram, aExposureProgram );
       
   816     }
       
   817 
       
   818 // -----------------------------------------------------------------------------
       
   819 // CExifModifyImpl::SetIsoSpeedRatingsL
       
   820 // Inserts/Updates given Iso Speed Ratings in the Exif data.
       
   821 // -----------------------------------------------------------------------------
       
   822 //
       
   823 void CExifModifyImpl::SetIsoSpeedRatingsL( const TDesC8& aIsoSpeedRatings )
       
   824     {
       
   825     if ( !iExifCore )
       
   826         {
       
   827         User::Leave( KErrGeneral );
       
   828         }
       
   829 
       
   830     iExifCore->SetTagDataL( KIdIsoSpeedRatings, aIsoSpeedRatings );
       
   831     }
       
   832 
       
   833 // -----------------------------------------------------------------------------
       
   834 // CExifModifyImpl::SetDateTimeOriginalL
       
   835 // Inserts/Updates given Date Time Original in the Exif data.
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 void CExifModifyImpl::SetDateTimeOriginalL( const TDesC8& aDateTimeOriginal )
       
   839     {
       
   840     if ( !iExifCore )
       
   841         {
       
   842         User::Leave( KErrGeneral );
       
   843         }
       
   844 
       
   845     iExifCore->SetTagDataL( KIdDateTimeOriginal, aDateTimeOriginal );
       
   846     }
       
   847 
       
   848 // -----------------------------------------------------------------------------
       
   849 // CExifModifyImpl::SetDateTimeDigitizedL
       
   850 // Inserts/Updates given Date Time Digitized in the Exif data.
       
   851 // -----------------------------------------------------------------------------
       
   852 //
       
   853 void CExifModifyImpl::SetDateTimeDigitizedL( const TDesC8& aDateTimeDigitized )
       
   854     {
       
   855     if ( !iExifCore )
       
   856         {
       
   857         User::Leave( KErrGeneral );
       
   858         }
       
   859 
       
   860     iExifCore->SetTagDataL( KIdDateTimeDigitized, aDateTimeDigitized );
       
   861     }
       
   862 
       
   863 // -----------------------------------------------------------------------------
       
   864 // CExifModifyImpl::SetApertureValueL
       
   865 // Inserts/Updates given Aperture Value in the Exif data.
       
   866 // -----------------------------------------------------------------------------
       
   867 //
       
   868 void CExifModifyImpl::SetApertureValueL( 
       
   869     TUint32 aApertureValue1, 
       
   870     TUint32 aApertureValue2 )
       
   871     {
       
   872     if ( !iExifCore )
       
   873         {
       
   874         User::Leave( KErrGeneral );
       
   875         }
       
   876 
       
   877     iExifCore->SetTagDataL( 
       
   878         KIdApertureValue, aApertureValue1, aApertureValue2 );
       
   879     }
       
   880 
       
   881 // -----------------------------------------------------------------------------
       
   882 // CExifModifyImpl::SetExposureBiasValueL
       
   883 // Inserts/Updates given Exposure Bias Value in the Exif data.
       
   884 // -----------------------------------------------------------------------------
       
   885 //
       
   886 void CExifModifyImpl::SetExposureBiasValueL(
       
   887     TInt32 aExposureBiasValue1, 
       
   888     TInt32 aExposureBiasValue2 )
       
   889     {
       
   890     if ( !iExifCore )
       
   891         {
       
   892         User::Leave( KErrGeneral );
       
   893         }
       
   894 
       
   895     iExifCore->SetTagDataL( KIdExposureBiasValue, 
       
   896         aExposureBiasValue1, aExposureBiasValue2 );
       
   897     }
       
   898 
       
   899 // -----------------------------------------------------------------------------
       
   900 // CExifModifyImpl::SetMeteringModeL
       
   901 // Inserts/Updates given Metering Mode in the Exif data.
       
   902 // -----------------------------------------------------------------------------
       
   903 //
       
   904 void CExifModifyImpl::SetMeteringModeL( TUint16 aMeteringMode )
       
   905     {
       
   906     if ( !iExifCore )
       
   907         {
       
   908         User::Leave( KErrGeneral );
       
   909         }
       
   910 
       
   911     iExifCore->SetTagDataL( KIdMeteringMode, aMeteringMode );
       
   912     }
       
   913 
       
   914 // -----------------------------------------------------------------------------
       
   915 // CExifModifyImpl::SetLightSourceL
       
   916 // Inserts/Updates given Light Source in the Exif data.
       
   917 // -----------------------------------------------------------------------------
       
   918 //
       
   919 void CExifModifyImpl::SetLightSourceL( TUint16 aLightSource )
       
   920     {
       
   921     if ( !iExifCore )
       
   922         {
       
   923         User::Leave( KErrGeneral );
       
   924         }
       
   925 
       
   926     iExifCore->SetTagDataL( KIdLightSource, aLightSource );
       
   927     }
       
   928 
       
   929 // -----------------------------------------------------------------------------
       
   930 // CExifModifyImpl::SetMakerNoteL
       
   931 // Inserts/Updates given Maker Note in the Exif data.
       
   932 // -----------------------------------------------------------------------------
       
   933 //
       
   934 void CExifModifyImpl::SetMakerNoteL( const TDesC8& aMakerNote )
       
   935     {
       
   936     if ( !iExifCore )
       
   937         {
       
   938         User::Leave( KErrGeneral );
       
   939         }
       
   940 
       
   941     iExifCore->SetTagDataL( KIdMakerNote, aMakerNote );
       
   942     }
       
   943 
       
   944 // -----------------------------------------------------------------------------
       
   945 // CExifModifyImpl::SetUserCommentL
       
   946 // Inserts/Updates given User Comment in the Exif data.
       
   947 // -----------------------------------------------------------------------------
       
   948 //
       
   949 void CExifModifyImpl::SetUserCommentL( const TDesC8& aUserComment )
       
   950     {
       
   951     if ( !iExifCore )
       
   952         {
       
   953         User::Leave( KErrGeneral );
       
   954         }
       
   955     iExifCore->SetTagDataL( KIdUserComment, aUserComment );
       
   956     }
       
   957 
       
   958 // -----------------------------------------------------------------------------
       
   959 // CExifModifyImpl::SetRelatedSoundFileL
       
   960 // Inserts/Updates given Related Sound File in the Exif data.
       
   961 // -----------------------------------------------------------------------------
       
   962 //
       
   963 void CExifModifyImpl::SetRelatedSoundFileL( const TDesC8& aRelatedSoundFile )
       
   964     {
       
   965     if ( !iExifCore )
       
   966         {
       
   967         User::Leave( KErrGeneral );
       
   968         }
       
   969 
       
   970     iExifCore->SetTagDataL( KIdRelatedSoundFile, aRelatedSoundFile );
       
   971     }
       
   972 
       
   973 // -----------------------------------------------------------------------------
       
   974 // CExifModifyImpl::SetFileSourceL
       
   975 // Inserts/Updates given FileSource in the Exif data.
       
   976 // -----------------------------------------------------------------------------
       
   977 //
       
   978 void CExifModifyImpl::SetFileSourceL(TInt8 aFileSource )
       
   979     {
       
   980     if ( !iExifCore )
       
   981         {
       
   982         User::Leave( KErrGeneral );
       
   983         }
       
   984 
       
   985     iExifCore->SetTagDataL( KIdFileSource, aFileSource );
       
   986     }
       
   987 
       
   988 // -----------------------------------------------------------------------------
       
   989 // CExifModifyImpl::SetDigitalZoomRatioL
       
   990 // Inserts/Updates given Digital Zoom Ratio in the Exif data.
       
   991 // -----------------------------------------------------------------------------
       
   992 //
       
   993 void CExifModifyImpl::SetDigitalZoomRatioL( 
       
   994     TUint32 aDigitalZoomRatio1, 
       
   995     TUint32 aDigitalZoomRatio2 )
       
   996     {
       
   997     if ( !iExifCore )
       
   998         {
       
   999         User::Leave( KErrGeneral );
       
  1000         }
       
  1001 
       
  1002     iExifCore->SetTagDataL( KIdDigitalZoomRatio, 
       
  1003         aDigitalZoomRatio1, aDigitalZoomRatio2 );
       
  1004     }
       
  1005 
       
  1006 // -----------------------------------------------------------------------------
       
  1007 // CExifModifyImpl::SetContrastL
       
  1008 // Inserts/Updates given Contrast in the Exif data.
       
  1009 // -----------------------------------------------------------------------------
       
  1010 //
       
  1011 void CExifModifyImpl::SetContrastL( TUint16 aContrast )
       
  1012     {
       
  1013     if ( !iExifCore )
       
  1014         {
       
  1015         User::Leave( KErrGeneral );
       
  1016         }
       
  1017 
       
  1018     iExifCore->SetTagDataL( KIdContrast, aContrast );
       
  1019     }
       
  1020 
       
  1021 // -----------------------------------------------------------------------------
       
  1022 // CExifModifyImpl::SetSaturationL
       
  1023 // Inserts/Updates given Saturation in the Exif data.
       
  1024 // -----------------------------------------------------------------------------
       
  1025 //
       
  1026 void CExifModifyImpl::SetSaturationL( TUint16 aSaturation )
       
  1027     {
       
  1028     if ( !iExifCore )
       
  1029         {
       
  1030         User::Leave( KErrGeneral );
       
  1031         }
       
  1032 
       
  1033     iExifCore->SetTagDataL( KIdSaturation, aSaturation );
       
  1034     }
       
  1035 
       
  1036 // -----------------------------------------------------------------------------
       
  1037 // CExifModifyImpl::SetSharpnessL
       
  1038 // Inserts/Updates given Sharpness in the Exif data.
       
  1039 // -----------------------------------------------------------------------------
       
  1040 //
       
  1041 void CExifModifyImpl::SetSharpnessL( TUint16 aSharpness )
       
  1042     {
       
  1043     if ( !iExifCore )
       
  1044         {
       
  1045         User::Leave( KErrGeneral );
       
  1046         }
       
  1047 
       
  1048     iExifCore->SetTagDataL( KIdSharpness, aSharpness );
       
  1049     }
       
  1050 
       
  1051 // -----------------------------------------------------------------------------
       
  1052 // CExifModifyImpl::SetThumbnailXResolutionL
       
  1053 // Inserts/Updates given Thumbnail X Resolution in the Exif data.
       
  1054 // -----------------------------------------------------------------------------
       
  1055 //
       
  1056 void CExifModifyImpl::SetThumbnailXResolutionL( 
       
  1057     TUint32 aXResolution1, 
       
  1058     TUint32 aXResolution2 )
       
  1059     {
       
  1060     if ( !iExifCore )
       
  1061         {
       
  1062         User::Leave( KErrGeneral );
       
  1063         }
       
  1064 
       
  1065     iExifCore->SetThumbnailTagDataL(KIdXResolution, 
       
  1066         aXResolution1, aXResolution2 );
       
  1067     }
       
  1068 
       
  1069 // -----------------------------------------------------------------------------
       
  1070 // CExifModifyImpl::SetThumbnailYResolutionL
       
  1071 // Inserts/Updates given Thumbnail Y Resolution in the Exif data.
       
  1072 // -----------------------------------------------------------------------------
       
  1073 //
       
  1074 void CExifModifyImpl::SetThumbnailYResolutionL( 
       
  1075     TUint32 aYResolution1, 
       
  1076     TUint32 aYResolution2 )
       
  1077     {
       
  1078     if ( !iExifCore )
       
  1079         {
       
  1080         User::Leave( KErrGeneral );
       
  1081         }
       
  1082 
       
  1083     iExifCore->SetThumbnailTagDataL(KIdYResolution, 
       
  1084         aYResolution1, aYResolution2 );
       
  1085     }
       
  1086 
       
  1087 // -----------------------------------------------------------------------------
       
  1088 // CExifModifyImpl::SetThumbnailResolutionUnitL
       
  1089 // Inserts/Updates given Thumbnail Resolution Unit in the Exif data.
       
  1090 // -----------------------------------------------------------------------------
       
  1091 //
       
  1092 void CExifModifyImpl::SetThumbnailResolutionUnitL( TUint16 aResolutionUnit )
       
  1093     {
       
  1094     if ( !iExifCore )
       
  1095         {
       
  1096         User::Leave( KErrGeneral );
       
  1097         }
       
  1098 
       
  1099     iExifCore->SetThumbnailTagDataL(KIdResolutionUnit, aResolutionUnit );
       
  1100     }
       
  1101 
       
  1102 // -----------------------------------------------------------------------------
       
  1103 // CExifModifyImpl::SetShutterSpeedValueL
       
  1104 // Inserts/Updates given Shutter Speed Value in the Exif data.
       
  1105 // -----------------------------------------------------------------------------
       
  1106 //
       
  1107 void CExifModifyImpl::SetShutterSpeedValueL( 
       
  1108     TInt32 aShutterSpeedValue1, 
       
  1109     TInt32 aShutterSpeedValue2 )
       
  1110     {
       
  1111     if ( !iExifCore )
       
  1112         {
       
  1113         User::Leave( KErrGeneral );
       
  1114         }
       
  1115 
       
  1116     iExifCore->SetTagDataL(KIdShutterSpeedValue, 
       
  1117         aShutterSpeedValue1, aShutterSpeedValue2 );
       
  1118     }
       
  1119 
       
  1120 // -----------------------------------------------------------------------------
       
  1121 // CExifModifyImpl::SetBrightnessValueL
       
  1122 // Inserts/Updates given Brightness Value in the Exif data.
       
  1123 // -----------------------------------------------------------------------------
       
  1124 //
       
  1125 void CExifModifyImpl::SetBrightnessValueL( 
       
  1126     TInt32 aBrightnessValue1, 
       
  1127     TInt32 aBrightnessValue2 )
       
  1128     {
       
  1129     if ( !iExifCore )
       
  1130         {
       
  1131         User::Leave( KErrGeneral );
       
  1132         }
       
  1133 
       
  1134     iExifCore->SetTagDataL(KIdBrightnessValue, 
       
  1135         aBrightnessValue1, aBrightnessValue2 );
       
  1136     }
       
  1137 
       
  1138 // -----------------------------------------------------------------------------
       
  1139 // CExifModifyImpl::SetCustomRenderedL
       
  1140 // Inserts/Updates given Custom Rendered in the Exif data.
       
  1141 // -----------------------------------------------------------------------------
       
  1142 //
       
  1143 void CExifModifyImpl::SetCustomRenderedL( TUint16 aCustomRendered )
       
  1144     {
       
  1145     if ( !iExifCore )
       
  1146         {
       
  1147         User::Leave( KErrGeneral );
       
  1148         }
       
  1149 
       
  1150     iExifCore->SetTagDataL( KIdCustomRendered, aCustomRendered );
       
  1151     }
       
  1152 
       
  1153 // -----------------------------------------------------------------------------
       
  1154 // CExifModifyImpl::SetGainControlL
       
  1155 // Inserts/Updates given Gain Control in the Exif data.
       
  1156 // -----------------------------------------------------------------------------
       
  1157 //
       
  1158 void CExifModifyImpl::SetGainControlL( TUint16 aGainControl )
       
  1159     {
       
  1160     if ( !iExifCore )
       
  1161         {
       
  1162         User::Leave( KErrGeneral );
       
  1163         }
       
  1164 
       
  1165     iExifCore->SetTagDataL( KIdGainControl, aGainControl );
       
  1166     }