Exif API
Changes in Exif API documentation
Changes in Exif API
Purpose
Exif is a file format specification for digital still images and associated
sound. Exif API handles the JPEG based Exif image file format. It is an
independent library providing services for reading, writing and modifying
Exif v2.2 compliant data. It offers an interface for general operations related
to basic Exif data as well as for advanced operations, and thus it may be
used with subsets of Exif, such as DCF. Users of this library include e.g.
the following:
-
Image viewer applications, which read and modify Exif data.
-
Interfaces/libraries providing Exif compliant JPEG images.
Constraints
This API is valid for all platforms running on Symbian OS v9.3 or later.
Classification and release information
The Exif API is an SDK API and was first published in S60 3rd Edition.
API Description
The Exif API does not have any relationships to the Symbian platform subsystems.
It only requires the basic Symbian platform. The Exif API supports reading,
writing and modifying Exif data. Particularly, it supports operations related
to tags, IFDs and thumbnails. IFDs store tags so that they are collected into
groups under the same category. Thumbnail image data is not presented as an
IFD or tag, but it is independent data tied to the first IFD which describes
its properties. A tag is the smallest unit of the data structure stored and
moved through the interface. The library interface provides both basic and
advanced services. The basic interface services provide abstracted interface
functions to read, write and modify the most common Exif data including mainly
the mandatory and recommended tags. The advanced interface services provide
more flexible lower-level operations to read, write and modify Exif data.
The Exif API is not intended to be used as such. It offers services that are
needed by other libraries supporting Exif. Those libraries can use Exif API
in order to provide the requested service.
Use Cases
The main use cases of Exif API are:
API Class Structure
There are four interface classes,
CExifRead
,
CExifModify
,
CExifTag
and
TExifTagInfo
which provides the lowest level interface for an individual tag.
TOperationMode
of
the
CExifModify
class is used to define the operation mode
of the class. The mode can be either
ECreate
to create
an Exif image from the given JPEG image data, or
EModify
to
modify an existing Exif image.
CExifReadImpl
,
CExifModifyImpl
and
CExifTagImpl
are
the implementation classes of the interfaces.
Related APIs
-
CExifModify
-
CExifModifyImpl
-
CExifRead
-
CExifReadImpl
-
CExifTag
-
CExifTagImpl
-
ECreate
-
EModify
-
TExifTagInfo
-
TOperationMode
Using Exif API
Parsing an existing Exif image
In this example the full validity checking is done:
// 1. Read Exif image from the file to a buffer...
RFile file;
User::LeaveIfError( file.Open( iFs, iExifFile->Des(), EFileRead ) );
CleanupClosePushL( file );
TInt size = 0;
file.Size(size);
HBufC8* exif = HBufC8::NewL( size );
CleanupStack::PushL( exif );
TPtr8 bufferDes( exif->Des() );
User::LeaveIfError( file.Read( bufferDes ) );
CleanupStack::Pop( exif );
CleanupStack::PopAndDestroy();
CleanupStack::PushL( exif );
// 2. Instantiate Exif reader...
CExifRead* read = CExifRead::NewL( exif->Des() );
CleanupStack::PushL( read );
// 3. Get required data from the Exif image...
HBufC8* data = NULL;
data = read->GetImageDescriptionL(); /* Leaves if data is not found. */
/* Process the data … */
delete data;
data = NULL;
// 4. Delete the reader instance...
CleanupStack::PopAndDestroy( read );
CleanupStack::PopAndDestroy( exif );
Parsing an existing Exif image with options
In this example the validity checking for the Exif tags or JPEG markers
is not done. The execution time is much shorter with bigger images.
// 1. Read Exif information from the file to a buffer...
RFile file;
User::LeaveIfError( file.Open( iFs, iExifFile->Des(), EFileRead ) );
CleanupClosePushL( file );
TInt size = 0;
file.Size(size);
// Don’t read more than 64k
if ( size > 65536 )
size = 65536;
HBufC8* exif = HBufC8::NewL( size );
CleanupStack::PushL( exif );
TPtr8 bufferDes( exif->Des() );
User::LeaveIfError( file.Read( bufferDes, size ) );
CleanupStack::Pop( exif );
CleanupStack::PopAndDestroy();
CleanupStack::PushL( exif );
// 2. Instantiate Exif reader in fast mode...
CExifRead* read = CExifRead::NewL( exif->Des(),
CExifRead::ENoTagChecking | CExifRead::ENoJpeg );
CleanupStack::PushL( read );
// 3. Get required data from the Exif image...
HBufC8* data = NULL;
data = read->GetImageDescriptionL(); /* Leaves if data is not found. */
/* Process the data … */
delete data;
data = NULL;
// 4. Delete the reader instance...
CleanupStack::PopAndDestroy( read );
CleanupStack::PopAndDestroy( exif );
Modifying an existing Exif image
// 1. Read Exif image from the file to a buffer...
RFile file;
User::LeaveIfError( file.Open( iFs, iExifFile->Des(), EFileRead ) );
CleanupClosePushL( file );
TInt size = 0;
file.Size(size);
HBufC8* exif = HBufC8::NewL( size );
CleanupStack::PushL( exif );
TPtr8 bufferDes( exif->Des() );
User::LeaveIfError( file.Read( bufferDes ) );
CleanupStack::Pop( exif );
CleanupStack::PopAndDestroy();
CleanupStack::PushL( exif );
// 2. Instantiate Exif modifier in EModify mode...
CExifModify* modify = CExifModify::NewL( exif->Des(), CExifModify::EModify );
CleanupStack::PushL( modify );
// 3. Modify required data in the Exif image...
modify->SetXResolutionL( 72, 1 );
// 4. Get the modified Exif image...
// If zero length descriptor is given instead of exif->Des(), then only the
// Exif meta data is returned.
HBufC8* modifiedExif = modify->WriteDataL( exif->Des() );
/* Process the modified Exif data */
delete modifiedExif;
modifiedExif = NULL;
// 5. Delete the modifier instance...
CleanupStack::PopAndDestroy( modify );
CleanupStack::PopAndDestroy( exif );
Creating an Exif image out of an existing JPEG image
// 1. Read JPEG image from the file to a buffer...
RFile file;
User::LeaveIfError( file.Open( iFs, iExifFile->Des(), EFileRead ) );
CleanupClosePushL( file );
TInt size = 0;
file.Size(size);
HBufC8* jpeg = HBufC8::NewL( size );
CleanupStack::PushL( jpeg );
TPtr8 bufferDes( jpeg->Des() );
User::LeaveIfError( file.Read( bufferDes ) );
CleanupStack::Pop( jpeg );
CleanupStack::PopAndDestroy();
CleanupStack::PushL( jpeg );
// 2. Instantiate Exif modifier in ECreate mode...
CExifModify* modify = CExifModify::NewL( jpeg->Des(), CExifModify::ECreate );
CleanupStack::PushL( modify );
// 3. Insert (Set) at least the mandatory data...
modify->SetXResolutionL( 72, 1 );
modify->SetYResolutionL( 72, 1 );
modify->SetResolutionUnitL( 2 );
modify->SetYCbCrPositioningL( 1 );
modify->SetComponentsConfigurationL( 1, 2, 3, 0 );
modify->SetColorSpaceL( 1 );
modify->SetPixelXDimensionL( KImageWidth );
modify->SetPixelYDimensionL( KImageHeight );
// 4. Get the new Exif image...
// If zero length descriptor is given instead of jpeg->Des(), then only the
// Exif meta data is returned.
HBufC8* newExif = modify->WriteDataL( jpeg->Des() );
/* Process the new Exif data */
delete newExif;
newExif = NULL;
// 5. Delete the modifier instance...
CleanupStack::PopAndDestroy( modify );
CleanupStack::PopAndDestroy( jpeg );
Creating Exif data without a JPEG image
// 1. Instantiate Exif modifier in ECreate mode...
CExifModify* modify = CExifModify::NewL();
CleanupStack::PushL( modify );
// 3. Insert (Set) at least the mandatory data...
modify->SetXResolutionL( 72, 1 );
modify->SetYResolutionL( 72, 1 );
modify->SetResolutionUnitL( 2 );
modify->SetYCbCrPositioningL( 1 );
modify->SetComponentsConfigurationL( 1, 2, 3, 0 );
modify->SetColorSpaceL( 1 );
modify->SetPixelXDimensionL( KImageWidth );
modify->SetPixelYDimensionL( KImageHeight );
// 4. Get the new Exif meta data...
// If a descriptor containing valid JPEG data is given instead of zero length
// descriptor, then the whole Exif image data is returned.
TPtrC8 zeroLengthDesc;
HBufC8* newExif = modify->WriteDataL( zeroLengthDesc );
/* Process the new Exif data */
delete newExif;
newExif = NULL;
// 5. Delete the modifier instance...
CleanupStack::PopAndDestroy( modify );
Error handling
The leave mechanism of the Symbian platform is used to handle memory
exhaustion. The Exif API leaves whenever it detects something from which it
cannot recover. The exception/error cases are listed below:
|
Out of memory.
|
KErrGeneral
|
An internal error occurred.
|
KErrArgument
|
The given parameter to the API function is incorrect or invalid.
|
KErrNotSupported
|
This library does not support the requested operation with the given
parameters.
|
KErrCorrupt
|
The given JPEG or Exif data is corrupted or invalid.
|
KErrNotFound
|
The data (tag or IFD) corresponding to the given parameter is not found
in the JPEG or Exif data.
|
KErrNotReady
|
The Exif data is not yet complete (valid) for writing. Mandatory tags
or thumbnail may be missing.
|
KErrOverflow
|
The APP1 marker segment size exceeds 64K if the given data is inserted
to the Exif data.
|
The users of the Exif API should be aware of the following considerations:
-
While instantiating an Exif reader or modifier (in the
EModify
mode),
the whole Exif data (containing the Exif application marker and the JPEG compressed
image data) must be provided. The Exif application marker is checked for the
Exif v2.2 and/or DCF v1.0 format validity, which also covers the prior but
no further versions. The JPEG compressed primary image data is also simply
checked for JPEG baseline validity, but it is still the user’s responsibility
to provide valid and correct image data.
-
With
TExifModifyOption
in modifier or
TExifReadOption
in
reader the user may enable faster parsing times when primary JPEG data markers
are not verified. With the
ENoJpeg
option in reader only
64 kB of data is needed to read to the buffer, so this provides significant
time saving with large images. With the
ENoTagChecking
option
the reader can open Exif images that are not fully compatible with Exif specifications.
-
While instantiating an Exif modifier (in the
ECreate
mode),
the whole JPEG data must be provided. The given data is simply checked for
JPEG baseline format validity. JPEG images containing an SOF marker other
than SOF0 (baseline) are not supported. The image may contain any application
or comment markers. These markers are discarded while writing the Exif data.
It is the user’s responsibility to provide valid and correct image data.
-
It is also possible to instantiate an Exif modifier (in the
ECreate
mode)
without providing any input data. In this case, no checking can be performed
for the image data. It is the user’s responsibility to use the Exif data with
a proper image data.
-
The Exif API supports reading both Little Endian and Big Endian Exif data,
but written Exif output is always in the Little Endian format. In the modifying
case, even if the input Exif data is in the Big Endian format, the output
Exif data is in the Little Endian format.
-
While inserting a thumbnail into Exif data, the given thumbnail image
data must be JPEG compressed. The thumbnail image is simply checked for JPEG
baseline validity, but it is still the user’s responsibility to provide valid
and correct image data.
-
While writing Exif data output (
CExifModify::WriteDataL
),
the original JPEG or Exif image must be provided again. Although a simple
crosscheck is done before writing the Exif output, it is the user’s responsibility
to provide the original (or identical) JPEG or Exif image. If a zero-length
buffer is provided instead of the original image data, then only the Exif
Meta data is returned (written).
-
While getting the Exif APP segment data (
CExifRead::GetExifAppSegment
),
only the whole APP1 segment containing the Exif specific data is returned.
The segment does not include the primary JPEG image, but includes the Exif
thumbnail image if one exists.
Related APIs
-
CExifModify::WriteDataL
-
CExifRead::GetExifAppSegment
-
ECreate
-
EModify
-
ENoJpeg
-
ENoTagChecking
-
KErrArgument
-
KErrCorrupt
-
KErrGeneral
-
KErrNotFound
-
KErrNotReady
-
KErrNotSupported
-
KErrOverflow
-
TExifModifyOption
-
TExifReadOption
Memory overhead
Since the maximum size of an Exif marker is 64 kB (limited by the JPEG
application marker segment), memory consumption is not essentially higher
than 64 kB in most operations. However, there are two operations where memory
consumption may be higher:
-
While getting out the whole Exif image using the
CExifModify::WriteDataL
function,
the instant memory consumption may reach up to twice the JPEG image data size.
-
While getting out the Exif APP1 segment using the
CExifRead::GetExifAppSegmentL
function,
the instant memory consumption may reach up to twice the Exif APP1 segment
data size.
Related APIs
-
CExifModify::WriteDataL
-
CExifRead::GetExifAppSegmentL
Glossary
Abbreviations
Abbreviations
|
|
DCF
|
Design rule for the Camera File system
|
Exif
|
Exchangeable image file format for digital still cameras
|
OOM
|
Out Of Memory
|
Definitions
Definitions
IFD
|
Image File Directory. A collection of related tags. For
example, the first IFD includes all the tags related to an Exif file’s thumbnail.
|
JPEG
|
Still image compression standard developed by the Joint
Photographer Experts Group.
|
Primary image
|
The actual JPEG image data of the Exif file.
|
Tag
|
The smallest unit of data handled by this library. It is
stored inside an IFD.
|
References
Exchangeable image file format for digital still cameras: Exif version
2.2.
|
http://www.exif.org/
|
Design Rule for Camera File System 1.0
|
http://www.exif.org/
|
|