Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


ICLCodec: Decoding/Encoding an image using the Image Conversion Library

This example application demonstrates how to convert still images, stored in files or descriptors, to and from bitmap objects using the Image Conversion Library (ICL) API. It is located in the folder examples\Multimedia\ICL\IclExample.

The overview contains the following sections:

[Top]


Description

The example application demonstrates how to encode, decode, rotate and scale an image using the plug-ins provided by ICL. It covers the following scenarios:

Note: An ECom session is started internally by the ICL framework, as it uses the ECom framework. The session is ended by calling the REComSession::FinalClose() function.


Decoding an image format from a descriptor or a file

The application creates and initialises a decoder (CImageDecoder) object to decode either from a descriptor or a file to a bitmap. It uses the CImageDecoder::DataNewL() and CImageDecoder::FileNewL() functions to specify the descriptor and file image sources respectively. After the source is specified, the application creates a bitmap (CFbsBitmap) object to store the decoded image. Finally, the CImageDecoder::Convert() function is called to start decoding process.

Apart from decoding an image from a file or a descriptor to a bitmap, the example application also demonstrates the following:


Encoding an image format into a descriptor

The application creates and initialises an encoder (CImageEncoder) object to encode the bitmap to a descriptor. It uses the CImageEncoder::DataNewL() function to specify the descriptor to be used to store the encoded image. The application creates a bitmap (CFbsBitmap) object to represent the source bitmap. Finally, the CImageEncoder::Convert() function is called to start the encoding process.

Apart from encoding a bitmap to a descriptor, the example application also demonstrates the following:


Rotating a bitmap

The example application rotates a bitmap using an object of the CBitmapRotator class.


Scaling a bitmap with and without a mask

The example application scales a bitmap using an object of the CBitmapScaler class.

Note: The application uses an object of the TFrameInfo class to store image header information, such as, image size, dimension of the frame, colour depth and so on.

[Top]


Class summary

[Top]


Build

The Symbian OS build process describes how to build an application.

The IclExample builds an executable called iclexample.exe in the standard location (\epoc32\release\winscw\<build_variant> for CodeWarrior). After launching the executable, depending on the emulator you are using, you may need to task away from the application launcher/shell screen to view the console.

[Top]


Example code


bld.inf

// bld.inf
// 
// ICLExample
// Copyright ©) Symbian Software Ltd 2007. All rights reserved.
//

PRJ_MMPFILES
iclexample.mmp

PRJ_EXPORTS
smiley.bmp \epoc32\WINSCW\C\ICLExample\smiley.bmp
clock.gif \epoc32\WINSCW\C\ICLExample\clock.gif
am475.gif \epoc32\WINSCW\C\ICLExample\am475.gif
thumbimage.jpg \epoc32\WINSCW\C\ICLExample\thumbimage.jpg
comment.jpg \epoc32\WINSCW\C\ICLExample\comment.jpg
exifencode.jpg \epoc32\WINSCW\C\ICLExample\exifencode.jpg 
yuvimage.jpg \epoc32\WINSCW\C\ICLExample\yuvimage.jpg
source.mbm \epoc32\WINSCW\C\ICLExample\source.mbm

Iclexample.mmp

// iclexample.mmp
//
// Copyright ©) Symbian Software Ltd 2007.  All rights reserved.
//

TARGET      iclexample.exe
TARGETTYPE  exe

UID 0 0xE80000B3

CAPABILITY  ReadUserData WriteUserData

SOURCEPATH  .
SOURCE      iclmainexample.cpp
SOURCE      icldecodeexample.cpp
SOURCE      iclencodeexample.cpp

USERINCLUDE   .
SYSTEMINCLUDE \epoc32\include

LIBRARY euser.lib
LIBRARY gdi.lib
LIBRARY fbscli.lib
LIBRARY ImageConversion.lib
LIBRARY imagedisplay.lib 
LIBRARY efsrv.lib
LIBRARY jpegexifplugin.lib 
LIBRARY jpegimageframeplugin.lib 
LIBRARY bitmaptransforms.lib 
LIBRARY ecom.lib 
LIBRARY exifutility.lib 
LIBRARY gifscaler.lib 
LIBRARY imagetransform.lib

Iclexample.h

// iclexample.h
//
// Copyright ©) Symbian Software Ltd 2007. All rights reserved.
//
/**
@file 
Contains the CIclExample class.
*/
#ifndef __ICLEXAMPLE_H__
#define __ICLEXAMPLE_H__

// Symbian OS includes
#include <bitmaptransforms.h>
#include <iclexifimageframe.h> 
#include <exifutility.h>
#include <e32cons.h>

// Literals
_LIT(KBitmapFile,"\\ICLExample\\smiley.bmp");
_LIT(KThumbFile,"\\ICLExample\\thumbimage.jpg");
_LIT(KYuvBitmap,"\\ICLExample\\yuvimage.jpg");
_LIT(KMultiFrameClock,"\\ICLExample\\clock.gif");
_LIT(KBitmapComment,"\\ICLExample\\am475.gif");
_LIT(KBitmapFrameComment,"\\ICLExample\\comment.jpg");
_LIT(KBitmapExif,"\\ICLExample\\exifencode.jpg");
_LIT(KSourceBitmap,"\\ICLExample\\source.mbm");

_LIT(KTitle, "ICL Example" );
_LIT(KWelcomeMessage,"\n   Welcome to ICL Example    \n");
_LIT(KPressAKeyMsg, "\n Press any key to step through the example\n");
_LIT(KExitMsg, "\n Press any key to exit the application ");
_LIT(KPressAKey, "\n Press any key to continue\n");
_LIT(KFailed, "\n Failed to complete");

_LIT(KDecode,"\n   Decoding Bitmap   ");
_LIT(KDecodeFromDescriptorToBitmap, "\n Decode descriptor to bitmap \n");
_LIT(KDecodeFromDescriptorAndFile, "\n File %S  successfully decoded from descriptor and file\n");
_LIT(KDecodeToHalfFourthAndEighthSizedBmp, "\n File %S successfully decoded to half,fourth and eighth sized bitmap using reduction factor and reduced size\n");
_LIT(KSeparateThreadAndCancelAndContinueConvert, "\n File %S successfully  decoded using separate thread and Continue convert \n");
_LIT(KDecodeUsingImageMask, "\n Decode using image mask\n");
_LIT(KDecodeToYuv, "\n File %S successfully decoded to image frame Yuv\n");
_LIT(KDecodeUsingSepThread, "\n Decode using separate thread\n");
_LIT(KAccessThumbnailToDecode, "\n JPEG thumbnail access\n");
_LIT(KAccessExifMetadata, "\n Access Exif metadata\n");
_LIT(KDisplayingImageComments, "\nDecode and display image comments\n");
_LIT(KGettingMimeTypeOfSourceDescriptor, "\nGet the MIME type of a source image descriptor, and load a decoder using a MIME type\n");
_LIT(KRChunk, "aRChunkICL");
_LIT(KAccessExifThumbnailAndDecodeThumbnail, "\nEXIF And JPEG thumbnail accessed and thumbnail part of file %S decoded successfully\n");
_LIT(KImageMaskAndMultiFrameImageDecode, "\nFile %S successfully decoded using image mask and Multiframe image \n");
_LIT(KImageAndFrameComment, "\nImage comment and frame comment accessed successfully\n");
_LIT(KGettingMimeTypeFromSourceAndFile, "\nFile %S decoded successfully after getting the MIME type from source image\n");

_LIT(KEncode, "\n    Encoding Bitmap      ");
_LIT(KFileEncode, "\nFile %S encoded successfully to descriptor\n");
_LIT(KEncodeImageWithThumbnail, "\nEncode a JPEG thumbnail of an image\n");
_LIT(KAccessToThumbnailAndExifSetting,"\nThumbnail access and setting Exif metadata to image successful\n");
_LIT(KFileRotate, "\nBitmap rotated successfully\n");
_LIT(KScaleBitmap, "\nBitmap scaled successfully including optional selection of low memory and quality algorithms\n");
_LIT(KSetSourceDestinationandResize, "\nResize using CImageTransform\n");
_LIT(KFileRotateAfterDecode, "\nFile %S rotated successfully after being decoded\n");
_LIT(KSetSourceAndDestinationAndResize, "\nSetting source and destination and resize and preserve image data successful\n");
_LIT8(KExifMetadata, "Smiley bitmap"); 
_LIT8(KBuf8ParamWriteVersion, "Add Exif data");
_LIT(KExifAndThumbnailAdded, "\nAdding thumbnail and Exif metadata successful\n");
_LIT(KAddThumbnailToJpegFile, "\nAdd thumbnail to JPEG file\n");
_LIT(KPluginLoadedSpecificToUID, "\nPlugin loaded according to specific uid\n");
_LIT(KScaledWithWithoutAndThresholdScaling, "\nScaling with and without mask and threshold scaling successful\n");

class CActiveListener;

/**
Demonstrates some uses of the Symbian OS ICL (Image Converter Library) component.

The class demonstrates how to decode, encode, rotate and scale images using the plug-ins provided by ICL.
It covers the following use-cases of the ICL component:
- Decoding an image:
 - from a descriptor 
 - from a file
 - using an image mask
 - using separate thread
 - using the image thumbnail
 - using mult-frame
 - that supports YUV format into an image frame
- Encoding an image to a descriptor with EXIF metadata
- Rotating a bitmap
- Scaling a bitmap with and without mask 
*/

class CIclExample: public CBase
    {
public:
    static CIclExample* NewLC();

    ~CIclExample();
    CActiveListener* CreateAndInitializeActiveListenerLC();
    void DecodeFromDescriptorToBitmapL(const TDesC& aFileName);
    void DecodeFromFileToBitmapL(const TDesC& aFilename);
    void DecodeToYuvFrameL(const TDesC& aFileName);
    void AccessThumbnailToDecodeL(const TDesC& aFileName);
    void AccessExifMetadataL(const TDesC& aFileName);
    void DecodeUsingSepThreadL(const TDesC& aFileName);
    void DecodeToHalfFourthAndEighthSizedBitmapL(const TDesC& aFileName);
    void DecodeUsingImageMaskL(const TDesC& aFileName);
    void MultiFrameImageDecodeL(const TDesC& aFileName);
    void DecodeTheThumbnailL(const TDesC& aFileName);
    void DecodeUsingContinueConvertL(const TDesC& aFileName);
    void DisplayingImageCommentsL(const TDesC& aFileName);
    void DisplayingFrameCommentsL(const TDesC& aFileName);
    void GettingMimeTypeOfSourceDescriptorL(const TDesC& aFileName);
    void GettingMimeTypeOfSourceFileL(const TDesC& aFileName);
    void EncodeBitmapToDescriptorL(const TDesC& aFileName);
    void EncodeImageWithThumbnailL(const TDesC& aFileName);
    void SettingExifMetadataL(const TDesC& aFileName);
    void RotateBitmapL(const TDesC& aFileName);
    void ScaleBitmapL(const TDesC& aFileName);
    void DecodeWithRotateL(const TDesC& aFileName);
    void SetSourceDestinationandResizeL(const TDesC& aFileName);
    void SettingWithUseOfPreserveImageDataL(const TDesC& aFileName);
    void AddThumbnailToJpegFileL(const TDesC& aSrcFileName, const TDesC& aDesFileName );
    void AddExifDataToJpegFileL(const TDesC& aFileName);
    void LoadPluginByUidL(const TDesC& aFilename, TUid aCodecUid);

private:
    CIclExample();
    void ConstructL();
    
    TPtr8 LoadImageIntoMemoryLC(const TDesC& aFileName); 

private:
    /* File server session */
    RFs iFs;
    };
  
/**
CActiveListener provides the asynchronous operation
of an active object
*/
class CActiveListener : public CActive
    {
public:
    static CActiveListener* NewLC();
    ~CActiveListener(); 

    void InitializeActiveListener();
    TBool IsRequestCancelled();
    
private:
    CActiveListener();

    virtual void RunL();
    virtual void DoCancel();
    };
    
#endif //__ICLEXAMPLE_H__

Icldecodeexample.cpp

// icldecodeexample.cpp
//
// Copyright (c) Symbian Software Ltd 2007. All rights reserved.
//

/** 
@file 
The code demonstrates various decode functionality of CIclExample
*/

#include "iclexample.h"

/**
Note 1: For demonstration purposes we create a client side active object which can handle
the asynchronous request to decode the image. In a standard application the asynchronous
call would be made passing in a TRequestStatus object associate with an active object
which is part of that application. We would return to the main UI processing thread in 
which an active scheduler is running and wait for the asynchronous request to complete. In 
this demonstration we need to manually start the active scheduler.
*/

/**
Note 2: Starts the active scheduler - this is for demonstration purposes. See Note 1:
*/
/**


/**
Demonstrates how to decode an image for which the content of the file has been loaded into memory.
The image is decoded into a bitmap which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface  
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing  
@leave KErrCorrupt  The plugin cannot interpret data
@leave EFrameNumberOutOfRange  Frame range is out of limit 
@leave KErrCouldNotConnect  A session could not connect 
@leave KErrArgument  An argument is out of range 
@leave KErrTooBig  A number is too big 
@leave KErrUnderflow  An underflow in some operation 
*/  
void CIclExample::DecodeFromDescriptorToBitmapL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame
    
    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);
    
    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);
    
    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFrameNumber);
    
    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);
    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
    
    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
    
    // Convert the image (first frame) 
    imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFrameNumber);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.
    
    
    // Just verifying the presence of some output. The image can also be displayed instead.
    
    destBitmap->Save(_L("c:\\ICLExample\\decodedbitmapfromdescriptor.mbm"));
        
   
    CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
    }


/**
Demonstrates how to decode an image which has been loaded into a file.
The image is decoded into a bitmap which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave EFrameNumberOutOfRange  Frame range is out of limit 
@leave KErrCouldNotConnect  A session could not connect 
@leave KErrArgument  An argument is out of range
@leave KErrTooBig   A number is too big
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::DecodeFromFileToBitmapL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame

    // Create the decoder, passing the filename. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::FileNewL(iFs, aFileName);
    CleanupStack::PushL(imageDecoder);

    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFrameNumber);

    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);
    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image (first frame) 
    imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFrameNumber);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.


    // Just verifying the presence of some output. The image can also be displayed instead.

    destBitmap->Save(_L("c:\\ICLExample\\decodedbitmapfromfile.mbm"));


    CleanupStack::PopAndDestroy(3); // activeListener, destBitmap and imageDecoder
    }


/**
Demonstrates how to decode a JPEG image to an uncompressed YUV image frame.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
@leave KErrNotSupported  Functionality is not supported 
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::DecodeToYuvFrameL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame
    RChunk chunk;
    TInt imageSizeInBytes;

    // Create the decoder, passing the filename. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CJPEGImageFrameDecoder* jpegImageDecoder = static_cast<CJPEGImageFrameDecoder*>( CJPEGImageFrameDecoder::FileNewL(iFs, aFileName));
    CleanupStack::PushL(jpegImageDecoder);

    // Check the image whether it's supporting YUV or not
    if ( jpegImageDecoder->RecommendedBufferSize(imageSizeInBytes) == EFalse )
        {
        User::Leave(KErrNotSupported);
        }
        
    User::LeaveIfError(chunk.CreateGlobal(KRChunk, imageSizeInBytes, imageSizeInBytes, EOwnerProcess));  
    CleanupClosePushL(chunk);
        
    // Create an empty imageframe   
    CImageFrame* imageFrame = CImageFrame::NewL(&chunk, imageSizeInBytes, 0);
    CleanupStack::PushL(imageFrame);

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image to YUV image frame
    jpegImageDecoder->ConvertFrame(&activeListener->iStatus, *imageFrame, KFrameNumber);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.

    // YUV pixel buffer can be used if appropriate screen driver is available

    CleanupStack::PopAndDestroy(4); // activeListener, imageFrame, chunk and jpegImageDecoder 
    }


/**
Demonstrates accessing the JPEG thumbnail of an image for which the content of the file 
has been loaded into memory.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  Either the plugin cannot interpret data, or links between sections have been corrupted
@leave KErrArgument  An argument is out of range
*/
void CIclExample::AccessThumbnailToDecodeL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CJPEGExifDecoder* exifDecoder = static_cast<CJPEGExifDecoder*> (CJPEGExifDecoder::DataNewL(iFs, imageFromFilePtr));
    CleanupStack::PushL(exifDecoder);

    exifDecoder->SetImageTypeL(CImageDecoder::EImageTypeThumbnail);

    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support
    const TFrameInfo& frameInfo = exifDecoder->FrameInfo(KFrameNumber);

    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);
    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
        
    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image
    exifDecoder->Convert(&activeListener->iStatus, *destBitmap, KFrameNumber);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // access and decode to thumbnail complete either display the image or report an error.


    // Just verifying the presence of some output. The image can also be displayed instead.

    destBitmap->Save(_L("c:\\ICLExample\\decodedwithaccessthumbnail.mbm"));


    CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, exifDecoder and imageInMemory
    }


/**
Demonstrates how to access Exif metadata of an image.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
@leave KErrNotSupported  Functionality is not supported 
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing 
@leave KErrOverflow  An overflow in some operation
*/
void CIclExample::AccessExifMetadataL(const TDesC& aFileName)
    {
    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CJPEGExifDecoder* exifDecoder = static_cast<CJPEGExifDecoder*>(CJPEGExifDecoder::FileNewL(iFs, aFileName));
    CleanupStack::PushL(exifDecoder);

    // Create a MExifMetadata object and Initializes to metadata associated with the CJPEGExifDecoder   
    MExifMetadata* metaData = exifDecoder->ExifMetadata();

    // Create a TExifReaderUtility object and pass the metadata to read it
    if ( metaData != NULL )
        {
        TExifReaderUtility reader(metaData);

        HBufC8* buffer8Bit = NULL;   

        User::LeaveIfError(reader.GetImageDescription(buffer8Bit));

        // Image metadata buffer can be used here

        delete buffer8Bit;     
        }

    CleanupStack::PopAndDestroy(exifDecoder);
    }


/**
Demonstrates how to decode the thumbnail of the image for which the content of the
file has been loaded into memory.
The image is decoded into a bitmap which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  Either the plugin cannot interpret data, or links between sections have been corrupted
@leave EFrameNumberOutOfRange  Frame range is out of limit 
@leave KErrCouldNotConnect  A session could not connect 
@leave KErrArgument  An argument is out of range
@leave KErrTooBig  A number is too big
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::DecodeTheThumbnailL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);
        
    // Create the decoder, passing the image buffer . The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder= CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);
        
    // Set the image type to thumbnail to decode only the thumbnail part of the image    
    imageDecoder->SetImageTypeL(CImageDecoder::EImageTypeThumbnail);

    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support 
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFrameNumber);

    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);
    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the thumbnail part of the image
    imageDecoder->Convert(&activeListener->iStatus, *destBitmap);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.


    // Just verifying the presence of some output. The image can also be displayed instead.
    
    destBitmap->Save(_L("c:\\ICLExample\\decodedbitmapwiththumbnail.mbm"));


    CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
    }

    
/**
Demonstrates how to decode an image using separate thread.
The image is decoded into a bitmap which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored 

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
@leave EFrameNumberOutOfRange  Frame range is out of limit 
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::DecodeUsingSepThreadL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create the decoder, passing the image buffer and decoder option as EOptionAlwaysThread. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr, CImageDecoder::EOptionAlwaysThread);
    CleanupStack::PushL(imageDecoder);
        
    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFrameNumber);

    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);
    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
                            
    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image
    imageDecoder->Convert(&activeListener->iStatus, *destBitmap , KFrameNumber);
        
    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // decode complete using separate thread either display the image or report an error.


    // Just verifying the presence of some output. The image can also be displayed instead.

    destBitmap->Save(_L("c:\\ICLExample\\decodedbitmapusingseparatethread.mbm"));


    CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
    }


/**
Demonstrates how to decode an image to ½, ¼ and 1/8 sized bitmaps for which the content of the file 
has been loaded into memory.
The image is decoded into a bitmap which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range.
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::DecodeToHalfFourthAndEighthSizedBitmapL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error       
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);

    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFrameNumber);

    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);

    // Create a new TSize object which is half the size of original size 
    // and pass this size to the destination bitmap
    TSize halfSize;
    TInt  reductionFactor = 1; // half size, but quarter (2) and eighth (3) size are possible too

    imageDecoder->ReducedSize(frameInfo.iOverallSizeInPixels, reductionFactor, halfSize);
    User::LeaveIfError(destBitmap->Create(halfSize, frameInfo.iFrameDisplayMode));
                        
    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image to half sized bitmap
    imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFrameNumber);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // decode to half sized bitmap complete either display the image or report an error.

    
    // Just verifying the presence of some output. The image can also be displayed instead.

    destBitmap->Save(_L("c:\\ICLExample\\halfsizeddecodedbitmap.mbm"));


    CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory 
    }


/**
Demonstrates how to decode an image using an image mask for which the content of the file 
has been loaded into memory.
The image is decoded into a bitmap which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range.
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::DecodeUsingImageMaskL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error       
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);

    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support
    // for both destination bitmap and destination mask bitmap
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFrameNumber);
    
    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);
    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
    
    if ( frameInfo.iFlags & TFrameInfo::ETransparencyPossible )
        {
        // we can decode the mask
        CFbsBitmap* destBitmapMask = new(ELeave) CFbsBitmap;
        CleanupStack::PushL(destBitmapMask);

        // mask bitmap type depends on presence of alpha channel
        TDisplayMode bitmapMode = (frameInfo.iFlags & TFrameInfo::EAlphaChannel) ? EGray256 : EGray2;
        User::LeaveIfError(destBitmapMask->Create(frameInfo.iOverallSizeInPixels, bitmapMode)); 
                                
        // See Note 1
        CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

        // Decoding the frame and separating the mask from the main image.
        imageDecoder->Convert(&activeListener->iStatus, *destBitmap, *destBitmapMask, KFrameNumber);

        // See Note 2
        CActiveScheduler::Start();
        User::LeaveIfError(activeListener->iStatus.Int()); // decode complete using an image mask either display the image or report an error.


        // Just verifying the presence of some output. The image can also be displayed instead.

        destBitmapMask->Save(_L("c:\\ICLExample\\decodedbitmapmask.mbm"));
        
        destBitmap->Save(_L("c:\\ICLExample\\decodedbitmapwithmask.mbm"));
        

        CleanupStack::PopAndDestroy(2); // activeListener, destBitmapMask
        }    
    else
        {
        // no mask available - in this case we decode without mask 
        // See Note 1
        CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

        // Convert the image
        imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFrameNumber);

        // See Note 2
        CActiveScheduler::Start();
        User::LeaveIfError(activeListener->iStatus.Int()); // decode complete without using mask either display the image or report an error.


        // Just verifying the presence of some output. The image can also be displayed instead.
        
        destBitmap->Save(_L("c:\\ICLExample\\decodedbitmapwithoutmask.mbm"));


        CleanupStack::PopAndDestroy(activeListener);
        }
    
    CleanupStack::PopAndDestroy(3); // destBitmap, imageDecoder and imageInMemory
    }


/**
Demonstrates how to decode a multi-frame image for which the content of the file 
has been loaded into memory.
The image is decoded into a bitmap which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored

@leave EFrameNumberOutOfRange  Frame range is out of limit 
@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::MultiFrameImageDecodeL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // First frame

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);
        
    // Since the image header has been parsed we can find out the image size and
    // can create the bitmap to match the display mode we wish to support
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFrameNumber);

    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);
    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));

    // Read the number of frames
    const TInt KNumberOfFrame = imageDecoder->FrameCount();

    // See Note 1
    CActiveListener* activeListener = CActiveListener::NewLC();

    // Iterate all the frames and display them
    for ( TInt frameNumber = 0; frameNumber < KNumberOfFrame; ++frameNumber )
        {    
        // Convert the multi frame image
        imageDecoder->Convert(&activeListener->iStatus, *destBitmap, frameNumber);

        // See Note 1
        activeListener->InitializeActiveListener();      

        // See Note 2
        CActiveScheduler::Start();
        User::LeaveIfError(activeListener->iStatus.Int()); // decode complete using multiframe image either display the image or report an error.

    
        // Just verifying the presence of some output and it gets overwritten each loop. The image can also be displayed instead.       
         
        }
    
    destBitmap->Save(_L("c:\\ICLExample\\decodedmultiframebitmap.mbm"));
    CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
    }


/**
Demonstrates how to decode an image using CBufferedImageDecoder::Convert() and
CBufferedImageDecoder::ContinueConvert() functions.
The image is decoded into a bitmap, which can later be displayed on the screen.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::DecodeUsingContinueConvertL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame
    const TInt KChunkSize = 32;


    // Open the file containing the image and get the size.
    // Create a TPtr object to wrap the pointer to the buffer.
    RFile file;
    User::LeaveIfError(file.Open(iFs, aFileName, EFileShareReadersOnly|EFileStream|EFileRead));
    CleanupClosePushL(file);

    // Read the file size
    TInt fileSize = 0;
    User::LeaveIfError(file.Size(fileSize));

    // Allocate the buffer for the file read in chunks
    HBufC8* buffer = HBufC8::NewLC(KChunkSize);
    TPtr8 bufferPtr(buffer->Des());
    
    // Read the first chunk from the file
    User::LeaveIfError(file.Read(bufferPtr, KChunkSize));

    // Create the decoder passing the File Server session and attempt to open the decoder
    CBufferedImageDecoder* decoder = CBufferedImageDecoder::NewL(iFs);
    CleanupStack::PushL(decoder);

    // The image is recognised by the Image Conversion Library, an appropriate codec plugin loaded and 
    // the image headers parsed.

    for ( decoder->OpenL(bufferPtr); ! decoder->ValidDecoder(); decoder->ContinueOpenL() )
        {
        // read next chunk of data
        User::LeaveIfError(file.Read(bufferPtr, KChunkSize));

        decoder->AppendDataL(bufferPtr);
        }

    // Make sure the header has been fully processed

    for ( ; ! decoder->IsImageHeaderProcessingComplete(); decoder->ContinueProcessingHeaderL() )
        {
        // read next chunk of data
        User::LeaveIfError(file.Read(bufferPtr, KChunkSize));

        decoder->AppendDataL(bufferPtr);
        }


    // Create the destination bitmap

    const TFrameInfo frameInfo = decoder->FrameInfo(0);

    CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
    CleanupStack::PushL(bitmap);

    User::LeaveIfError(bitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image (first frame) using Convert() function for the first piece of code
    // and ContinueConvert() function for the remaining piece of code
    // Fed the image piece by piece in to decoder when the error code is KErrUnderflow until it becomes KErrNone
    // If the image is not recognised or valid then the call will leave with an error

    decoder->Convert(&activeListener->iStatus, *bitmap, KFrameNumber);

    // See Note 2
    CActiveScheduler::Start();

    for ( TInt status = activeListener->iStatus.Int(); status == KErrUnderflow; status = activeListener->iStatus.Int() )
        {
        if ( status != KErrNone && status != KErrUnderflow )
            {
            User::Leave(status);
            }
        
        // even if it attempts to read more byte, the Read function won't exceed the end
        // and return the number of read bytes.
        User::LeaveIfError(file.Read(bufferPtr, KChunkSize));
        
        decoder->AppendDataL(bufferPtr);

        activeListener->InitializeActiveListener();

        decoder->ContinueConvert(&activeListener->iStatus);

        CActiveScheduler::Start();
        }

    // Just verifying the presence of some output. The image can also be displayed instead.
    
    bitmap->Save(_L("c:\\ICLExample\\decodedbitmapwithcontinueconvert.mbm"));


    CleanupStack::PopAndDestroy(5); // file, buffer, decoder, bitmap and activeListener
    }


/**
Demonstrates how to display the comments contained in an image for which the content of the file 
has been loaded into memory. 

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
*/
void CIclExample::DisplayingImageCommentsL(const TDesC& aFileName)
    {
    TInt numberOfImageComment;

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);

    // Count the number of image comments attached to the specified image
    numberOfImageComment = imageDecoder->NumberOfImageComments();

    for ( TInt commentNumber = 0; commentNumber < numberOfImageComment; ++commentNumber )
        {
        HBufC* imageComment = imageDecoder->ImageCommentL(commentNumber);
        CleanupStack::PushL(imageComment);

        TPtrC commentPtr = imageComment->Des();

        // Decoded image comments can be displayed here
        CleanupStack::PopAndDestroy(imageComment);
        }

    CleanupStack::PopAndDestroy(2); // imageDecoder and imageInMemory
    }


/**
Demonstrates how to display the comments contained in frame of an image for which the content of the file 
has been loaded into memory.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
*/ 
void CIclExample::DisplayingFrameCommentsL(const TDesC& aFileName)
    {
    const TInt KFrameNumber = 0; // first frame
    TInt numberOfComment = 0;

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);

    for ( TInt frameNumber = 0; frameNumber < imageDecoder->FrameCount(); ++frameNumber )
        {
        // Count the number of frame comments
        numberOfComment = imageDecoder->NumberOfFrameComments(frameNumber);
        
        for ( TInt commentNumber = 0; commentNumber < numberOfComment; ++commentNumber )
            {
            HBufC* frameComment = imageDecoder->FrameCommentL(frameNumber,commentNumber);
            CleanupStack::PushL(frameComment);

            TPtrC commentPtr = frameComment->Des();

            // Decoded frame comments can be displayed here

            CleanupStack::PopAndDestroy(frameComment);
            }
        }

    CleanupStack::PopAndDestroy(2); // imageDecoder and imageInMemory
    }


/**
Demonstrates how to get the mime type of source in descriptor and load the decoder using this mime type.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
@leave KErrPermissionDenied  An operation cannot be performed due to a potential security violation
@leave KErrInUse  Requested resource is already in use
*/
void CIclExample::GettingMimeTypeOfSourceDescriptorL(const TDesC& aFileName)
    {
    TBuf8<128> theMimeType;

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Call GetMimeTypeDataL() function of CImageDecoder to get the mime type of specified file
    CImageDecoder::GetMimeTypeDataL(imageFromFilePtr, theMimeType);

    // Create the decoder, passing the image buffer. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr, theMimeType);
    CleanupStack::PushL(imageDecoder);

    // Decoded image mime can be displayed here after convert operation.  

    CleanupStack::PopAndDestroy(2); // imageDecoder and imageInMemory
    }


/**
Demonstrates how to get the mime type of source in file and load the decoder using this mime type.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range
@leave EFrameNumberOutOfRange  Frame range is out of limit 
*/
void CIclExample::GettingMimeTypeOfSourceFileL(const TDesC& aFileName)
    {
    TBuf8<128> theMimeType;

    // Call GetMimeTypeFileL() function of CImageDecoderGet to get the mime type of source file
    CImageDecoder::GetMimeTypeFileL(iFs, aFileName, theMimeType);

    // Create the decoder, passing the filename and mime type. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::FileNewL(iFs, aFileName, theMimeType);
    CleanupStack::PushL(imageDecoder);

    // Decoded image mime can be displayed here after convert operation

    CleanupStack::PopAndDestroy(imageDecoder);
    }


/**
Demonstrates how to resolve and load a plug-in by specific UID

@param aFileName  The specified file  where the image is stored
@param TUid  aCodecUid specific Uid to load the decoder

@leave KErrArgument  An argument is out of range
*/ 
void CIclExample::LoadPluginByUidL(const TDesC& aFileName, TUid aCodecUid)
    {
    // create the decoder, passing the filename. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed according to Uid.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = NULL;

    imageDecoder = CImageDecoder::FileNewL(iFs, aFileName, CImageDecoder::EOptionNone, aCodecUid);
    CleanupStack::PushL(imageDecoder);

    // Decoder can be used here

    CleanupStack::PopAndDestroy(imageDecoder);
    }


/**
Demonstrates how to decode a bitmap including rotation of image MNG/GIF 'Animation'

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave EFrameNumberOutOfRange  Frame range is out of limit
@leave KErrCouldNotConnect  A session could not connect 
@leave KErrArgument  An argument is out of range
@leave KErrTooBig  A number is too big
@leave KErrUnderflow  An underflow in some operation
@leave ENoSourceBitmap  Invalid source bitmap
*/        
void CIclExample::DecodeWithRotateL(const TDesC& aFileName)
    {
    const TInt frameNumber = 0; // first frame

    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);
        
    // create the decoder, passing in the image memory. The image is recognised by the 
    // Image Conversion Library, an appropriate codec plugin loaded and the image 
    // headers parsed.
    // If the image is not recognised or valid then the call will leave with an error
    CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageFromFilePtr);
    CleanupStack::PushL(imageDecoder);

    // Since the image header has been parsed we can find out the image size and can create 
    // the bitmap to match the display mode we wish to support.
    const TFrameInfo& frameInfo = imageDecoder->FrameInfo(frameNumber);

    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);

    User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image (first frame) 
    imageDecoder->Convert(&activeListener->iStatus, *destBitmap, frameNumber);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.

    // Create a CBitmapRotator object and push it on the cleanup stack
    CBitmapRotator* rotator = CBitmapRotator::NewL();
    CleanupStack::PushL(rotator);

    // Rotate the bitmap through the specified angle
    activeListener->InitializeActiveListener();

    rotator->Rotate(&activeListener->iStatus, *destBitmap, CBitmapRotator::ERotation180DegreesClockwise);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // rotate complete either display the image or report an error.


    // Just verifying the presence of some output. The rotated image can also be displayed instead.

    destBitmap->Save(_L("c:\\ICLExample\\rotatedbitmap.mbm"));


    CleanupStack::PopAndDestroy(5); // rotator, destBitmap, activeListener, imageDecoder and imageInMemory
    }

Iclencodeexample.cpp

// iclencodeexample.cpp
//
// Copyright (c) Symbian Software Ltd 2007. All rights reserved.
//

/** 
@file 

This code demonstrates various encoding,rotating and scaling functionality of images in 
ICL component
*/

/**
Note 1: For demonstration purposes we create a client side active object which can 
handle the asynchronous request to decode the image. In a standard application the asynchronous
call would be made passing in a TRequestStatus object associate with an active object
which is part of that application. We would return to the main UI processing thread in 
which an active scheduler is running and wait for the asynchronous request to complete. In 
this demonstration we need to manually start the active scheduler.
*/

/**
Note 2: Starts the active scheduler - this is for demonstration purposes. See Note 1:
*/

#include "iclexample.h"
#include <gifscaler.h>
#include <imagetransform.h>
    
/**
Demonstrates how to encode an image into a descriptor.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrUnderflow An underflow in some operation
*/
void CIclExample::EncodeBitmapToDescriptorL(const TDesC& aFileName)  
    {
    HBufC8* encodedImageDescriptor = NULL;

    // Create the encoder, passing a buffer to store the encoded image
    CImageEncoder* encoder = CImageEncoder::DataNewL(encodedImageDescriptor, CImageEncoder::EOptionNone,KImageTypeGIFUid);
    CleanupStack::PushL(encoder);

    // Create a CFbsBitmap to store the source bitmap to encode
    CFbsBitmap* sourceBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(sourceBitmap);

    User::LeaveIfError(sourceBitmap->Create(TSize(20,30), EColor16M));
    User::LeaveIfError(sourceBitmap->Load(aFileName));

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image
    encoder->Convert(&activeListener->iStatus, *sourceBitmap);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int());// encode complete either display the image or report an error.


    CleanupStack::PopAndDestroy(3); // encoder, sourceBitmap and activeListener


    // We can use the descriptor here

    // And as we took ownership back, we need to push into the cleanup stack to make sure no
    // memory leaks take place if any leave later

    CleanupDeletePushL(encodedImageDescriptor);


    // Just verifying the presence of some output. 

    RFile file;
    
    User::LeaveIfError(file.Replace(iFs, _L("c:\\ICLExample\\encodeddescriptor.mbm"), EFileWrite)); 
    CleanupClosePushL(file);

    User::LeaveIfError(file.Write(*encodedImageDescriptor));

    CleanupStack::PopAndDestroy(&file);


    CleanupStack::PopAndDestroy(encodedImageDescriptor);
    }

    
/**
Demonstrates how to encode a JPEG thumbnail of an image.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrUnderflow  An underflow in some operation
*/
void CIclExample::EncodeImageWithThumbnailL(const TDesC& aFileName)
    {
    HBufC8* encodedImageDescriptor = NULL;

    // Create the encoder, passing a buffer to store the encoded image
    CImageEncoder* encoder = CImageEncoder::DataNewL(encodedImageDescriptor, CImageEncoder::EOptionNone, KImageTypeJPGUid);
    CleanupStack::PushL(encoder);

    // Set the image type to thumbnail 
    encoder->SetThumbnail(ETrue);

    // Create a bitmap to access the thumbnail
    CFbsBitmap* sourceBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(sourceBitmap);

    User::LeaveIfError(sourceBitmap->Create(TSize(250,200), EColor16M));
    User::LeaveIfError(sourceBitmap->Load(aFileName));

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image
    encoder->Convert(&activeListener->iStatus, *sourceBitmap);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // access to thumbnail complete either display the image or report an error.


    CleanupStack::PopAndDestroy(3); // encoder, sourceBitmap and activeListener
    

    // We can use the descriptor here
    
    // And as we took ownership back, we need to push into the cleanup stack to make sure no
    // memory leaks take place if any leave later

    CleanupDeletePushL(encodedImageDescriptor);
    

    // Just verifying the presence of some output.

    RFile file;
    
    User::LeaveIfError(file.Replace(iFs, _L("c:\\ICLExample\\encodedbitmapwiththumbnail.mbm"), EFileWrite)); 
    CleanupClosePushL(file);

    User::LeaveIfError(file.Write(*encodedImageDescriptor));

    CleanupStack::PopAndDestroy(&file);


    CleanupStack::PopAndDestroy(encodedImageDescriptor);
    }


/**
Demonstrates how to set the exif metadata of an image.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrCorrupt  The plugin cannot interpret data
@leave KErrArgument  An argument is out of range 
@leave KErrNotSupported  Functionality is not supported 
*/       
void CIclExample::SettingExifMetadataL(const TDesC& aFileName)   
    {
    HBufC8* encodedImageDescriptor = NULL;

    // Create the encoder, passing a buffer to store the encoded image
    CJPEGExifEncoder* exifEncoder = static_cast<CJPEGExifEncoder*>(CImageEncoder::DataNewL(encodedImageDescriptor, CImageEncoder::EOptionNone, KImageTypeJPGUid));
    CleanupStack::PushL(exifEncoder);

    // Create a MExifMetadata object and initialize it with the metadata associated with CJPEGexifEncoder  
    MExifMetadataWriter* metaData = exifEncoder->ExifMetadata(); 

    // Create a TExifWriterUtility object to write the metadata in to the image
    TExifWriterUtility exifWriteUtility(metaData);

    HBufC8* buf8ParamWriteVersion = KBuf8ParamWriteVersion().AllocLC();
    
    User::LeaveIfError(exifWriteUtility.SetImageDescription(buf8ParamWriteVersion));

    CleanupStack::PopAndDestroy(buf8ParamWriteVersion);


    // Create a bitmap 
    CFbsBitmap* sourceBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(sourceBitmap);

    User::LeaveIfError(sourceBitmap->Create(TSize(250,200), EColor16M));
    User::LeaveIfError(sourceBitmap->Load(aFileName));
        
    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image
    exifEncoder->Convert(&activeListener->iStatus, *sourceBitmap);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int());


    CleanupStack::PopAndDestroy(3); // encoder, sourceBitmap and activeListener


    // We can use the descriptor here

    // And as we took ownership back, we need to push into the cleanup stack to make sure no
    // memory leaks take place if any leave later

    CleanupDeletePushL(encodedImageDescriptor);


    // Just verifying the presence of some output.

    RFile file;
    
    User::LeaveIfError(file.Replace(iFs, _L("c:\\ICLExample\\settingexifdescriptor.mbm"), EFileWrite)); 
    CleanupClosePushL(file);

    User::LeaveIfError(file.Write(*encodedImageDescriptor));

    CleanupStack::PopAndDestroy(&file);
    

    CleanupStack::PopAndDestroy(encodedImageDescriptor);
    }


/**
Demonstrates how to rotate a bitmap.

@param aFileName  The specified file where the image is stored

@leave ENoSourceBitmap  Invalid source bitmap
*/
void CIclExample::RotateBitmapL(const TDesC& aFileName)
    {
    // Create a CBitmapRotator object and push it on the cleanup stack 
    CBitmapRotator* rotator = CBitmapRotator::NewL();
    CleanupStack::PushL(rotator);

    // Create a source bitmap 
    CFbsBitmap* sourceBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(sourceBitmap);

    User::LeaveIfError(sourceBitmap->Create(TSize(15,20), EColor16M));
    User::LeaveIfError(sourceBitmap->Load(aFileName));

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Rotate the bitmap through the specified angle
    rotator->Rotate(&activeListener->iStatus, *sourceBitmap, CBitmapRotator::ERotation180DegreesClockwise);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int());

    // Just verifying the presence of some output.
    sourceBitmap->Save(_L("c:\\ICLExample\\rotatedbitmap.mbm"));


    CleanupStack::PopAndDestroy(3); // rotator, sourceBitmap and activeListener
    }


/**
Demonstrates how to scale a bitmap including optional selection of low memory
and quality algorithms.

@param aFileName  The specified file where the image is stored

@leave KErrNotSupported  Functionality is not supported 
*/
void CIclExample::ScaleBitmapL(const TDesC& aFileName)
    {
    // Create a source bitmap object and push it on to the cleanup stack
    CFbsBitmap* sourceBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(sourceBitmap);

    User::LeaveIfError(sourceBitmap->Create(TSize(100,100), EGray2));
    User::LeaveIfError(sourceBitmap->Load(aFileName));

    // Create a destination bitmap  object and push it on to the cleanup stack
    CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(destBitmap);

    User::LeaveIfError(destBitmap->Create(TSize(20,30), EColor16M));

    // Scale the bitmap with old algorithm
    // Create a CBitmapScaler object and push it on to the cleanup stack
    CBitmapScaler* scaler = CBitmapScaler::NewL();
    CleanupStack::PushL(scaler);

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Scale the bitmap using low memory and medium quality algorithm
    scaler->UseLowMemoryAlgorithm(ETrue);
    scaler->SetQualityAlgorithm(CBitmapScaler::EMediumQuality);

    // Call the scale() function of CBitmapScaler to perform the scaling operation with optional selection of low memory 
    scaler->Scale(&activeListener->iStatus, *sourceBitmap, *destBitmap, EFalse);   

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int());// scale complete either display the image or report an error.

    // Just verifying the presence of some output. Descriptor can also be used instead

    destBitmap->Save(_L("c:\\ICLExample\\scaledbitmap.mbm"));


    CleanupStack::PopAndDestroy(4); // activeListener, scaler, destBitmap and sourceBitmap
    }


/**
1) Specifies the name of the source file containing the image to transform
2) Defines the destination descriptor
3) Resize using CImageTransform

@param aFileName  The specified file  where the image is stored

@leave KErrArgument  An argument is out of range
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
*/ 
void CIclExample::SetSourceDestinationandResizeL(const TDesC& aFileName)
    {
    HBufC8* desData = NULL;

    // Create CImageTransform object and push it on to the cleanup stack
    CImageTransform* imageTransform = CImageTransform::NewL(iFs);
    CleanupStack::PushL(imageTransform);

    imageTransform->SetSourceFilenameL(aFileName);
    imageTransform->SetDestDataL(desData);
    imageTransform->SetDestSizeInPixelsL(TSize(160, 120), ETrue);
    imageTransform->SetupL();

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Call Transform() function of CImageTransform for image transform operation
    imageTransform->Transform(activeListener->iStatus);

    // See Note 2
    CActiveScheduler::Start();
    // destData ownership is on CLI side if something goes wrong
    User::LeaveIfError(activeListener->iStatus.Int());


    CleanupStack::PopAndDestroy(2); // imageTransform and activeListener


    // We can use the destination data here

    // And as we took ownership back, we need to push into the cleanup stack to make sure no
    // memory leaks take place if any leave later

    CleanupDeletePushL(desData);


    // Just verifying the presence of some output.

    RFile file;
    
    User::LeaveIfError(file.Replace(iFs, _L("c:\\ICLExample\\destdata.mbm"), EFileWrite)); 
    CleanupClosePushL(file);

    User::LeaveIfError(file.Write(*desData));

    CleanupStack::PopAndDestroy(&file);

    
    CleanupStack::PopAndDestroy(desData);
    }


/**
1) Specifies the source descriptor containing the image to transform
2) Specifies the name of the destination file where the transformed image 
is to be written to.
3) Transforms the bitmap
4) Either specify that the original image data is to be preserved, as far as possible, 
or that the image data should be re-encoded to produce a more size-efficient image. 

@param aFileName  The specified file  where the image is stored

@leave KErrArgument  An argument is out of range
*/ 
void CIclExample::SettingWithUseOfPreserveImageDataL(const TDesC& aFileName)
    {
    TPtr8 imageFromFilePtr = LoadImageIntoMemoryLC(aFileName);

    // Create CImageTransform object and push it on to the cleanup stack
    CImageTransform* imageTransform = CImageTransform::NewL(iFs);
    CleanupStack::PushL(imageTransform);

    imageTransform->SetSourceDataL(imageFromFilePtr);
    imageTransform->SetDestFilenameL(aFileName);
    imageTransform->SetDestSizeInPixelsL(TSize(160, 120), ETrue);
    imageTransform->SetPreserveImageData(ETrue); 
    imageTransform->SetupL();

    // Call Transform() function of CImageTransform for image transform operation
    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Call Transform() function of CImageTransform for image transform operation
    imageTransform->Transform(activeListener->iStatus);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int());


    CleanupStack::PopAndDestroy(3); // activeListener, imageTransform and imageInMemory
    }

    
/**
Demonstrates how to add thumbnail to JPEG file.

@param aSrcFileName  The specified file  where the source image is stored
@param aDesFileName  The specified

@leave KErrArgument  An argument is out of range
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrNotSupported  Functionality is not supported
*/ 
void CIclExample::AddThumbnailToJpegFileL(const TDesC& aSrcFileName, const TDesC& aDesFileName)
    {
    // Create a CImageTransform object and push it on to the cleanup stack
    CImageTransform* imageTransform = NULL;
    
    imageTransform = CImageTransform::NewL(iFs);
    CleanupStack::PushL(imageTransform);

    imageTransform->SetSourceFilenameL(aSrcFileName);
    imageTransform->SetDestFilenameL(aDesFileName);
    imageTransform->SetDestSizeInPixelsL(TSize(160, 120), ETrue);
    imageTransform->SetOptionsL(CImageTransform::EThumbnail);
    imageTransform->SetupL();

    // encode the image to add thumbnail
    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Call Transform() function of CImageTransform for image transform operation
    imageTransform->Transform(activeListener->iStatus);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int());


    CleanupStack::PopAndDestroy(2); // activeListener and imageTransform
    }


/**
Demonstrates how to add Exif data to a JPEG file.

@param aFileName  The specified file where the image is stored

@leave KEComErrNoInterfaceIdentified  ECom could not find the specified interface
@leave KErrNotFound  Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing
@leave KErrArgument  An argument is out of range 
@leave KErrNotSupported  Functionality is not supported
@leave KErrOverflow  An overflow in some operation
*/ 
void CIclExample::AddExifDataToJpegFileL(const TDesC& aFileName)
    {   
    HBufC8* encodedImageDescriptor = NULL;

    // Create the encoder, passing a buffer to store the encoded image
    CJPEGExifEncoder* exifEncoder = static_cast<CJPEGExifEncoder*>(CImageEncoder::DataNewL(encodedImageDescriptor, CImageEncoder::EOptionNone, KImageTypeJPGUid));
    CleanupStack::PushL(exifEncoder);

    // Create a MExifMetadata object and initializes to metadata associated with CJPEGexifEncoder  
    MExifMetadataWriter* metaData = exifEncoder->ExifMetadata(); 

    // Create a TExifWriterUtility object to write the metadata in to the image
    TExifWriterUtility exifWriteUtility(metaData);

    HBufC8* buf8ParamWriteVersion = KBuf8ParamWriteVersion().AllocLC();
    
    User::LeaveIfError(exifWriteUtility.SetImageDescription(buf8ParamWriteVersion));

    CleanupStack::PopAndDestroy(buf8ParamWriteVersion);


    // Create a CFbsBitmap to store the source bitmap to encode
    CFbsBitmap* sourceBitmap = new(ELeave) CFbsBitmap;
    CleanupStack::PushL(sourceBitmap);
    
    User::LeaveIfError(sourceBitmap->Create(TSize(20,30), EColor16M));
    User::LeaveIfError(sourceBitmap->Load(aFileName));

    // Create CFrameImageData object and push it on the cleanup stack 
    CFrameImageData* frameImageData = CFrameImageData::NewL();
    CleanupStack::PushL(frameImageData);

    // See Note 1
    CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();

    // Convert the image
    exifEncoder->Convert(&activeListener->iStatus, *sourceBitmap, frameImageData);

    // See Note 2
    CActiveScheduler::Start();
    User::LeaveIfError(activeListener->iStatus.Int()); // encode complete either display the image or report an error.


    // Just verifying the presence of some output.
    sourceBitmap->Save(_L("c:\\ICLExample\\addexifbitmap.mbm"));


    CleanupStack::PopAndDestroy(4); // activeListener, frameImageData, sourceBitmap and exifEncoder


    // We can use the descriptor here
    
    // And as we took ownership back, we need to push into the cleanup stack to make sure no
    // memory leaks take place if any leave later

    CleanupDeletePushL(encodedImageDescriptor);


    // Just verifying the presence of some output.

    RFile file;
    
    User::LeaveIfError(file.Replace(iFs, _L("c:\\ICLExample\\addexifdescriptor.mbm"), EFileWrite)); 
    CleanupClosePushL(file);

    User::LeaveIfError(file.Write(*encodedImageDescriptor));

    CleanupStack::PopAndDestroy(&file);


    CleanupStack::PopAndDestroy(encodedImageDescriptor);
    }

Iclmainexample.cpp

// iclmainexample.cpp
//
// Copyright (c) Symbian Software Ltd 2007. All rights reserved.
//
/**
@file 
This example program demonstrates the usage of the CIclExample and CActiveListener classes. 
It defines E32Main() which internally calls the  MainL() function for calling all the 
functions of the CIclExample class.
*/
#include "iclexample.h"


/**
CActiveListener factory function
@return A CActiveListener object
*/
CActiveListener* CActiveListener::NewLC()
    {
    CActiveListener* self = new(ELeave) CActiveListener;
    CleanupStack::PushL(self);  
    return self;
    }

/**
Constructor for class CActiveListener
*/
CActiveListener::CActiveListener() : CActive(EPriorityLow)
    {
   CActiveScheduler::Add(this); 
    }

/**
Destructor
*/  
CActiveListener::~CActiveListener()
    {
    }
    
/**
Handles the request.
This function is derived from CActive
*/  
void CActiveListener::RunL()
    {
    CActiveScheduler::Stop();
    }
    
/**
Cancels the outstanding request.
This function is derived from CActive
*/  
void CActiveListener::DoCancel()
    {
    }

/**
Initializes the CActiveListener
*/  
void CActiveListener::InitializeActiveListener()
    {
    SetActive();
    }
    
/**
Check that the request has been cancelled.
@return A boolean indicating whether the request has been cancelled or not
*/
TBool CActiveListener::IsRequestCancelled()
    { 
    return ( iStatus == KErrCancel );
    }
        


/**
Instance a CIclExample object and push it on the cleanup stack.
Initializes all member data to their default values.
@return A CIclExample object
*/      
CIclExample* CIclExample::NewLC()
   {
    CIclExample* self = new(ELeave) CIclExample();
    CleanupStack::PushL(self);
    self->ConstructL();  
    return self;
    }

/**
Constructor
*/
CIclExample::CIclExample()
    {
    }
    
void CIclExample::ConstructL()
    {
    User::LeaveIfError(iFs.Connect());
    User::LeaveIfError(RFbsSession::Connect());
    }
    
/**
Destructor
*/
CIclExample::~CIclExample()
    {
    RFbsSession::Disconnect();
    iFs.Close();
    
    // Close REComSession 
    REComSession::FinalClose();
    }


/**
Opens file and creates file pointer
@param aFileName The specified file to open
@return imageInMemoryPtr A Pointer to iImageInMemory
@leave System-wide error codes
*/  
TPtr8 CIclExample::LoadImageIntoMemoryLC(const TDesC& aFileName)
    {
    RFile file;
    TInt fileSize = 0;

    // Open the file for decoding
   User::LeaveIfError(file.Open(iFs, aFileName, EFileRead));
    file.Size(fileSize);    

    HBufC8* imageInMemory = HBufC8::NewMaxLC(fileSize);
    TPtr8 imageInMemoryPtr = imageInMemory->Des();
    if(file.SubSessionHandle())
        {
        User::LeaveIfError(file.Read(imageInMemoryPtr));    
        }
        
    file.Close();

    return imageInMemoryPtr;
    }


/**
Creates and Initializes a CActiveListener object.
@return A CActiveListener object
*/
CActiveListener* CIclExample::CreateAndInitializeActiveListenerLC()
    {
    // Create an active Listener and push it on the cleanup stack
    CActiveListener* activeListener = CActiveListener::NewLC();
    activeListener->InitializeActiveListener();
    return activeListener;
    }


LOCAL_C void MainL()
    {
    // Create a CConsoleBase to define console interface
    CConsoleBase* gConsole = Console::NewL(KTitle,TSize(KConsFullScreen, KConsFullScreen));
    CleanupStack::PushL(gConsole);

    // Create an active scheduler to handle asychronous calls
    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
    CleanupStack::PushL(scheduler);
    CActiveScheduler::Install(scheduler);

    CIclExample* app = CIclExample::NewLC();
    
    gConsole->Printf(KWelcomeMessage);
    gConsole->Printf(KPressAKeyMsg);
    gConsole->Getch();   

    /*
    Various Decode functions
    */
    gConsole->Printf(KDecode);
    
    // Decode descriptor to bitmap 
    app->DecodeFromDescriptorToBitmapL(KBitmapFile);
    gConsole->Printf(KDecodeFromDescriptorToBitmap);

    // Decode from image file to bitmap
    app->DecodeFromFileToBitmapL(KBitmapFile);
    gConsole->Printf(KDecodeFromDescriptorAndFile, &KBitmapFile);   

    // Decode to image frame YUV
    app->DecodeToYuvFrameL(KYuvBitmap);
    gConsole->Printf(KDecodeToYuv, &KYuvBitmap);
       
    // Decode to ½, ¼ and 1/8 sized bitmaps 
    app->DecodeToHalfFourthAndEighthSizedBitmapL(KBitmapFile);
    gConsole->Printf(KDecodeToHalfFourthAndEighthSizedBmp, &KBitmapFile);

    // Decode using image mask    
    app->DecodeUsingImageMaskL(KMultiFrameClock);
    gConsole->Printf(KDecodeUsingImageMask);

    // Multi-frame Image Decode
    app->MultiFrameImageDecodeL(KMultiFrameClock);
    gConsole->Printf(KImageMaskAndMultiFrameImageDecode, &KMultiFrameClock);
    
    // Decode using separate thread 
    app->DecodeUsingSepThreadL(KBitmapFile);
    gConsole->Printf(KDecodeUsingSepThread);
    
    // Decode using continue convert
    app->DecodeUsingContinueConvertL(KBitmapFile);
    gConsole->Printf(KSeparateThreadAndCancelAndContinueConvert, &KBitmapFile);
    
    // JPEG thumbnail access 
    app->AccessThumbnailToDecodeL(KThumbFile);
    gConsole->Printf(KAccessThumbnailToDecode);
    
    // Access Exif metadata
    app->AccessExifMetadataL(KBitmapExif);
    gConsole->Printf(KAccessExifMetadata);
    
    // Decode the thumbnail part of the image
    app->DecodeTheThumbnailL(KThumbFile);
    gConsole->Printf(KAccessExifThumbnailAndDecodeThumbnail, &KThumbFile);
     
    // Decode and display image comments
    app->DisplayingImageCommentsL(KBitmapComment);
    gConsole->Printf(KDisplayingImageComments);

    // Decode and display frame comments
    app->DisplayingFrameCommentsL(KBitmapFrameComment);
    gConsole->Printf(KImageAndFrameComment);
     
    // Get the MIME type of a source image descriptor, and load a decoder using a MIME type
    app->GettingMimeTypeOfSourceDescriptorL(KBitmapFile);
    gConsole->Printf(KGettingMimeTypeOfSourceDescriptor);
      
    // Get the MIME type of a source image file, and load a decoder using a MIME type
    app->GettingMimeTypeOfSourceFileL(KBitmapFile);
    gConsole->Printf(KGettingMimeTypeFromSourceAndFile, &KBitmapFile);
    
    // Decode Bitmap including rotating an image
    app->DecodeWithRotateL(KBitmapFile);
    gConsole->Printf(KFileRotateAfterDecode, &KBitmapFile);

    // Load a Plugin by specific UID 
    app->LoadPluginByUidL(KBitmapExif, KImageTypeJPGUid);
    gConsole->Printf(KPluginLoadedSpecificToUID);
    
    
    gConsole->Printf(KPressAKey);
    gConsole->Getch();


    /*
    various encode functions
    */
    gConsole->Printf(KEncode);
    
    // Encode image frame (YUV) to descriptor 
    app->EncodeBitmapToDescriptorL(KSourceBitmap);
    gConsole->Printf(KFileEncode, &KSourceBitmap);
     
    // JPEG thumbnail access
    app->EncodeImageWithThumbnailL(KSourceBitmap);
    gConsole->Printf(KEncodeImageWithThumbnail);
     
    // Setting EXIF metadata 
    app->SettingExifMetadataL(KSourceBitmap);
    gConsole->Printf(KAccessToThumbnailAndExifSetting);
      
    // Rotating a bitmap
    app->RotateBitmapL(KSourceBitmap);
    gConsole->Printf(KFileRotate);
     
    // Scaling a bitmap (including optional selection of low memory and quality algorithms) 
    app->ScaleBitmapL(KSourceBitmap);
    gConsole->Printf(KScaleBitmap);
      
    // Set Source to File and destination to descriptor and resize
    app->SetSourceDestinationandResizeL(KBitmapExif);
    gConsole->Printf(KSetSourceDestinationandResize);
     
    // Set Source to descriptor and destination to File and resize
    app->SettingWithUseOfPreserveImageDataL(KYuvBitmap);
    gConsole->Printf(KSetSourceAndDestinationAndResize);
     
    // Adding thumbnail to JPEG file 
    app->AddThumbnailToJpegFileL(KBitmapExif, KYuvBitmap);
    gConsole->Printf(KAddThumbnailToJpegFile);

    // Adding Exif data to JPEG file 
    app->AddExifDataToJpegFileL(KSourceBitmap);
    gConsole->Printf(KExifAndThumbnailAdded);


    gConsole->Printf(KExitMsg); 
    gConsole->Getch();

    CleanupStack::PopAndDestroy(3);// app, scheduler, gConsole
    }


GLDEF_C TInt E32Main()
    { 
    __UHEAP_MARK;
    
    CTrapCleanup* cleanup = CTrapCleanup::New();

    if ( cleanup == NULL )
        {
        return KErrNoMemory;
        }

    TRAPD(err, MainL());
    if ( err != KErrNone )
        {
        User::Panic(KFailed,err);
        }

    delete cleanup;
    
   __UHEAP_MARKEND;
 
    return KErrNone;
    }