Symbian3/SDK/Source/GUID-1FC88405-616F-5ED1-A136-9FE1E9226F0E.dita
changeset 7 51a74ef9ed63
child 8 ae94777fff8f
equal deleted inserted replaced
6:43e37759235e 7:51a74ef9ed63
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept xml:lang="en" id="GUID-1FC88405-616F-5ED1-A136-9FE1E9226F0E"><title>Exif Utility Library Guide</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>Exif (Exchangeable image file format) is a standard specifying rules for storing metadata in digital image files, mainly those using JPEG compression. </p> <section id="GUID-3333CA2A-EF84-5E7B-B9BE-8FF00523897F-GENID-1-8-1-18-1-1-5-1-6-1-8-1-4-1-2-2"><title>Purpose</title> <p>Exif enhances the JPEG and TIFF specifications with the addition of metadata tags to hold information such as the camera settings used to take the picture. </p> </section> <section><title>Exif Overview</title> <p>The Exif standard defines a wide range of metadata tags, some of which are listed below: </p> <ul><li id="GUID-55D72AF0-DEB5-55FE-AD34-52B14DD39590"><p>Date and time information of the image captured. </p> </li> <li id="GUID-DE117EE6-9465-59CD-A5C2-1FAECBF6DFE0"><p>Camera settings like camera model and make, and information that varies with each image such as orientation, aperture, shutter speed, focal length, metering mode, and film speed information. </p> </li> <li id="GUID-6F02CD74-00C5-5574-A3A2-45DB997F9AD4"><p>A thumbnail for previewing the picture on camera LCD. </p> </li> <li id="GUID-BB16459B-A734-5E3D-A632-CF8AFB31398F"><p>Copyright information. </p> </li> </ul> <p><b> Accessing Exif Metadata</b> </p> <p>Access to Exif metadata is provided through an abstract interface available in all the main ICL APIs. This interface can be implemented and managed through an ICL plugin, exhibiting the functionality to the client through the plugin extension mechanism. </p> <p>The <xref href="GUID-D3846471-6576-3080-A0C0-C1531DD6DAA3.dita"><apiname>MExifMetaData</apiname></xref> class is a generic interface for accessing the Exif metadata. To access a specific item of a metadata, both tag ID and the primary Image File Directory [IFD] number must be provided in the <xref href="GUID-D3846471-6576-3080-A0C0-C1531DD6DAA3.dita"><apiname>MExifMetaData</apiname></xref> access method, as some tags may appear in more than one IFD. The primary IFD number may either be 0 or 1. The main image tags are grouped together under IFD 0 and the tags for the thumbnail images are grouped under IFD 1 in the Exif metadata. The tags under these IFD can be further classified into sub IFD: </p> <p>For example : Tags related to the GPS can be sorted to form a group. </p> <p>The <xref href="GUID-D3846471-6576-3080-A0C0-C1531DD6DAA3.dita"><apiname>MExifMetaData</apiname></xref> is compounded by two classes as mentioned below: </p> <ul><li id="GUID-607A6DAE-75E0-56CD-8601-E360272D4CB3"><p> <xref href="GUID-B742FC40-2D88-3E71-8F89-FCB15A2C6619.dita"><apiname>MExifMetadataReader</apiname></xref> : This provides more generic functionalitites to read the tags from the Exif Metadata. The user is expected to provide the tag id and the primary IFD for the tags that needs to be read. </p> </li> <li id="GUID-0174AF96-9024-5FC1-BC04-4799C4F04CC0"><p> <xref href="GUID-27F068D2-F5BE-3D0B-83F4-493A783CFB80.dita"><apiname>MExifMetadataWriter</apiname></xref> : This is a generic way to write or set the tags of the Exif metadata. Here also the user is expected to render the key inputs like tag id and IFD for the data that needs to be written or modified. </p> </li> </ul> <p>The access provided by <xref href="GUID-D3846471-6576-3080-A0C0-C1531DD6DAA3.dita"><apiname>MExifMetaData</apiname></xref> is quite low level. The users are expected to know the tag IDs defined in the Exif specification in order to use it. Hence more user friendly classes as listed below are made available to access these tags. </p> </section> <section><title>Examples</title> <p>This section contains code snippets showing how Exif metadata is accessed in several situations. </p> <p><b>JPEG Exif Plugin</b> </p> <ul><li id="GUID-0D60F5DD-FFCD-51F5-BC57-9FB04500147F"><p> <xref href="GUID-8AA987C9-456B-3E7C-95C2-C5578EE977B9.dita"><apiname>TExifReaderUtility</apiname></xref> : This class provides a user friendly interface for reading the metadata in Exif encoded image files. The following example code illustrates its use: </p> <codeblock id="GUID-15B5C5BE-4021-55A9-99AD-77745A571863" xml:space="preserve">void CIclExample::AccessToEXIFMetadataL(const TDesC&amp; aFileName)
       
    13     {
       
    14     HBufC8* buffer8Bit=NULL;
       
    15     
       
    16     // If the image is not recognised or valid then the call will leave with an error
       
    17     CJPEGExifDecoder* exifdecoder =  static_cast&lt;CJPEGExifDecoder*&gt;(CJPEGExifDecoder::FileNewL(iFs, aFileName/*,CImageDecoder::EOptionNone, KNullUid, KNullUid, KUidICLJpegEXIFInterface*/));
       
    18        CleanupStack::PushL(exifdecoder);
       
    19     
       
    20     // Create a MExifMetadata object and Initializes to metadata associated with the CJPEGExifDecoder    
       
    21     MExifMetadata* metaData=exifdecoder-&gt;ExifMetadata();
       
    22 
       
    23     // Create a TExifReaderUtility object and pass the metadata to read it
       
    24     if(metaData != NULL)
       
    25         {
       
    26         TExifReaderUtility reader(metaData);    
       
    27         User::LeaveIfError(reader.GetImageDescription(buffer8Bit));
       
    28         }
       
    29 
       
    30     delete buffer8Bit;
       
    31     CleanupStack::PopAndDestroy(exifdecoder);
       
    32     }</codeblock> </li> <li id="GUID-07517C00-052C-5E88-9ED6-B4F87B95470C"><p> <xref href="GUID-62EA502C-FBE8-39A8-AEC6-3104C15F18C9.dita"><apiname> TExifWriterUtility</apiname></xref> : This class provides a user friendly interface for writing the metadata in Exif encoded image files. The following example code illustrates its use: </p> <codeblock id="GUID-71F45182-4C2E-57D0-94D9-DF71B05D31AF" xml:space="preserve">void CIclExample::AddEXIFDataToJPEGFileL()
       
    33 {
       
    34     TInt err = KErrNone;
       
    35       
       
    36     HBufC8 *encodedImageDescriptor = NULL;
       
    37    
       
    38     // Create the encoder, passing a buffer to store the encoded image
       
    39     CJPEGExifEncoder* exifencoder = static_cast&lt;CJPEGExifEncoder*&gt;(CImageEncoder::DataNewL(encodedImageDescriptor,CImageEncoder::EOptionNone,KImageTypeJPGUid));
       
    40     
       
    41     // Create a MExifMetadata object and initializes to metadata associated with CJPEGExifEncoder  
       
    42     MExifMetadataWriter* metaData=exifencoder-&gt;ExifMetadata(); 
       
    43     CleanupStack::PushL(exifencoder);
       
    44     
       
    45     // Create a TExifWriterUtility object to write the metadata in to the image
       
    46       TExifWriterUtility exifWriteUtility(metaData);
       
    47 
       
    48     HBufC8*    buf8ParamWriteVersion=KBuf8ParamWriteVersion().Alloc();
       
    49 
       
    50     User::LeaveIfError(exifWriteUtility.SetImageDescription(buf8ParamWriteVersion));
       
    51    
       
    52        delete encodedImageDescriptor;
       
    53       encodedImageDescriptor = NULL;
       
    54       
       
    55       delete buf8ParamWriteVersion;
       
    56       buf8ParamWriteVersion = NULL;
       
    57        
       
    58     CleanupStack::PopAndDestroy(exifencoder);
       
    59 
       
    60     }</codeblock> </li> </ul> <p>The access to the Exif metadata in image decoder/encoder will be provided through the <xref href="GUID-B6ACC0F4-BB58-3944-9ED2-42B043670573.dita"><apiname>MExifMetadata</apiname></xref> interface. The extended object <xref href="GUID-52969E30-A244-3A27-8182-FE105FEDABD7.dita"><apiname>CJPEGExifDecoder</apiname></xref> of the public class <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> provides the mechanism to access the custom Exif interface, by allowing the client to request a reference to the MExifMetadata interface. Once the source image has been set, and the client has acquired a reference to <xref href="GUID-B6ACC0F4-BB58-3944-9ED2-42B043670573.dita"><apiname>MExifMetadata</apiname></xref>, the data associated with the Exif tags can be accessed at any time before or after a decoding process has taken place. </p> <p>The client can request the main image or the thumbnail image as the source for the decode operation using the function <xref href="GUID-6F675985-A77B-3ADB-891A-B5B24D749DBC.dita"><apiname>SetImageTypeL()</apiname></xref>. These are the only arguments SetImageTypeL() will accept. Any other argument provided will cause the function to leave with error KErrArgument. The plugin assumes the main image to be the source unless otherwise specified. The plugin will ignore the function call if the image requested is unavailable. </p> <codeblock id="GUID-E7E96B7B-7BED-56A0-BBBD-C2F7B6F355FF" xml:space="preserve">imageDecoder-&gt;SetImageTypeL(CImageDecoder::EImageTypeThumbnail);</codeblock> <p>Unlike decoding, encoding is a one step procedure that requires all the Exif data to be set before the event is initiated. Any unspecified parameters must be populated by the default values. The call to the SetImageTypeL() determines whether an embedded image will be included in the encoded image or not. The client must furnish an optional parameter EImageTypeThumbnail along with the EImageTypeMain included in the bitfield to denote the inclusion of a thumbnail in the encoded image. Any other parameter specified aberrant from this specification will result in the function leaving with KErrArgument error. The thumbnail generated will conform to the DCF standards. </p> <p id="GUID-93EB3782-FECC-5151-A052-F922BEEA6479"><b> Exif support in CImageDisplay</b> </p> <p>In this scenario, the <xref href="GUID-204C95AA-803F-322F-A43D-4E1622180EF6.dita"><apiname>ExifMetadata()</apiname></xref> returns a pointer to the object that implements the <xref href="GUID-B6ACC0F4-BB58-3944-9ED2-42B043670573.dita"><apiname>MExifMetadata</apiname></xref> interface. The Exif metadata can be extracted, once the source image has been set. This provides a read only access to the metadata. It is illustrated as follows: </p> <codeblock id="GUID-9953D8E8-B8A6-53FF-93B3-294371948E88" xml:space="preserve">void CIclExample::AccessToEXIFMetadataL(const TDesC&amp; aFileName)
       
    61     {
       
    62     HBufC8* buffer8Bit=NULL;
       
    63     
       
    64     // Create the decoder, passing in the image memory. The image is recognised by the 
       
    65     // Image Conversion Library, an appropriate codec plugin loaded and the image 
       
    66     // headers parsed.
       
    67     // If the image is not recognised or valid then the call will leave with an error
       
    68     CJPEGExifDecoder* exifdecoder =  static_cast&lt;CJPEGExifDecoder*&gt;(CJPEGExifDecoder::FileNewL(iFs, aFileName/*,CImageDecoder::EOptionNone, KNullUid, KNullUid, KUidICLJpegEXIFInterface*/));
       
    69        CleanupStack::PushL(exifdecoder);
       
    70     
       
    71     // Create a MExifMetadata object and Initializes to metadata associated with the CJPEGExifDecoder    
       
    72     MExifMetadata* metaData=exifdecoder-&gt;ExifMetadata();
       
    73 
       
    74     // Create a TExifReaderUtility object and pass the metadata to read it
       
    75     if(metaData != NULL)
       
    76         {
       
    77         TExifReaderUtility reader(metaData);    
       
    78         User::LeaveIfError(reader.GetImageDescription(buffer8Bit));
       
    79         }
       
    80 
       
    81     delete buffer8Bit;
       
    82     CleanupStack::PopAndDestroy(exifdecoder);
       
    83     }</codeblock> <p id="GUID-A0B37BD4-05E2-58DA-8D25-F1E4A116AE79"><b>Exif support in CimageTransform</b> </p> <p>In this scenario, the <xref href="GUID-204C95AA-803F-322F-A43D-4E1622180EF6.dita"><apiname>ExifMetadata()</apiname></xref> returns a pointer to the object that implements the <xref href="GUID-B6ACC0F4-BB58-3944-9ED2-42B043670573.dita"><apiname>MExifMetadata</apiname></xref> interface. It is illustrated as follows: </p> <codeblock id="GUID-581E936E-BDDC-5C7F-9645-B3911A2A6F6F" xml:space="preserve">void CIclExample::AddEXIFDataToJPEGFileL()
       
    84 {
       
    85     TInt err = KErrNone;
       
    86       
       
    87     HBufC8 *encodedImageDescriptor = NULL;
       
    88    
       
    89     // Create the encoder, passing a buffer to store the encoded image
       
    90     CJPEGExifEncoder* exifencoder = static_cast&lt;CJPEGExifEncoder*&gt;(CImageEncoder::DataNewL(encodedImageDescriptor,CImageEncoder::EOptionNone,KImageTypeJPGUid));
       
    91     
       
    92     // Create a MExifMetadata object and initializes to metadata associated with CJPEGExifEncoder  
       
    93     MExifMetadataWriter* metaData=exifencoder-&gt;ExifMetadata(); 
       
    94     CleanupStack::PushL(exifencoder);
       
    95     
       
    96     // Create a TExifWriterUtility object to write the metadata in to the image
       
    97       TExifWriterUtility exifWriteUtility(metaData);
       
    98 
       
    99     HBufC8*    buf8ParamWriteVersion=KBuf8ParamWriteVersion().Alloc();
       
   100 
       
   101     User::LeaveIfError(exifWriteUtility.SetImageDescription(buf8ParamWriteVersion));
       
   102    
       
   103        delete encodedImageDescriptor;
       
   104       encodedImageDescriptor = NULL;
       
   105       
       
   106       delete buf8ParamWriteVersion;
       
   107       buf8ParamWriteVersion = NULL;
       
   108        
       
   109     CleanupStack::PopAndDestroy(exifencoder);
       
   110 
       
   111     }</codeblock> <p>The <xref href="GUID-204C95AA-803F-322F-A43D-4E1622180EF6.dita"><apiname>ExifMetadata()</apiname></xref> provides functions to scale still images. Additionally, it has the ability to scale only a subset of the original image by setting a clipping rectangle. This acts as if the source image outside the region does not exist causing the clipped image to be resized to the size specified. </p> <p>Furthermore, a thumbnail can be added to the JPEG file as shown in the code below: </p> <codeblock id="GUID-F7E532F5-14AC-5F4B-B98E-3A471C6DEA30" xml:space="preserve">void CIclExample::AddThumbnailToJPEGFileL(const TDesC&amp; aFileName)
       
   112     {
       
   113         TInt err = KErrNone;
       
   114                  TInt soiOffset=0;
       
   115                  TInt thumbnailLength = 0;
       
   116      TInt size = 0;
       
   117      Const TInt KConstStartOffset = 12;
       
   118            HBufC8 *desData= NULL;
       
   119   
       
   120      TPtr8 imageFromFilePtr = LoadImageIntoMemoryL(aFileName);
       
   121 
       
   122      // Create a CImageTransform object and push it on to the cleanup stack
       
   123      CImageTransform* imageTransform=CImageTransform::NewL(iFs);
       
   124      CleanupStack::PushL(imageTransform);
       
   125 
       
   126      // Call SetSourceFilenameL() function of CImageTransform to set the source to file
       
   127      imageTransform-&gt;SetSourceFilenameL(aFileName);
       
   128      
       
   129      // Call SetDestDataL() function of CImageTransform to set the destination size in pixels
       
   130      imageTransform-&gt;SetDestDataL(desData);
       
   131      
       
   132      // Call SetDestSizeInPixelsL() function of CImageTransform to set the destination size in pixels
       
   133      imageTransform-&gt;SetDestSizeInPixelsL(TSize(160, 120), ETrue);
       
   134      
       
   135      // Call SetOptionsL() to add the thumbnail
       
   136      imageTransform-&gt;SetOptionsL(CImageTransform::EThumbnail);
       
   137      
       
   138      //Call SetupL() to setup the ImageTransform
       
   139      imageTransform-&gt;SetupL();
       
   140     
       
   141    // encode the image
       
   142      CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
       
   143      imageTransform-&gt;Transform(activeListener-&gt;iStatus);
       
   144      CActiveScheduler::Start();
       
   145      User::LeaveIfError(activeListener -&gt; iStatus.Int());    
       
   146      
       
   147      // Create a CJPEGExifDecoder
       
   148   CJPEGExifDecoder* exifdecoder = static_cast&lt;CJPEGExifDecoder*&gt;(CJPEGExifDecoder::DataNewL(iFs, imageFromFilePtr));
       
   149   CleanupStack::PushL(exifdecoder);
       
   150      
       
   151      // Get the thumbnail from the image
       
   152      MExifMetadata* metaData=exifdecoder-&gt;ExifMetadata();        
       
   153 
       
   154      // Get the offset to the thumbnail image (i.e. the value of tag 0x0201)
       
   155   metaData-&gt;GetIntegerParam(0x0201, 1, soiOffset);
       
   156         
       
   157      // Get the length of the thumbnail image    (i.e. the value of tag 0x0202)
       
   158      metaData-&gt;GetIntegerParam(0x0202, 1, thumbnailLength);
       
   159      
       
   160      // Add thumbnail to image    
       
   161      RFile file;
       
   162      file.Open(iFs,KbitmapFile,EFileShareReadersOnly|EFileStream|EFileRead);
       
   163      CleanupClosePushL(file);
       
   164      file.Size(size);
       
   165 
       
   166      HBufC8* buffer = HBufC8::NewMaxLC(size);
       
   167      TPtr8 bufferDes(buffer-&gt;Des());
       
   168      file.Read(bufferDes);
       
   169  
       
   170   TPtrC8 thumbnailData = bufferDes.Mid(KConstStartOffset + soiOffset,thumbnailLength);
       
   171      
       
   172   // Write thumbnail data to image
       
   173      User::LeaveIfError(file.Write(thumbnailData));
       
   174 
       
   175      file.Close();
       
   176   delete desData;
       
   177   
       
   178      CleanupStack::PopAndDestroy(6);// buffer,exifdecoder,activeListener,imageTransform,desData,iImageInMemory
       
   179     }</codeblock> <p><b>Exif extension to support YUV image format</b> </p> <p>An extension to Exif is provided in the ICL to support encoding and decoding uncompressed YUV data images to and from the JPEG data format. The advantage of YUV format over RGB is that it reduces the amount of information required to reproduce a satisfactory video image. This is achieved by some of the components in YUV corresponding to more than one pixel. </p> <p>For example, the pixel does not necessarily have its own set of Y,U,V components, but may share the U and V components with other pixels as shown below: </p> <ul><li id="GUID-0ECC419B-DD45-5AC9-A645-2ABB7879A948"><p>YUV 4:4:4 - Each pixel has a Y, U, and V component. </p> </li> <li id="GUID-AC35BF13-7982-5F41-B9B2-5307FC6CEF90"><p>YUV 4:2:2 - Each horizontal pair of pixels has a Y component per pixel but only one U and V component per pair. </p> </li> <li id="GUID-7AE81F82-1379-5129-89DB-9B2DEB3D7352"><p>YUV 4:2:0 - Each 2*2 block of pixels has a Y component per pixel but only one U and one V component per block. </p> </li> </ul> <p>Note: The YUV bitmap layout may differ from the RGB bitmap layout in the sense that the RGB pixel components are rendered in the same buffer as opposed to YUV bitmaps which may have different layouts. </p> <p>The conversion between RGB and 4:4:4 YUV is pretty straight forward. The <xref href="GUID-BD22C221-5362-3E3B-A32C-56F43433D2FB.dita"><apiname>CFbsBitmaps</apiname></xref> are capable of encapsulating YUV data presented in its basic 4:4:4 YUV interleaved format. However, the existing <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> does not support all possible YUV bitmap formats and layouts. This limitation is overcome by the <xref href="GUID-54159F7E-C9A9-3FB5-806D-751DAF213290.dita"><apiname>CImageFrame</apiname></xref> class which allows the image data to be stored in the memory in any format or layout as long as it is uniquely identified. This is achieved by using format code UID's. </p> <codeblock id="GUID-270015D5-6359-5720-8EF0-494DA64A24FC" xml:space="preserve">    CImageFrame* imageFrame= CImageFrame::NewL(&amp;chunk, imageSizeInBytes, KRChunkSize);</codeblock> </section> </conbody><related-links><link href="GUID-FCEE832C-5D8D-5177-A86A-E10015EF77DC.dita"><linktext>Exif Utility Overview</linktext> </link> <link href="GUID-9C371845-9F5D-56BB-BE16-ED60139D02AF.dita"><linktext>JPEG Exif Plugin</linktext> </link> <link href="GUID-27220B08-B2E7-5106-9BCC-C86938D3E37D.dita"><linktext>Image Display</linktext> </link> <link href="GUID-6914EA3D-6FAB-52DD-A159-990F4ED892A2.dita"><linktext>Image Transformation</linktext> </link> </related-links></concept>