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 );
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 );
// 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 );
// 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 );
// 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 );
The leave mechanism of the Symbian OS environment is used to handle memory exhaustion. Exif API leaves whenever it detects something from which it cannot recover. The exception/error cases are listed below:
KErrNoMemory |
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 Exif API should be aware of the following considerations:
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.
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.
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.
ECreate
mode)
without providing any input data. In this case, no checking can be performed
for the image data. It is user’s responsibility to use the Exif data with
a proper image data.
CExifModify
),
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).
CExifRead
),
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.
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:
CExifModify
function,
the instant memory consumption may reach up to twice the JPEG image data size.
CExifRead
function,
the instant memory consumption may reach up to twice the Exif APP1 segment
data size.