Initial version default tip
authorjkauppin
Fri, 15 Oct 2010 10:18:29 +0900
changeset 3 93fff7023be8
parent 2 e1e28b0273b0
Initial version
AppInc/CDrawFaceBrowsing.h
AppInc/CDrawGrid.h
AppInc/CDrawMagGlass.h
AppInc/CDrawOneByOne.h
AppInc/DrawUtility.h
AppInc/DrawableInterface.h
AppInc/FixedMath.h
AppInc/Gesture.h
AppInc/Imagic.hrh
AppInc/ImagicApp.h
AppInc/ImagicAppUi.h
AppInc/ImagicContainerBrowser.h
AppInc/ImagicDocument.h
AppInc/ImagicViewBrowser.h
AppInc/SendImageFile.h
AppInc/TextureLoader.h
AppInc/debug.h
AppInc/debug2.h
AppInc/glfont2.h
AppInc/project.h
AppSrc/CDrawFaceBrowsing.cpp
AppSrc/CDrawGrid.cpp
AppSrc/CDrawMagGlass.cpp
AppSrc/CDrawOneByOne.cpp
AppSrc/DrawUtility.cpp
AppSrc/DrawableInterface.cpp
AppSrc/Gesture.cpp
AppSrc/Imagic.cpp
AppSrc/ImagicApp.cpp
AppSrc/ImagicAppUi.cpp
AppSrc/ImagicContainerBrowser.cpp
AppSrc/ImagicDocument.cpp
AppSrc/ImagicViewBrowser.cpp
AppSrc/SendImageFile.cpp
AppSrc/TextureLoader.cpp
AppSrc/glfont2.cpp
AppSrc/project.cpp
Common/Inc/IEEngineUtils.h
Common/Inc/IEImageData.h
Common/Inc/ImagicConsts.h
Common/Inc/ImagicUtils.h
Common/Inc/debug.h
Common/Src/IEEngineUtils.cpp
Common/Src/IEImageData.cpp
Common/Src/ImagicUtils.cpp
EngInc/FileSystemMonitorAO.h
EngInc/IEBgpsController.h
EngInc/IEBitmapLoader.h
EngInc/IEEditor.h
EngInc/IEEngine.h
EngInc/IEEngineImp.h
EngInc/IEFileLoader.h
EngInc/IEImage.h
EngInc/IEImageDecoder.h
EngInc/IEImageEncoder.h
EngInc/IEImageFinder.h
EngInc/IEImageFinderAO.h
EngInc/IEImageList.h
EngInc/IESensorDataFilter.h
EngInc/IESensorMonitor.h
EngInc/IEThreadEngine.h
EngInc/ImageMonitorAO.h
EngInc/debug.h
EngInc/rrsensorapi.h
EngSrc/FileSystemMonitorAO.cpp
EngSrc/IEBgpsController.cpp
EngSrc/IEBitmapLoader.cpp
EngSrc/IEEngineImp.cpp
EngSrc/IEFileLoader.cpp
EngSrc/IEImageDecoder.cpp
EngSrc/IEImageEncoder.cpp
EngSrc/IEImageFinder.cpp
EngSrc/IEImageList.cpp
EngSrc/IESensorDataFilter.cpp
EngSrc/IESensorMonitor.cpp
EngSrc/IEThreadEngine.cpp
EngSrc/ImageMonitorAO.cpp
IEBgpClient/group/IEBgpClient.mmp
IEBgpClient/group/bld.inf
IEBgpClient/inc/IEBGPSTrace.h
IEBgpClient/inc/IEBgpClient.h
IEBgpClient/inc/IEImageProcessing.h
IEBgpClient/inc/IEImageProcessingImp.h
IEBgpClient/inc/IEImagicBGPSAO.h
IEBgpClient/inc/debug.h
IEBgpClient/src/IEBgpClient.cpp
IEBgpClient/src/IEImageProcessingImp.cpp
IEBgpClient/src/IEImagicGBPSAO.cpp
IEBgps/group/IEBgps.mmp
IEBgps/group/bld.inf
IEBgps/inc/IEBGPSTrace.h
IEBgps/inc/IEBgpServer.h
IEBgps/inc/IEBgpServerSession.h
IEBgps/inc/IEBgpsInfo.h
IEBgps/inc/IEFaceBrowser.h
IEBgps/inc/IEImageDecoder.h
IEBgps/inc/IEImageEncoder.h
IEBgps/inc/IETNGenerator.h
IEBgps/inc/debug.h
IEBgps/src/IEBgpServer.cpp
IEBgps/src/IEBgpServerSession.cpp
IEBgps/src/IEFaceBrowser.cpp
IEBgps/src/IEImageDecoder.cpp
IEBgps/src/IEImageEncoder.cpp
IEBgps/src/IETNGenerator.cpp
group/IEEngine.mmp
group/IEUtils.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/CDrawFaceBrowsing.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,107 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef DRAWFACEBROWSING_H
+#define DRAWFACEBROWSING_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include "ImagicContainerBrowser.h"
+
+
+// CLASS DECLARATION
+
+/**
+ *  CDrawFaceBrowsing
+ * 
+ */
+class CDrawFaceBrowsing : public CBase
+    {
+public:
+    // Constructors and destructor
+
+    /**
+     * Destructor.
+     */
+    ~CDrawFaceBrowsing();
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawFaceBrowsing* NewL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawFaceBrowsing* NewLC(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+    
+    void InitFaceBrowsing();
+    void DrawFaceBrowsing(const TSize &aSize);
+    void DrawFaceFrame(TInt aFace2bDrawn);
+    TBool IsDrawingNeededFaceBrowsing();
+    FloatCoords ConvertCoordsFromAlgo2OGl(const TInt aFaceIndex);
+    void GetFaceCoordinatesL(TRect& aRect, TFileName& aFilename);
+    void SetCurrentFaceNro(TInt aNro);
+    TInt GetCurrentFaceNro();
+    TInt GetNumberOfFaces();
+    void SetFaceCoords(RArray<TRect>& aCoordinates);
+    void ClearFaceArray();
+    TInt GetFaceCount();
+    void IncFaceNumber();
+    void DecFaceNumber();
+    void KeyPressed();
+    void KeyReleased();
+    void KeyEvent();
+    void GetFBZoomAndLocation(TReal& aDrawZoom, TReal& aInPictureX, TReal& aInPictureY);
+    
+private:
+
+    /**
+     * Constructor for performing 1st stage construction
+     */
+    CDrawFaceBrowsing(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+    /**
+     * EPOC default constructor for performing 2nd stage construction
+     */
+    void ConstructL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+    TBool ShowUtilities();
+    
+private:    
+    CImagicContainerBrowser* iContainer;
+    //TInt&                    iCurrentIndex;
+    RArray<TRect>            iCoordinates;
+    RArray<FloatCoords>      iFloatCoordinates;
+    TInt                     iCoordIndex;
+    TInt                     iFaceNro;
+    float                    iFBMovingSpeed;
+    TInt                     iFBRectCounter;
+    float                    iDrawWidth, iDrawHeight;//OneByOne mode image size Widht and Height
+    float                    iImageWidth, iImageHeight;
+    //float                    iDrawFBZoom;
+    float                    iDrawZoom;//Used for image scaling in OneByOne mode
+    float                    iDrawFBTargetZoom;
+    //Coordinates, when moving in picture zoomed in
+    float                    iInPictureX, iInPictureY;
+    float                    iDrawTargetX, iDrawTargetY;//target value of target X and Y
+    float                    iDrawX, iDrawY;//current value of target X and Y
+    float                    iFBZoomingSpeed;
+    TReal                    iMenuAlpha;
+    };
+
+#endif // DRAWFACEBROWSING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/CDrawGrid.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,133 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef CDRAWGRID_H
+#define CDRAWGRID_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include "ImagicContainerBrowser.h"
+
+// CLASS DECLARATION
+
+
+struct TGridXY
+    {
+    float iX;
+    float iY;
+    };
+    
+    
+/**
+ *  CDrawGrid
+ * 
+ */
+class CDrawGrid : public CBase
+    {
+public:
+    // Constructors and destructor
+
+    /**
+     * Destructor.
+     */
+    ~CDrawGrid();
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawGrid* NewL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawGrid* NewLC(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+private:
+
+    /**
+     * Constructor for performing 1st stage construction
+     */
+    CDrawGrid(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+    /**
+     * EPOC default constructor for performing 2nd stage construction
+     */
+    void ConstructL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+    
+    void MovingDirection();
+    void DisplayDate();
+    void SetPrespective(const TSize &aSize);
+    void DrawFrame(TInt aIndex);
+    void BubbleEffect(TInt& x, TInt& y, float& z);
+    void HandleKeys();
+    
+public:
+    void InitDrawGrid();
+    void DrawGridL(const TSize &aSize);
+    TBool IsDrawingNeededGrid();
+    TReal GetCurrentGridTilt();
+    TReal GetGridZoom();
+    TGridXY GetGridTargetXY();
+    void SetGridTargetXY(TGridXY aValue);
+    TGridXY GetGridXY();
+    void SetGridXY(TGridXY aValue);
+    void UpdateImageCoordinates(const TInt aFirstIndex);    
+    void KeyPressed();
+    void KeyReleased();
+    void KeyEvent();
+    
+    CImagicContainerBrowser* iContainer;
+    
+    float               iPerspectiveCurrent;//current value of perspective when moving on grid by tilting while grid
+    //float               iPerspectiveTarget;//target value of perspective
+    float               iGridMovingSpeed;
+    float               iGridZoomSpeed;//zoom value in Grid
+    float               iGridZoomStep;//zoom value in Grid
+    float               iDrawGridZoom;//Holds zooming value for Grid
+    float               iDrawGridTargetZoom;//Holds target zooming value for Grid
+    float               iTargetPerspective;
+    TBool               iIntheEndOfGrid;
+    TBool               iJumpOver;
+    TUint               iLastGridTexture;
+    TBool               iMovingRight;
+    TBool               iMovingLeft;
+    TDateTime           iPrevDateTime;
+    TGridXY             iDrawGridXY;
+    TGridXY             iDrawGridTargetXY;
+    
+    
+    
+    //variables used in Buble mode
+    TBool               iBubbleEffect;//Flag for "Bubble" effect to set it on/off
+    TInt                iDistanceX;
+    TInt                iDistanceY;
+    TInt                iDiff;
+    TInt                iDistX;
+    TInt                iDistY;
+    TInt                iBindDiff;
+    
+    
+    TInt                iKeyTimer;
+    TInt                iKeyTimer2;
+    
+    TReal               iMenuAlpha;
+    
+    float               iScaleTarget;
+    };
+
+#endif // CDRAWGRID_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/CDrawMagGlass.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,90 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef DRAWMAGGLASS_H
+#define DRAWMAGGLASS_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include "ImagicContainerBrowser.h"
+#include "CDrawOneByOne.h"
+
+#define VERTICES_PER_LINE 32
+
+// CLASS DECLARATION
+class CDrawOneByOne;
+
+
+/**
+ *  CDrawMagGlass
+ * 
+ */
+class CDrawMagGlass : public CBase
+    {
+public:
+    // Constructors and destructor
+
+    /**
+     * Destructor.
+     */
+    ~CDrawMagGlass();
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawMagGlass* NewL(CImagicContainerBrowser* aContainer, CDrawOneByOne* aDrawOneByOne);
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawMagGlass* NewLC(CImagicContainerBrowser* aContainer, CDrawOneByOne* aDrawOneByOne);
+
+private:
+
+    /**
+     * Constructor for performing 1st stage construction
+     */
+    CDrawMagGlass();
+
+    /**
+     * EPOC default constructor for performing 2nd stage construction
+     */
+    void ConstructL(CImagicContainerBrowser* aContainer, CDrawOneByOne* aDrawOneByOne);
+    void Interpolate(float &aValue, const float aTarget, const float aStep);
+    
+public:
+    void InitDrawMagGlass();
+    void DrawMagGlass(const TSize &aScreenPhysicalSize, TReal aImageAspectRatio);
+    TReal GetMagGlassZoomFactor();
+    
+private:
+    CImagicContainerBrowser* iContainer;
+    CDrawOneByOne*           iDrawOneByOne;
+    
+    float                    iMagGlassZoomFactor;
+    
+    
+    static const GLfixed iGlobalTexCoords[4*2];
+    static GLfixed       iMagGlassVertices[VERTICES_PER_LINE*VERTICES_PER_LINE*3];
+    static GLfixed       iMagGlassTex[VERTICES_PER_LINE*VERTICES_PER_LINE*2];
+           
+    static const TInt    iMagGlassTriCount;
+    static GLushort      iMagGlassIndices[];
+    };
+
+#endif // DRAWMAGGLASS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/CDrawOneByOne.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,146 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef DRAWONEBYONE_H
+#define DRAWONEBYONE_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include "ImagicContainerBrowser.h"
+#include "CDrawMagGlass.h"
+
+
+
+class CDrawMagGlass;
+
+struct TDrawOneByOneXY
+    {
+    float iX;
+    float iY;
+    };
+
+// CLASS DECLARATION
+
+/**
+ *  CDrawOneByOne
+ * 
+ */
+class CDrawOneByOne : public CBase
+    {
+public:
+    // Constructors and destructor
+
+    /**
+     * Destructor.
+     */
+    ~CDrawOneByOne();
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawOneByOne* NewL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+    /**
+     * Two-phased constructor.
+     */
+    static CDrawOneByOne* NewLC(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+private:
+
+    /**
+     * Constructor for performing 1st stage construction
+     */
+    CDrawOneByOne(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+
+    /**
+     * EPOC default constructor for performing 2nd stage construction
+     */
+    void ConstructL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex);
+    void CheckImageLocation(/*float& aImageWidth, float& aImageHeight*/);
+    void HandleMovingKeysOnebyOne();
+    
+public:
+    void InitDrawOnebyOne(TReal aDrawZoom, TReal aInPictureX, TReal aInPictureY);
+    void DrawOnebyOneL(const TSize &aSize);
+    TBool IsDrawingNeededOneByOne();
+    float GetMovingStep();
+    float GetImgeFlowLocation();
+    void SetImgeFlowLocation(float aValue);
+    TDrawOneByOneXY GetDrawOneByOneXY();
+    TDrawOneByOneXY GetDrawOneByOneTargetXY();
+    void SetDrawOneByOneTargetXY(TDrawOneByOneXY aValue);
+    void ChangeDrawOneByOneTargetX(float aValue);
+    void ChangeDrawOneByOneTargetY(float aValue);
+    float GetDrawOneByOneZoom();
+    void SetDrawOneByOneZoom(float aValue);
+    float GetDrawOneByOneTargetZoom();
+    void SetDrawOneByOneTargetZoom(float aValue);
+    float GetDrawOneByOneWidth();
+    void SetDrawOneByOneWidth(float aValue);
+    float GetDrawOneByOneHeight();
+    void SetDrawOneByOneHeight(float aValue);
+    
+    TBool IsMagGlassOn();
+    void SetMagGlassStatus(TBool aValue);
+    TBool IsMagGlassPrevStateOn();
+    void SetMagGlassPrevStatus(TBool aValue);
+    CDrawMagGlass* GetMagGlass();
+    void KeyPressed();
+    void KeyReleased();
+    void KeyEvent();
+
+    
+    
+private:    
+    CImagicContainerBrowser* iContainer;
+    CDrawMagGlass*           iMagGlass;
+    
+    float                    iMovingSpeed;
+    float                    iMovingStep;
+    
+    float                    iZoomingStep;
+    float                    iZoomingSpeed;
+    float                    iScalingSpeed;
+    float                    iOneByOneFlow;
+    
+    TDrawOneByOneXY          iDrawOneByOneXY;
+    TDrawOneByOneXY          iDrawOneByOneTargetXY;
+    float                    iDrawOneByOneZoom;//Used for image scaling in OneByOne mode
+    float                    iDrawOneByOneTargetZoom;//Used for image zooming in OneByOne mode
+    float                    iDrawOnebyOneW, iDrawOnebyOneH;//OneByOne mode image size Widht and Height
+    float                    iInPictureX, iInPictureY;
+    //when moving in picture zoomed in, this defines value how we can go over the image boundary
+    float                    iBorder;
+    //Size of the screen, when moving in picture zoomed in
+    float                    iScreenW;
+    float                    iScreenH;
+    float                    iImageWidth;
+    float                    iImageHeight;
+    float                    iFadeColor;
+    //MagGlass
+    TBool                    iMagGlassOn;
+    TBool                    iMagGlassOnPrev;
+    float                    iFlowThresHold;
+    TReal                    iMenuAlpha;
+    
+public:
+    static const float KMaxMagGlassZoomFactor;
+    
+    };
+
+#endif // DRAWONEBYONE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/DrawUtility.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef LOADING_ANIMATION_H
+#define LOADING_ANIMATION_H
+
+/*--------------------------------------------------------------------------*/
+
+//#include "DrawableInterface.h"
+#include "ImagicContainerBrowser.h"
+//#include "ImagicAppUi.h"
+#include <GLES\egl.h>
+
+class CImagicContainerBrowser;
+/*--------------------------------------------------------------------------*/
+
+class CDrawUtility //: public CDrawableInterface
+	{
+	private:
+		// 1st and 2nd stage constructors
+		CDrawUtility();
+		void ConstructL(CImagicContainerBrowser* aContainer);
+	public:
+		// NewL and destructor
+		//static CDrawableInterface* NewL(void);
+	    static CDrawUtility* NewL(CImagicContainerBrowser* aContainer);
+		~CDrawUtility();
+		
+		// Update animation
+		// Returns true if screen should be redrawn
+		TBool Update(void);
+		// Draw animation
+		void Draw(const TSize &aScreenSize);
+		void DrawIcon(const TSize &aScreenSize, GLuint aTexIndex);
+		void DrawIcon2(const TSize &aScreenSize, GLuint aTexIndex, TReal aAlpha);
+		void DrawZoomIcon(const CImageData* aImageData,
+                          const TSize aScreenSize, 
+                          float aDrawOneByOneX, 
+                          float aDrawOneByOneY,
+                          TReal aDrawOnebyOneW, 
+                          TReal aDrawOnebyOneH,
+                          TBool aShowLocationRect);
+		void DrawZoomFrame(float aRotationTarget);
+		void DrawFrame(TInt aIndex);
+		void DrawMovingArrow(TBool aPrevArrow, TBool aUpDownArrow, const TSize& aScreenSize);
+		void DrawMenuIndicators(const TSize& aScreenSize);
+		
+	private:
+		// Makes sure that angle is on valid range
+		void LimitAngle(TInt &Angle);
+		void SetPictureVertices(GLfixed* aVertices, TReal aAspectRatio);
+		
+		
+		// Rotation angles
+		TInt iAngleX;
+		TInt iAngleY;
+		TInt iAngleZ;
+		
+		// Mesh data
+		static const TInt iTriCount;
+		static const GLfixed iVertices[4*3];
+		static const GLfixed iNormals[4*3];
+		static const GLushort iIndices[4*3];
+		
+		CImagicContainerBrowser* iContainer;
+		float iRotation; 
+		float iRotationTarget;
+		TSize iScrSize;
+		TSize iThumbSize;
+		TSize iZoomRectSize;
+		TReal iAspectRatio;
+		float iDrawOneByOneX; 
+        float iDrawOneByOneY;
+        TReal iScrAspectratio;
+        TReal iDrawOnebyOneW; 
+        TReal iDrawOnebyOneH;
+	};
+
+/*--------------------------------------------------------------------------*/
+
+#endif // LOADING_ANIMATION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/DrawableInterface.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef DRAWABLE_INTERFACE_H
+#define DRAWABLE_INTERFACE_H
+
+/*--------------------------------------------------------------------------*/
+
+#include <e32std.h>
+#include <e32base.h>
+
+
+/*--------------------------------------------------------------------------*/
+
+class CDrawableInterface : public CBase
+	{
+	protected:
+		// Constructor
+		CDrawableInterface();
+		//virtual void ConstructL(void) =0;
+	public:
+		// Destructor
+		virtual ~CDrawableInterface();
+		
+		// Pure virtual Update and Draw functions
+		
+		// Update, returns true if screen should be redrawn
+		virtual TBool Update(void) =0;
+		// Draw, takes screen size as a argument
+		virtual void Draw(const TSize &aScreenSize) =0;
+	};
+
+/*--------------------------------------------------------------------------*/
+
+#endif // DRAWABLE_INTERFACE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/FixedMath.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+//------------------------------
+#ifndef FIXED_MATH_H_
+#define FIXED_MATH_H_
+//------------------------------
+ 
+// INCLUDES
+#include <e32base.h>
+#include <e32std.h>
+#include <e32math.h>
+#include <GLES/gl.h>   
+ 
+// FUNCTIONS
+ 
+inline GLfixed IntToFixed (GLint aValue)
+{ return aValue << 16; }
+ 
+ 
+inline GLfixed FloatToFixed (GLfloat aValue)
+{ return (GLfixed) (aValue * 65536.0f); }
+ 
+ 
+inline GLint FixedToInt (GLfixed aValue)
+{ return aValue >> 16; }
+ 
+ 
+inline GLfloat FixedToFloat (GLfixed aValue)
+{ return (GLfloat) (aValue * (1 / 65536.0f)); }
+ 
+ 
+inline GLfixed MultiplyFixed (GLfixed op1, GLfixed op2) 
+{
+  TInt64 r = (TInt64)op1 * (TInt64)op2;
+  return (GLfixed) (r >> 16);
+}
+ 
+ 
+//------------------------------
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/Gesture.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,238 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef GESTURE_H
+#define GESTURE_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include <w32std.h>
+
+#undef CURSOR_SIMULATION
+
+const TInt KDefaultThresholdOfTapPixels      = 25;
+const TInt KDefaultThresholdOfCursorPixels   = 0;      // Any movement is cursor movement 
+const TInt KDefaultStationaryTime            = 100000; // 100ms
+const TInt KDefaultLongTapTime               = 400000; // 300ms = 200ms + stationary (100ms)  
+const TInt KDefaultMonitoringTime            = 200000; // 200ms
+const TInt KDefaultSafetyTime                = 200000; // 200ms
+const TInt KDefaultValidityTimeOfFlick       = 300000; // recent 300ms drag to be checked 
+
+enum {
+    EGestureNone        = 0x0000,
+    EGestureStationary  = 0x0001,  // Send on moved event when user hasn't moved finger
+    EGestureDrag        = 0x0002,
+    EGestureTap         = 0x0004,
+    EGestureLongTapping = 0x0008,
+    EGestureLongTap     = 0x0010,
+    EGestureCursor      = 0x0100,
+    // sub-type for cursor simuation
+    EGestureUp          = 0x1000,
+    EGestureDown        = 0x2000,
+    EGestureLeft        = 0x4000,
+    EGestureRight       = 0x8000,
+    // 1st gesture type is stored in high 16 bits
+    EGestureDragged     = EGestureDrag    << 16,
+    EGestureTapped      = EGestureTap     << 16,
+    EGestureLongTapped  = EGestureLongTap << 16
+};
+// Gestures can be combination
+typedef TUint32 TGestureType;
+
+#define IS_GESTURE_NONE(t)             ((t) == (EGestureNone))
+#define IS_GESTURE_DRAG(t)             ((t) & (EGestureDrag))
+#define IS_GESTURE_STATIONARY(t)       ((t) & (EGestureStationary))
+#define IS_GESTURE_CURSORSIMULATION(t) ((t) & ((EGestureUp | EGestureDown | EGestureLeft | EGestureRight)))
+#define IS_GESTURE_TAP(t)              ((t) & (EGestureTap))
+#define IS_GESTURE_TAPPED(t)           ((t) & (EGestureTapped))
+#define IS_GESTURE_LONGTAPPING(t)      ((t) & (EGestureLongTapping))
+#define IS_GESTURE_LONGTAP(t)          ((t) & (EGestureLongTap))
+#define IS_GESTURE_DRAGGED(t)          ((t) & (EGestureDragged))
+#define IS_GESTURE_SINGLETAP(t)        (IS_GESTURE_TAP(t) && !IS_GESTURE_TAPPED(t))
+#define IS_GESTURE_DOUBLETAP(t)        (IS_GESTURE_TAP(t) && IS_GESTURE_TAPPED(t))
+#define IS_GESTURE_TAPnDRAG(t)         (IS_GESTURE_CURSORSIMULATION(t) && IS_GESTURE_TAPPED(t))
+
+enum {
+    EGestureModeNone                  = 0x00,
+    EGestureModeCursorEmulation       = 0x01, // gives cursor movements when beyond threshold
+    EGestureModeSingleCursorEmulation = 0x02, // gives singles cursor movement on each touch
+    EGestureModeDrag                  = 0x04, // 
+    EGestureModeTap                   = 0x08,
+    EGestureModeTapAndDrag            = 0x10,
+    EGestureModeDrawCircle            = 0x20
+};
+
+// CLASS DECLARATION
+
+class MGestureCallBack
+    {
+public:
+    /**
+    * Callback method. Get's called when touch gesture started (when user touches).
+    * @param aPos  Point where touch happens
+    * @param aType Gesture type bit flag (move_right/left/up/down or tap)
+    */
+    
+    // Called when user touches screen
+    virtual void HandleGestureBeganL(const TPoint&      aPos ) = 0;
+
+    // Called when user is dragging
+    // Drag event comes with movement delta from previous event (EGestureDrag)
+    // Drag event comes with touched position (EGestureUp/Down/Left/Right)
+    //   when it exceeds defined threshold
+    virtual void HandleGestureMovedL(const TPoint&      aPos,
+                                     const TGestureType aType) = 0;
+
+    // Called when user releases screen
+    // Movement within defined last moment is given in aPos. (pixels/250ms by default)
+    virtual void HandleGestureEndedL(const TPoint&      aPos,
+                                     const TGestureType aType) = 0;
+    };
+
+/**
+ *  CGesture
+ * 
+ */
+class CGesture : public CTimer
+    {
+public:
+    // Constructors and destructor
+
+    /**
+     * Destructor.
+     */
+    ~CGesture();
+
+    /**
+     * Two-phased constructor.
+     */
+    static CGesture* NewL(MGestureCallBack* aOwner);
+
+    /**
+     * Two-phased constructor.
+     */
+    static CGesture* NewLC(MGestureCallBack* aOwner);
+
+private:
+
+    /**
+     * Constructor for performing 1st stage construction
+     */
+    CGesture(MGestureCallBack* aOwner);
+
+    /**
+     * EPOC default constructor for performing 2nd stage construction
+     */
+    void ConstructL();
+
+public: // New functions
+
+    IMPORT_C void PointerEventL(const TPointerEvent& aEvent);
+    IMPORT_C void SetThresholdOfTap(const TInt aPixels);
+    IMPORT_C void SetThresholdOfCursor(const TInt aPixels);
+    IMPORT_C void SetStationaryTime(const TInt aMicroseconds);
+    IMPORT_C void SetLongTapTime(const TInt aMicroSeconds);
+    IMPORT_C void SetMonitoringTime(const TInt aMicroseconds);
+    IMPORT_C void SetSafetyTime(const TInt aMicroseconds);
+
+private:
+
+    enum TGestureState
+        {
+        EWaiting,          // Waiting for first touch
+        EBegan,            // Touch down. Gesture started (or second gesture)
+        EStationary,       // Gesture is stationary
+        ETravelling,       // Dragging beyond threshold
+        EMonitoring,       // Monitoring second gesture
+        EEnded             // Touch operation ended. Wait to avoid mis touch
+        };
+
+    /**
+     * Just check if the movement exceeds thoreshold
+     */
+    TBool IsMovementWithinThreshold(const TPoint aDelta, const TInt aThreshold);
+
+    /**
+     * Map touch movement to 8-directions if volume of movement exceeds threshold
+     * Also check if movement is faster than threshold
+     */
+    TGestureType CheckMovement(const TPoint aPointPrevious, const TPoint aPointCurrent, const TBool aSkipThresholdCheck=EFalse);
+
+    /**
+     * Maps touch movements in last defines time, aValidityTime, to 8-directions
+     * Movements are recorded in iDragPoints and iDragTicks (RArray of TPoint and TInt)
+     */
+    TGestureType CheckFlick(const TInt aValidityTime, TPoint& aVector);
+
+    /**
+     * Active object callback. Used for timer
+     */
+    void RunL();
+
+private: // Data
+
+    /**
+     * Current state of Gesture
+     */
+    TGestureState iState;
+    
+    /**
+     * Pointer to owner
+     */
+    MGestureCallBack* iOwner;
+
+    /**
+     * Pointer event received from owner.
+     */
+    TPointerEvent iPointerEvent;
+
+    /**
+     * Point records
+     */
+    TPoint iPointBegan;         // point where user touched down
+    TPoint iPointFirstBegan;    // point where user touched down in 1st gesture
+    TPoint iPointLastCursor;    // point where last cursor simulation event occured
+    TPoint iPointPreviousEvent; // last point where avkon informed on drag
+
+    /**
+     * Remembers gesture in 1st gesture
+     */
+    TGestureType iFirstGesture;
+
+    /**
+     * Thresholds in Pixels
+     */
+    TInt iThresholdOfTap;       // movement stays within this pixels
+    TInt iThresholdOfCursor;    // cursor simulation occurs when exceeding threshold
+    
+    /**
+     * Thresholds in Micro seconds
+     */
+    TInt iStationaryTime;       // UP should occur within the time for Tap 
+    TInt iLongTapTime;          // for long tap
+    TInt iMonitoringTime;       // for 2nd gesture. Notify gesture end if expires
+    TInt iSafetyTime;           // Ignores gesture after Ended to avoid mis-touch
+     
+    /**
+     * Drag points and the tick time for flick
+     */
+    RArray<TPoint> iDragPoints;
+    RArray<TInt>   iDragTicks;
+    };
+
+#endif // GESTURE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/Imagic.hrh	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGIC_HRH
+#define IMAGIC_HRH
+
+
+///////////////////////////////////////////////////////////////
+
+/** HuiSimpleImage enumerate command codes */
+/*
+enum THuiSimpleImageIds
+    {
+    EHuiSimpleImageCommand1 = 1,  // start value must not be 0
+    EHuiSimpleImageCommand2 = 2
+    };
+*/
+///////////////////////////////////////////////////////////////
+
+enum TDialogCommands
+    {
+    ESavingNote = 10000
+    };
+
+enum TImagicCommandIds
+    {
+    EImagicCmdAppTest1 = 1,
+    EImagicCmdViewCmd1,
+    EImagicCmdViewCmd2,
+    EImagicCmdViewCmd3,
+    EImagicCmdViewCmd4,
+    EImagicCmdViewCmd5,
+    EImagicCmdViewBrowserCmd1,
+    EImagicCmdViewBrowserCropping,
+    EImagicCmdViewBrowserDrawFaces,
+    EImagicCmdViewBrowserRotateRight,
+    EImagicCmdViewBrowserRotateLeft,
+    EImagicCmdViewBrowserDelete,
+    EImagicCmdViewBrowserRemoveFace,
+    EImagicCmdViewBrowserAddNewFace,
+    EImagicCmdViewBrowserAddAsThisNewFace,
+    EImagicCmdViewBrowserFaceCropping,
+    EImagicCmdViewBrowserGridModeFolder,
+    EImagicCmdViewBrowserGridModeTime,
+    EImagicCmdViewBrowserGridModePeople,
+    EImagicCmdViewWizardEditCmd1,
+    EImagicCmdViewWizardEditCmd2,
+    EImagicCmdViewWizardEditCmd3,
+    EImagicCmdViewWizardEditCmd4,
+    EImagicCmdViewCropCmd1,
+    EImagicCmdViewCropCmd2,
+    EImagicCmdViewCropCmd3,
+    EImagicCmdViewCropCmd4,
+    EImagicCmdHUIViewRotateCmd1,
+    EImagicCmdHUIViewRotateCmd2,
+    EImagicCmdViewRotateCmd1,
+    EImagicCmdViewRotateCmd2,
+    EImagicCmdViewEdit,
+    EImagicCmdViewBrowserShowImageInfo,
+    EImagicCmdViewFaceBrowsing,
+    EImagicCmdViewFaceBrowsingWithCoordinates,
+    ECmdRotateImage,
+    EImagicWaitDialogNote,
+    EImagicCmdViewBrowserHelp,
+    EImagicCmdViewBrowserSend
+    
+    };
+
+enum TImagicTabViewId
+    {
+    EImagicView1Tab= 1,
+    EImagicView2Tab
+    };
+ 
+
+
+
+#endif      // Imagic_HRH
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/ImagicApp.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGICAPP_H
+#define IMAGICAPP_H
+
+// INCLUDES
+#include <aknapp.h>
+#include "../group/UidList.txt"
+
+// CONSTANTS
+const TUid KUidImagic = { Imagic_UID3  }; //0xE1EF0018
+
+
+// CLASS DECLARATION
+
+/**
+* CImagicApp application class.
+* Provides factory to create concrete document object.
+* 
+*/
+class CImagicApp : public CAknApplication
+    {
+    
+    private:
+
+        /**
+        * From CApaApplication, creates CImagicDocument document object.
+        * @return A pointer to the created document object.
+        */
+        CApaDocument* CreateDocumentL();
+        
+        /**
+        * From CApaApplication, returns application's UID (KUidImagic).
+        * @return The value of KUidImagic.
+        */
+        TUid AppDllUid() const;
+    };
+
+#endif
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/ImagicAppUi.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,276 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGICAPPUI_H
+#define IMAGICAPPUI_H
+
+// INCLUDES
+#include <eikapp.h>
+#include <eikdoc.h>
+#include <e32std.h>
+#include <coeccntx.h>
+#include <aknviewappui.h>       // View AppUi adds View handling to AppUi
+#include <aknnavide.h>
+#include <BAUTILS.H> 
+#include <exifmodify.h> 
+#include "ImagicConsts.h"
+#include "HLPLCH.H" 
+//#include <oommonitorclient.h>
+//#include <oommonitorsession.h>
+
+//Hitchcock
+#ifdef HITCHCOCK
+#include <hitchcock.h>
+#include "ImagicHUIViewRotate.h"
+#endif
+// Image converter library API header
+#include <ImageConversion.h>
+// Bitmap transforms API header
+#include <BitmapTransforms.h>
+//#include "IEFileLoader.h"
+
+//IE engine header
+#include <IEEngine.h>
+#include "debug.h"
+#include <aknwaitdialog.h>
+#include "ImagicContainerBrowser.h"
+#include "IEImage.h"
+
+// UID of view
+//const TUid EditMainView = {1};
+const TUid DummyUID = {1};
+const TUid BrightnessAdjustment = {2};
+const TUid ContrastAdjustement = {3};
+const TUid BrowserView = {4};
+const TUid Crop = {5};
+const TUid SharpnessAdjustement = {6};
+const TUid Resize = {7};
+const TUid Zoom = {8};
+const TUid Rotate = {9};
+const TUid ColorAdjustement = {10};
+const TUid GammaAdjustement = {11};
+const TUid LocalContrastAdjustement = {12};
+const TUid HUIRotate = {13};
+const TUid HUICrop = {14};
+
+//Error IDs
+const TUid KErrorId= { -1 };    // MessageUid to send
+
+
+// FORWARD DECLARATIONS
+class CImagicHUIViewRotate;
+class CImagicHUIViewCrop;
+class CImagicViewBrowser;
+class CImagicContainerBrowser;
+class CImagicContainerCrop;
+class CImagicViewWizardEdit; 
+//IE Engine
+class MIEEngineObserver;
+class CIEEngine;
+
+class CImagicUtils;
+ 
+
+enum TStatus
+    {
+    ENormal = 1,
+    EProcessing,
+    EDone,
+    ESaving,
+    EError
+    };
+
+enum TImageQuality
+    {
+    ELQTextIndex,//OpenGL 128x128 texture index
+    EHQTextIndex,//OpenGL 512x512 texture index
+    ESuperHQTextIndex//OpenGL 2048x2048 texture index
+    };
+
+/**
+* Application UI class. CAknViewAppUi derives from CAknAppUi and has view handling methods added.
+* Provides support for the following features:
+* - EIKON control architecture
+* - view architecture
+* - status pane
+* 
+*/
+//CAknViewAppUi derived from CEikAppUi
+class CImagicAppUi : public CAknViewAppUi, public MIEEngineObserver
+    {
+    public: // // Constructors and destructor
+
+        /**
+        * EPOC default constructor.
+        */      
+        void ConstructL();
+
+        /**
+        * Destructor.
+        */      
+        ~CImagicAppUi();
+        
+    private:
+        // From MEikMenuObserver
+        // With this, we can dynamically activate/deactivate menu items.
+        void DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane);
+        
+        CArrayFix<TCoeHelpContext>* CImagicAppUi::HelpContextL() const;
+        void ScreenImmeadetaUpdate();
+        
+    public:
+        void DestructEngine();
+        void SetActiveView(TUid aViewNro);
+        TUid GetActiveView();
+        
+        TInt GetImageIndex();
+        void SetImageIndex(TInt aIndex);
+#ifdef _ACCELEROMETER_SUPPORTED_
+        void ImageRotated(TImagicDeviceOrientation aDeviceOrientation);
+#endif
+        CIEEngine* GetEngine();
+        
+        void GetWizardImagesL(TInt aIndex, TIEFeature aFeature);
+        void SavedImageReady(CFbsBitmap* croppedBitmap);
+        //TInt GetTotalImages();
+        
+        void SetFileNameForEditing(TFileName aFileName);
+        TFileName GetFileNameForEditing();
+        static TInt TimerCallBack(TAny* aPtr);
+        
+        static TInt ExitTimerCallBack(TAny* aPtr);
+        //void SetFont();
+        
+        //from class MIEEngineObserver
+        void WizardImagesReadyL();
+        void FeatureCompleteL(TIEFeature aFeature, TInt aError);
+        void FeatureErrorL(TIEFeature aFeature, TInt aError);
+        void ImagesLoadedL(TInt aError);
+        void EditedImageSavedL(TInt aError);
+        //void SetNumberOfImages(TInt aCount);
+        //void SetNumberOfFaceImages(TInt aCount);
+        void TNCreationCompleteL(TThumbSize aTnRes);
+        void SingleTNCreationCompletedL(TInt aIndex, TThumbSize aTnRes);
+        void FaceDetectionComplete();
+        void SingleFaceDetectionComplete();
+        void AllFilesScanned();
+        void ImageListChanged(TInt aIndex, TBool aAdded);
+        
+        CImagicUtils *GetImagicUtils();
+        TInt GetErrorCode();
+        //TRgb GetTransparentWhite();
+        //TRgb GetTransparentBlack();
+        //const CFont* GetFont();
+        
+    public:
+        TInt DeleteImage(TInt aIndex);
+        void SetTNGenerationFlag(TBool aValue);
+        void SetUIDrawMode(TImageArrayMode aMode);
+        //TImageArrayMode GetUIDrawMode();
+        void CImagicAppUiReady();
+        void BrowserContainerInitialized();
+        TInt GetGleMaxRes();
+        TBool IsAppOnTop();
+        
+    private:
+        
+        TInt iNoOfFacesDetected;
+        RArray<TRect> iFaceCoOrdinates;
+        
+    private:
+        /**
+        * From CEikAppUi, takes care of command handling.
+        * @param aCommand command to be handled
+        */
+        void HandleCommandL(TInt aCommand);
+        
+        
+        /**
+        * From CEikAppUi, handles key events.
+        * @param aKeyEvent Event to handled.
+        * @param aType Type of the key event. 
+        * @return Response code (EKeyWasConsumed, EKeyWasNotConsumed). 
+        */
+        virtual TKeyResponse HandleKeyEventL(
+            const TKeyEvent& aKeyEvent,TEventCode aType);
+
+        void HandleForegroundEventL(TBool aForeground);
+
+	    /**
+	    * From CEikAppUi, handles key events.
+	    * @param aType The type of resources that have changed
+	    */    
+	    virtual void HandleResourceChangeL( TInt aType );  
+	    
+	    
+    private: //Data
+        /** Active object that is the timing source for the clearing OpenGL memory. */
+        CPeriodic*                  iPeriodic;
+        CImagicContainerBrowser*    iBrowserContainer;
+        CImagicContainerCrop*       iCropContainer;
+        CImagicUtils*               iImagicUtils;
+        CIEEngine*                  iIEngine;
+        
+        TUid						iViewIdEditorMain;
+		TUid 						iViewIdBrowser;
+		TUid 						iViewIdWizardEdit;
+		TUid 						iViewIdCrop;
+		TUid                        iViewIdRotate;
+		TUid                        iViewHUIIdRotate;
+		TUid                        iViewHUIIdCrop;
+		TInt						iImageIndex;
+	    TUid						iViewNro;
+	    
+	    //TInt                        iTotalNumOfImages;
+	    //TInt                        iNumOfImagesLoaded;
+	    //TInt                        iNumOfFacesLoaded;
+	    RArray<CFbsBitmap*>         iWizardBitmapArray;
+	    //TIEFeature                  iFeature;
+	    TInt                        iFeatureError;
+	    
+	    const CFont*                iFont;
+	    TRgb                        iTransparentWhite;
+        TRgb                        iTransparentBlack;
+        TBool                       iImagesLoaded;
+        TFileName                   iFileName;
+        CAknWaitDialog*             iWaitDialog;
+        
+        TBool                       iWzContainerSatus;
+        TBool                       iAppActiveState;
+        
+        TBool                       iWaitingForIdleTimer;
+        TBool                       iWaitingForTimer;
+        
+        RFs                         iFileServer;
+        TBool                       iTNGenerationOnGoing;
+        
+        CAknWaitDialog*             iExitWaitDialog;
+        
+        CPeriodic*                  iExitPeriodic;
+        TInt                        iNumberOfIterations;
+        
+        RArray<TRect>               iCoordinates;
+        TImageArrayMode             iUIDrawMode;
+        TBool                       iMenuOn;
+        TBool                       iAppForeGround;
+        
+        //ROomMonitorSession*         iMemoryRequester;
+    };
+
+#endif
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/ImagicContainerBrowser.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,494 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGICCONTAINERBROWSER_H
+#define IMAGICCONTAINERBROWSER_H
+
+//#define ADAPTIVE_FRAMERATE   // adaptive frame rate
+#define MOMENTUM_MOVE
+#define DOUBLETAP_FACEBROWSING
+#define DOUBLETAP_SELECT_IN_GRID
+#define SINGLETAP_CLOSE_IN_ZOOM
+#define FLICK_ONLY_IN_X_IN_GRID
+#define HOLD_SELECTION_ONDRAG
+#undef  CURSORSIMULATION_IN_GRID
+#undef  CURSORSIMULATION_IN_ONEBYONE
+#undef  CURSORSIMULATION_IN_FACEBROWSER
+#undef  SELECT_ON_TOUCHDOWN
+#undef  TAP_AND_GESTURE
+//#undef  DOUBLETAP_ZOOMGRID
+#undef  USE_AVKON_LONGTAP_DETECTOR
+
+//#undef RD_FACEFRAME
+#define RD_FACEFRAME
+#define RD_ZOOMICON
+
+// INCLUDES
+#include <coecntrl.h>
+#include <aknnotewrappers.h>
+#include <aknlongtapdetector.h>
+#include <GLES\egl.h>
+#include "ImagicAppUi.h"
+#include <HWRMLight.h>
+#include "Gesture.h"
+#include "ImagicUtils.h"
+#include "DrawableInterface.h"
+#include "DrawUtility.h"
+#include "CDrawGrid.h"
+#include "CDrawOneByOne.h"
+#include "CDrawFaceBrowsing.h"
+#include "CDrawMagGlass.h"
+
+
+#ifdef USE_AVKON_TACTILE_FEEDBACK
+#include <touchfeedback.h>
+#include <touchlogicalfeedback.h>
+#endif
+
+//#define VERTICES_PER_LINE 32
+
+
+// FORWARD DECLARATIONS
+class CImagicViewBrowser;
+class CImagicAppUi;
+class CGLImageHandler;
+class CTextureLoader;
+class CDrawUtility;
+class CDrawGrid;
+class CDrawOneByOne;
+class CDrawFaceBrowsing;
+class CDrawMagGlass;
+
+
+
+// Variables telling how many times keys has been pressed
+class CKeyData
+	{
+public:
+    //void ResetData();
+    
+	//these variables hold number of key presses as long they are consumed
+	//value must be reset after usage
+	TInt iX,iY;		// Movement keys
+	TInt iRotate;	// Rotation keys
+	//TInt iZoom;		// Zooming keys
+	
+	// Tells if button is currently pressed
+	TBool iLeft,iRight;
+	TBool iUp,iDown;
+	//TBool iZoomIn, iZoomOut;
+	TBool iZoomInKey, iZoomOutKey;
+    };
+
+
+// CLASS DECLARATION
+
+/**
+*  CImagicContainerBrowser  container control class.
+*  
+*/
+class CImagicContainerBrowser : public CCoeControl, MCoeControlObserver
+    , MAknLongTapDetectorCallBack
+    , MGestureCallBack
+    {
+    public: // Constructors and destructor
+        
+        //Drawing functions
+        enum TDrawFunction
+            {
+            EGrid,
+            EOneByOne,
+            EFaceBrowser,
+            ELastDrawFunction
+            };
+
+        //Grid Drawing modes
+        enum TGridMode
+            {
+             EListof3 = 1,
+             EListof5,
+             ESquare
+            };
+        
+        /**
+        * EPOC default constructor.
+        * @param aRect Frame rectangle for container.
+        */
+        void ConstructL(CImagicAppUi* aImagicAppUi, CImagicViewBrowser* aView, const TRect& aRect);
+
+        /**
+        * Destructor.
+        */
+        ~CImagicContainerBrowser();
+        
+        //void SetBitmapArrayL(CFbsBitmap* aBitmap);
+        void ImageLoadedL(TInt aError, CFbsBitmap* aBitmap, TThumbSize aResolution/*, TInt aLoadedImageIndex*/);
+        
+        TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);
+        // Handle any tap on the screen
+        void HandlePointerEventL(const TPointerEvent& aPointerEvent);
+
+        // From MAknLongTapDetectorCallBack
+        void HandleLongTapEventL(const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation);
+        void HandleGestureBeganL(const TPoint& aPos);
+        void HandleGestureMovedL(const TPoint& aPos, const TGestureType aType);
+        void HandleGestureEndedL(const TPoint& aPos, const TGestureType aType);
+
+        void DoTapAndDrag(const TPoint& aPos, const TGestureType aType);
+        void DoCursorSimulation(const TPoint& aPos, const TGestureType aType);
+        void DoDrag(const TPoint& aPos, const TGestureType aType);
+        void DoFlick(const TPoint& aPos, const TGestureType aType);
+        void DoSingleTap(const TPoint& aPos, const TGestureType aType);
+        void DoDoubleTap(const TPoint& aPos, const TGestureType aType);
+        void DoLongTapping(const TPoint& aPos, const TGestureType aType);
+        void DoLongTap(const TPoint& aPos, const TGestureType aType);
+
+        
+        void SetFullScreen();
+        void SetBitmapFromArrayL();
+        TBool IsOpenGLInit();
+        void OpenGLInitL();
+        void InitL();
+        void DeleteTextures();
+        void DisableDisplayDraw();
+        void EnableDisplayDraw();
+        //void SetGridMode(TGridMode aDrawMode);
+        void SetDrawMode(TDrawFunction aDrawFunction);
+        TDrawFunction GetDrawMode();
+        void SetBGPSStatus(TBool aValue);
+        //void SetTNCreationStarted(TBool aValue);
+        void DeleteImageL();
+        CTextureLoader* GetTextureLoader();
+        void DisplayDeleteQueryDialogL(TInt aResourceId);
+        float GetAspectRatio(TInt aIndex);
+        void SetFaceCoords(RArray<TRect>& aCoordinates);
+        void ClearFaceArray();
+        //void SwapArrays();
+        void SetLoadingOn(TBool aValue);
+        void DynamicLoadingL();
+        void SetDeleteTextures(TBool aValue);
+        //void InitFaceBrowsing();
+        //MRemConCoreApiTargetObserver
+        //void MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct);
+        
+    private: // Functions from base classes
+
+       /**
+        * From CoeControl,SizeChanged.
+        */
+        void SizeChanged();
+
+       /**
+        * From CoeControl,CountComponentControls.
+        */
+        TInt CountComponentControls() const;
+
+       /**
+        * From CCoeControl,ComponentControl.
+        */
+        CCoeControl* ComponentControl(TInt aIndex) const;
+
+       /**
+        * From CCoeControl,Draw.
+        */
+        void Draw(const TRect& aRect) const;
+
+       /**
+        * From CCoeControl, HandleControlEventL.
+        */
+        // event handling section
+        // e.g Listbox events
+        void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType);
+        
+        /**
+         * Callback function for the CPeriodic. Calculates the current frame, keeps the background
+         * light from turning off and orders the CSlideshow to do the rendering for each frame.
+         *@param aInstance Pointer to this instance of CSlideshowContainer.*/
+        static TInt DrawCallBackL( TAny* aInstance );
+        void DrawL();
+        void BeginDrawing();
+        void EndDrawing();
+        
+/*----------------------------------------------------------------------*/
+		void CheckLimits(float &aValue, const float aMin, const float aMax);
+		void SetPictureVertices(CImageData* aData, GLfixed *aVertices);
+		void HandleRotationKeys(void);
+		//void HandleMovingKeysOnebyOne();
+		
+		
+		//void BubbleEffect(TInt& x, TInt& y, float& z);
+        
+        static TInt DisableDrawTimer( TAny* aInstance );
+        static TInt PowerSaveCallBack(TAny *aAnyPtr);
+        void PowerSave();
+        void CheckIndexLimits(TInt &aIndex);
+        void SetQvgaCoordinates(const TPoint &aPoint, const TSize &aSize);
+        void CalculateImageSize2(float& width, float& height, const float aAspectRatio);
+        void InitDrawMagGlass();
+        void DrawMagGlass(const TSize &aScreenPhysicalSize, TReal aImageAspectRatio);
+        void DrawCross(const TSize &aScreenPhysicalSize, const TReal aImageAspectRatio);
+        void SetMinMagFilterLinear(TBool aValue);
+        void SetMinMagFilterLinearDo(TBool aValue);
+        
+
+        void MoveIndex(TInt aMoveX, TInt aMoveY, TBool aWrap = ETrue);
+        void SelectIndex(void);
+        FloatCoords ConvertCoordsFromScreen2OGl(const TPoint aPos);
+        TBool FindImageInGrid(const TPoint aPos, TInt& aResultIndex);
+        TInt GetFreeRam();
+        TBool FindImageInScreen(const TPoint aPos, TInt& aResultIndex);
+        TBool FindNearestImageInOGl(const FloatCoords aPos, TInt& aResultIndex);
+        TBool SetMinMagFilter(CImageData* aImageData, TBool aMagFilterLinear, TInt aIndex);
+        void ShowMagGlass(const TBool aState);
+        
+        void LoadHQ512Image(CImageData* imageData, TInt aIndex);
+        void DrawFaceBrowsingIcon();
+        void DrawZoomIcon();
+        void SetMinMagFiltering();
+        void ResetZoomKeys();
+        void ResetDirKeyData();
+        void HandleDrawingModeSwitch(TDrawFunction& aDrawFunction);
+        void LoadHighResImage(CImageData* imageData, TInt aIndex);
+        //void CheckIndexLimits(TInt &aIndex);
+        
+    public:      
+        void SetDrawFreqToNormal(TInt aTimerDelay);
+        TInt UpdateScreenDrawFreq();
+        void CalculateImageSize(float& width, float& height, const float aAspectRatio);
+        void HandleRotation(float& aRotationAngle, float& aTargetRotationAngle);
+        void SetCurrentFaceNro(TInt aNro);
+        void GetCurrentFilenameL(TFileName& aFilename, TThumbSize aRes);
+        void ConvertScreenCoords2QvgaCoords(TPoint& aPoint, TRect& aRect);
+        TBool FindNearestFace(const TPoint aPos, TInt& aResultIndex);
+        void SetLastTouchPoint(const TPoint& aPos);
+        TPoint GetLastTouchPoint(void);
+        void SetTextIndex(GLuint aIndex);
+        void IconTexturesLoaded(RArray<GLuint> aIconTexIndex);
+        void Interpolate(float &aValue, const float aTarget, const float aStep);
+        TBool GetScreenOrientation();
+        void InitAfterPowerSaveL();
+        void NewImageAdded();
+        void ImageListChanged(TInt aIndex, TBool bAdded);
+#ifdef _ACCELEROMETER_SUPPORTED_
+        TImagicDeviceOrientation CImagicContainerBrowser::GetDeviceOrientation();
+        void PhoneRotated(TImagicDeviceOrientation aDeviceOrientation);
+#endif
+        TBool IsHwAcceleration();
+        void HandleSend2BackgroundEvent();
+        void InitFaceBrowsing();
+        TBool IsTouchPointThresholdExeed();
+        float GetDisplayRotTargetAngle();
+        float GetDisplayRotAngle();
+        void SetDisplayRotAngle(float aValue);
+        TReal GetMaxX() const;
+        
+        CKeyData& GetKeyData();
+        void SetKeyData(CKeyData aData);
+        void ResetKeyData();
+        
+        CKeyData& GetTouchData();
+        void SetTouchData(CKeyData aData);
+        void ResetTouchData();
+                
+        TBool GetSlideByDragValue();
+        TInt GetCurrentIndex();
+        TInt GetPrevIndex();
+        void SetCurrentIndex(TInt aIndex);
+        void SetPrevIndex(TInt aIndex);
+        TInt GetGleMaxRes();
+        void ResetHighResLoading();
+        void DynamicUnLoading();
+        TBool IsUserInputGiven();
+        TSize GetScreenSize();
+        void SetScreenImmeadetaUpdate(TBool aValue);
+       
+/*----------------------------------------------------------------------*/
+        
+    private: //data
+        CImagicAppUi*           iImagicAppUi;//App UI class pointer
+        CIEEngine*              iIEngine;
+        CImagicViewBrowser*     iView;//Browser view class pointer
+        //CTextureLoader*			iTextureLoader;
+        CGesture*               iGesture;
+        CDrawUtility*           iDrawUtility;
+        
+    friend class CTextureLoader;
+        CTextureLoader*         iTextureLoader;
+    friend class CDrawGrid;
+        CDrawGrid*              iDrawGrid;
+    friend class CDrawOneByOne;
+        CDrawOneByOne*          iDrawOneByOne;
+    friend class CDrawFaceBrowsing;
+        CDrawFaceBrowsing*      iDrawFaceBrowsing;
+    friend class CDrawMagGlass;
+        //CDrawMagGlass*          iDrawMagGlass;
+        
+        
+        
+        
+    private: //data
+/*----------------------------------------------------------------------*/
+       //OpenGL valiables
+	   //Flag that indicates if OpenGL ES has been initialized or not.
+	    TBool iOpenGlInitialized;
+	    //Display where the OpenGL ES window surface resides.
+	    EGLDisplay  iEglDisplay;
+	    //Window surface where the OpenGL ES rendering is blitted to.
+	    EGLSurface  iEglSurface;
+	    // OpenGL ES rendering context.
+	    EGLContext  iEglContext;
+	    //Active object that is the timing source for the animation.
+	    CPeriodic*  iPeriodic;
+	    CPeriodic*  iPowerSavePeriodic;
+/*----------------------------------------------------------------------*/	    
+	    
+        //Variables used to calculate time
+        GLfloat     	    iLastTime;
+        GLfloat     	    iTimeNow;
+        GLfloat     	    iTimeDiff;
+
+/*----------------------------------------------------------------------*/
+        //Variables for OneByOne init
+        TBool               iOnTheEdge;
+        TBool               iTouchPointThreshold;
+        TBool               iKeyPressedDown;
+
+/*----------------------------------------------------------------------*/
+        TInt				iCurrentIndex;// Selected picture index
+		TInt                iPreviousIndex;// One before selected picture index
+		
+/*----------------------------------------------------------------------*/		
+		
+				
+		//Draw function enum, OneByOne and Grid implemented, add here more when new draw function are created
+		enum TDrawFunction	iDrawFunction;
+		
+		
+		//Struct for KeyData, this struct holds all data for key events handling
+		CKeyData		    iTouchMoveData;
+		CKeyData            iKeyData;
+		
+		float               iDisplayRotation;//This controls the whole display rotation, not single picture
+		float               iDisplayRotationTarget;//Display target rotation angle
+		TBool               iScreenRotateOngoing;
+		TReal               iScreenAspectRatio;
+		TSize               iScreenSize;
+		
+		TBool               iTNCreationComplete; // Set TRue if TNs are created
+        RCriticalSection    iDrawLock;
+        
+        //Texture related variables
+        GLuint              iCurrentBindedIndex;
+        TInt                iLoadingTextureIndex; // texture to draw if no image exist
+        TInt                iExitTextureIndex; // texture to draw if no image exist
+        TInt                iMenuTextureIndex; // texture to draw if no image exist
+#ifdef SHADOW_PHOTOS        
+        TInt                iShadowTextureIndex;
+#endif        
+        TInt                iDisplayDrawFreq;
+        GLint               iGLMaxRes;//OpenGL max texture resolution
+ 
+//        CRemConInterfaceSelector* iSelector;
+//        CRemConCoreApiTarget* iTarget;
+       
+       //When set on drawing is enabled
+       TBool                iDrawNow;
+
+       //Image loading related flags
+       TBool                iDynamicLoadingOn;//Set on for dynamic loading
+       TBool                iNewImageAdded;//New image added to array
+       TInt                 iIsLoaderRunning;
+       
+       TBool                iMagFilterLinear;//Set on when linear filtering is wanted
+       
+       RArray<GLuint>       iIconTextureIndexes;//Array to hold icon textures
+       TBool                iMinMagFilterSetting;
+       TBool                iPreferHighResLoading;//Set this on when want to load high resolution image(stops loading low res images)
+       
+       
+#ifdef USE_AVKON_LONGTAP_DETECTOR
+       CAknLongTapDetector* iLongTapDetector;
+#endif
+#ifdef USE_AVKON_TACTILE_FEEDBACK
+       MTouchFeedback*      iTouchFeedBack;
+#endif
+       
+       TPoint               iLastTouchPoint;
+       
+#ifdef HOLD_SELECTION_ONDRAG
+       TBool                iHoldSelection;
+       TBool                iOneByOneSlideByDrag;
+#endif
+#ifdef MOMENTUM_MOVE
+       TBool                iMomentumMove;
+       float                iMomentumSpeedX;
+       float                iMomentumSpeedY;
+#endif
+       
+       TReal                    iDeviceOrientationAngle;
+#ifdef _ACCELEROMETER_SUPPORTED_
+	   TImagicDeviceOrientation iDeviceOrientation;
+	   TImagicDeviceOrientation iDeviceOrientationPrev;
+#else
+	   TBool                    iDeviceOrientation;
+#endif
+	   
+#ifdef ADAPTIVE_FRAMERATE
+	   TInt                     iWaitDrawTicks;
+#endif	   
+	   
+	   //Remove these
+	   TBool               iIntheEndOfGrid;
+       TBool               iJumpOver;
+	   TInt                iDrawOnes;
+	   
+	   TBool               iUserInputGiven;
+	   TBool               iDeleteTextures;
+	   TBool               iScreenImmeadetaUpdate;
+	   
+	   TReal               drawZoom;
+	   TReal               inPictureX;
+	   TReal               inPictureY;
+	   
+	   TBool               iLastEventFromKeys;
+	   
+	   //Class consts
+	   static const GLfixed iGlobalTexCoords[4*2];
+       static const float KMinOneByOneZoom;
+       static const float KMaxOneByOneZoom;
+	   static const TInt  KDoubleTapZoomOneByOne1;
+       static const TInt  KDoubleTapZoomOneByOne2;
+       static const TReal KAngle2Start128Loading;
+       static const TReal KAngle2Start128LoadingHwAcc;
+       static const float KSpacingX;// Picture spacing in the grid
+       static const float KSpacingY;// Picture spacing in the grid
+       static const float KSpacingYTarget;
+       static const float KSpacingXTarget;
+       // Space between pictures in one by one
+       static const float KOneByOneSpacing;
+       static const TInt  KGridSizeY;
+       
+       static /*const*/ TInt  K512TNImageBuffer;
+       static const TInt  K128TNImageBuffer;
+       static /*const*/ TInt  K32TNImageBuffer;
+       static /*const*/ TInt  K32TNImageUnLoadBuffer;
+       
+    };
+
+#endif
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/ImagicDocument.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGICDOCUMENT_H
+#define IMAGICDOCUMENT_H
+
+// INCLUDES
+#include <akndoc.h>
+   
+// FORWARD DECLARATIONS
+class  CEikAppUi;
+
+// CLASS DECLARATION
+
+/**
+*  CImagicDocument application class.
+*/
+class CImagicDocument : public CAknDocument
+    {
+    public: // Constructors and destructor
+        /**
+        * Two-phased constructor.
+        */
+        static CImagicDocument* NewL(CEikApplication& aApp);
+
+        /**
+        * Destructor.
+        */
+        virtual ~CImagicDocument();
+
+    private:
+
+        /**
+        * EPOC default constructor.
+        */
+        CImagicDocument(CEikApplication& aApp);
+        void ConstructL();
+
+    private:
+
+        /**
+        * From CEikDocument, create CImagicAppUi "App UI" object.
+        */
+        CEikAppUi* CreateAppUiL();
+    };
+
+#endif
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/ImagicViewBrowser.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,168 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGICVIEWBROWSER_H
+#define IMAGICVIEWBROWSER_H
+
+// INCLUDES
+#include <aknview.h>
+#include "TextureLoader.h"
+#include "ImagicAppUi.h"
+
+
+// FORWARD DECLARATIONS
+class CImagicContainerBrowser;
+class CImagicAppUi;
+class CTextureLoader;
+
+// CLASS DECLARATION
+
+//Face browsing states
+enum TFaceBrowsingModes
+    {
+     EFaceBrowserNone = 1,
+     EFaceBrowsingShowRect,
+     EFaceBrowsing,
+     EFaceBrowsingRemoveFace,
+     EFaceBrowsingAddNewFace,
+     EFaceBrowsingAddThisAsNewFace
+    };
+
+enum TApplicationFeature
+    {
+    EAppFeatureCropping = 1,
+    EAppFeatureEditing,
+    EAppFeatureFaceBrowsing,
+    EAppFeatureNone
+    };
+
+
+class CSettings
+{
+public :
+    enum TSettingsValue {
+        ESettingImageIndex = 0,
+        ESettingGridMode = 1
+    };
+    
+    CSettings();
+    void ExternalizeL(RWriteStream& aStream) const;
+    void InternalizeL(RReadStream& aStream);
+    void SetValue(TSettingsValue aIndex, TInt aValue);
+    TInt GetValue(TSettingsValue aIndex) const;
+    TBool IsChanged() const;
+
+private :
+    TInt    iValues[2];
+    TBool   iChanged;
+};
+ 
+/**
+*  CImagicViewBrowser view class.
+* 
+*/
+class CImagicViewBrowser : public CAknView
+    {
+    public: // Constructors and destructor
+
+        /**
+        * EPOC default constructor.
+        */
+        void ConstructL(CImagicAppUi*	aImagicAppUi);
+
+        /**
+        * Destructor.
+        */
+        ~CImagicViewBrowser();
+
+    public: // Functions from base classes
+        
+        /**
+        * Return Uid
+        */
+        TUid Id() const;
+
+        /**
+        * Handle Commands
+        */
+        void HandleCommandL(TInt aCommand);
+
+        /**
+        * Handle size change
+        */
+        void HandleClientRectChange();
+        
+        void SetActiveViewL(TUid aViewNro);
+        void LoadBitmapsToBrowserL(CImageData* aImageData, TThumbSize aImageResolution);
+        CImagicContainerBrowser* GetContainer();
+        void BitmapLoadedByEngineL(TInt aError);
+        void TNCreationComplete();
+        void FaceDetectionComplete();
+        void TNCreationBegin();
+        void DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane);
+        
+        void WriteSettingsFileL(const TDesC& aName);
+        void ReadSettingsFileL(const TDesC& aName);
+        //TBool FindFileName(const TDesC& aName);
+        TApplicationFeature GetAppFeature();
+        
+        void EditImageL();
+        void CropImageL();
+        
+        //void SetFaceCoords(RArray<TRect>& aCoordinates);
+        void ResetFaceCoords();
+        void SetFaceBrowsingMode(TFaceBrowsingModes aMode);
+        TFaceBrowsingModes GetFaceBrowsingMode();
+        
+    private:
+
+        /**
+        * From AknView, activates view
+        */
+        void DoActivateL(const TVwsViewId& aPrevViewId,TUid aCustomMessageId,
+            const TDesC8& aCustomMessage);
+
+        /**
+        * From AknView, deactivates view
+        */
+        void DoDeactivate();
+        void DisplayAddFacesQueryDialogL(TInt aResourceId);
+        void SetGridMode(TGridMode aGridMode);
+        
+    private: // Data
+        CImagicContainerBrowser*    iContainer;
+        CImagicAppUi*	            iImagicAppUi;
+        CFbsBitmap*                 iBitmap;
+        TBool                       iHighRes;
+        TBool                       iTNCreationComplete;//Set TRue if TNs are created
+        TBool                       iFaceBrowsingComplete;//Set TRue if background Face Browsing is complete
+        TBool                       iFaceCroppingComplete;//Set TRue if background Face Cropping is complete
+        TBool                       iEditModeEnabledCmd1;
+        RFs                         iFsSession;
+        RArray<TRect>               iCoordinates;
+        TFileName                   iFaceTNFilename;
+        TFaceBrowsingModes          iFaceBrowsingMode;
+        RArray<TRect>               iTempCordArray;
+        TApplicationFeature         iApplicationFeature;
+        //TFileName                   tmpFileName;
+        TThumbSize                  iImageResolution;
+        CSettings                   iSettings;        
+    };
+
+#endif
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/SendImageFile.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __SENDIMAGE_H__
+#define __SENDIMAGE_H__
+
+#include <eikenv.h>
+
+class CSendUi;
+
+class CSendImageFile {
+
+public:
+    CSendImageFile();
+    static CSendImageFile* NewL();
+    void ConstructL();
+    ~CSendImageFile();
+#ifdef SEND_FILE_DIALOGUE
+    void SendFileViaSendUiL();
+#endif
+    void SendFileViaSendUiL(TFileName path);
+    
+private:
+#ifdef SEND_FILE_DIALOGUE
+    TBool AskFileL(TFileName& aFileName);
+#endif
+    
+private:
+    CSendUi* iSendUi;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/TextureLoader.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,118 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGIC_TEXTURE_LOADER_H
+#define IMAGIC_TEXTURE_LOADER_H
+
+// INCLUDES
+#include "ImagicViewBrowser.h"
+#include "ImagicContainerBrowser.h"
+#include <BitmapTransforms.h>
+
+
+// FORWARD DECLARATIONS
+class CImagicViewBrowser;
+class CImagicAppUi;
+
+/*enum TTextureLoaderStatus
+{
+    EIdle = 0,
+    EScaling = 1,
+    EDecoding = 2,
+    ECreateSmileTex = 3,
+};*/
+
+class CTextureLoader : public CActive
+	{
+	public:
+		// Constructor and destructor
+	    void ConstructL();
+		CTextureLoader(CImagicAppUi* aImagicAppUi, CImagicContainerBrowser* aContainer, 
+		               CImagicViewBrowser* aView, RCriticalSection* aDrawLock);
+		~CTextureLoader();
+		
+		// Tells if loader is running at the moment
+		inline const TBool IsRunning(void) const 
+			{
+			return (iData!=NULL);
+			}
+		
+		// Loads picture and stores the OpenGL index into specified variable
+		void LoadL(CImageData* aData, TThumbSize aResolution);
+		
+		// Unloads picture from specified index
+		void ReleaseSuperHResTexture(CImageData* aGridData);
+        void ReleaseHQ512Textures();
+	    void UnloadLQ512Tex(CImageData* aData) const;
+		void UnloadLQ128Tex(CImageData* aData) const;
+		void UnloadLQ32Tex(CImageData* aData) const;
+		
+		// Called when image is loaded
+		void ImageLoadedL(TInt aError, CFbsBitmap* aBitmap, TInt aGLMaxRes);
+		
+		// Creates OpenGL texture of given bitmap
+		static TInt CreateTexture(CFbsBitmap* aBitmap, TBool aHighQuality);
+		void CreateIconTextures(/*RArray<CFbsBitmap*> aBitmapArray*/);
+		void LoadIcons();
+		
+		//void LoadAnimation();
+		TBool IsActiveAndRunning();
+		void GetPngL(TFileName& afilepath, CFbsBitmap* aBitmap);
+		
+	private:
+        // Active object interface
+        void RunL();
+        void DoCancel();
+        void RunError();
+        void CreateThumbnailTexture(CFbsBitmap* aBitmap);        
+		
+	private:
+		// Scales given value to power of two
+        TInt ScaleDown(TInt aSize);
+        TBool IsScalingNeeded(TSize aImageSize);
+		
+	private:
+		CImagicViewBrowser*   iView;		// Pointer to view
+		RCriticalSection*     iDrawLock;	// Drawing mutex
+		CImagicContainerBrowser* iContainer; // Container class
+        CFbsBitmap*           iBitmap;          // Bitmap for scaled picture
+        CFbsBitmap*           iSmileBitmap;          // Bitmap for scaled picture
+        CFbsBitmap*           iZoomBitmap;          // Bitmap for scaled picture
+        RArray<CFbsBitmap*>   iBitmapArray;          // Bitmap for scaled picture
+        CBitmapScaler*        iBitmapScaler;    // Bitmap scaler object
+        CImageDecoder*        iImageDecoder;
+        
+        CImageData*           iData;		// Pointer to one grid data
+		TBool                 iHighQuality;	// Is image supposed to be high quality
+		
+		TUint                 iNewIndex; 				// Texture index
+		CImageData*           iPreviousData;                // Texture index
+
+		
+	    TBool                 iCreateAnimation;
+		GLuint                iSmileTexIndex;
+		RArray<GLuint>        iIconTextureIndexes;
+		TSize                 iImageSize;
+        TBool                 iScalingNeeded;
+        CImagicAppUi*         iImagicAppUi;
+        TInt                  iGLMaxRes;
+        TThumbSize            iResolution;
+        TBool                 iClearCurrentLoading;
+        TBool                 iRGB2BGRDone;
+	};
+
+#endif // IMAGIC_TEXTURE_LOADER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/debug.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#define _IMAGIC_DEBUG
+#ifdef _IMAGIC_DEBUG
+
+#include <e32debug.h>
+
+#define DP0_IMAGIC(string)                            RDebug::Print(string)
+#define DP1_IMAGIC(string,arg1)                       RDebug::Print(string,arg1)
+#define DP2_IMAGIC(string,arg1,arg2)                  RDebug::Print(string,arg1,arg2)
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             RDebug::Print(string,arg1,arg2,arg3)
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        RDebug::Print(string,arg1,arg2,arg3,arg4)
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)   RDebug::Print(string,arg1,arg2,arg3,arg4,arg5)
+
+#else
+
+#define DP0_IMAGIC(string)                            
+#define DP1_IMAGIC(string,arg1)                       
+#define DP2_IMAGIC(string,arg1,arg2)                  
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)
+#endif // _DEBUG
+
+
+//#endif //__IMAGIC_TRACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/debug2.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+//  - INCLUDES ------------------------
+#include <e32debug.h>
+
+//  - NAMESPACE -----------------------
+
+//  - MACROS --------------------------
+
+// Check that D_FLOW is defined
+#ifndef D_FLOW
+#warning D_FLOW not defined!
+#define D_FLOW 0
+#endif
+
+// Small debug functions
+#define DebugIn()				if (DEBUG && D_FLOW)	RDebug::Printf("> %s", __FUNCTION__)
+#define DebugOut()				if (DEBUG && D_FLOW)	RDebug::Printf("< %s", __FUNCTION__)
+#define DebugInD(fmt,args...)	if (DEBUG && D_FLOW)	RDebug::Printf("> %s: "fmt, __FUNCTION__, ##args)
+#define DebugOutD(fmt,args...)	if (DEBUG && D_FLOW)	RDebug::Printf("< %s: "fmt, __FUNCTION__, ##args)
+#define DebugAt(X, fmt,args...)	if (DEBUG && X)			RDebug::Printf("= %s: "fmt, __FUNCTION__, ##args)
+
+//  - CONSTANTS -----------------------
+
+//  - EXTERNAL DATA -------------------
+
+//  - FORWARD DECLARATIONS ------------
+
+//  - DATA TYPES ----------------------
+
+//  - FUNCTION DECLARATIONS -----------
+
+//  - Inline Functions ----------------
+
+#endif // __DEBUG_H__
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/glfont2.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,138 @@
+//*******************************************************************
+// glfont2.h -- Header for glfont2.cpp
+// Copyright (c) 1998-2002 Brad Fish
+// See glfont.html for terms of use
+// May 14, 2002
+//
+// Symbian OS port - June 2007
+// Luis Valente - lpvalente@gmail.com
+//
+//*******************************************************************
+ 
+#ifndef GLFONT2_H
+#define GLFONT2_H
+ 
+#include <e32base.h>
+#include <GLES/gl.h>
+ 
+//_____________________________________________________________________________
+//
+// Simple class to output text as texture-mapped triangles. Does not support
+// unicode strings. Reference point when drawing: top-left.
+//
+ 
+class GLFont
+{	
+  public:
+ 
+   /**
+    * Factory-method.
+    */
+   static GLFont* NewL (const TDesC & aFilename);
+ 
+  public:
+ 
+   /**
+    * Destructor.
+    */		
+   ~GLFont ();
+ 
+  public:
+ 
+ 
+   /**
+    * Retrieves the texture width and height.
+    */	
+   void GetTexSize (TInt & aWidth, TInt & aHeight);
+ 
+   /**
+    * Retrieves the character interval.
+    */	
+   void GetCharInterval (TInt & aStart, TInt & aEnd);
+ 
+   /**
+    * Retrieves the character dimensions.
+    */
+   void GetCharSize (TText8 c, TInt & aWidth, TInt aHeight);
+ 
+ 
+   /**
+    * Calculates the dimensions of a string.
+    */
+   void GetStringSize (const TDesC8 & aText, TInt & aWidth, TInt & aHeight);
+ 
+   /**
+    * Renders a string.
+    */
+   void DrawString (const TDesC8 & aText, GLfixed aX, GLfixed aY);	
+ 
+   /**
+    * Sets required states for the font.
+    */
+   void BeginDraw ()
+   {			
+    glEnable (GL_BLEND);
+    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glEnable (GL_TEXTURE_2D);
+    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+   }
+ 
+   /**
+    * Turns off required states.
+    */
+   void EndDraw ()
+   {			
+    glDisable (GL_BLEND);			
+    glDisable (GL_TEXTURE_2D);
+    glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+   }		
+ 
+ private:
+ 
+    /**
+     * Default constructor.
+     */
+   GLFont ();
+ 
+   /**
+    * Final part of the two-phase constructor.
+    */
+   void ConstructL (const TDesC & aFilename);
+ 
+   /**
+    * Loads the font file.
+    */
+   void LoadFileL (RFs & aFs, const TDesC & aFilename);		
+ 
+   /**
+    * Destroys the font.
+    */		
+   void Destroy ();		
+ 
+ 
+  private:	
+ 
+   // single character
+   struct GLFontChar
+   {
+      GLfixed dx, dy;
+      GLfixed tx1, ty1;
+      GLfixed tx2, ty2;
+   };
+ 
+   // font header
+   struct GLFontHeader
+   {
+      GLuint tex;
+      TInt   texWidth, texHeight;
+      TInt   startChar, endChar;
+      GLFontChar *chars;
+   };			
+ 
+ private:
+ 
+   GLFontHeader iHeader;
+};
+ 
+//*******************************************************************
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppInc/project.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef PROJECT_H_
+#define PROJECT_H_
+
+#include <e32std.h>
+#include <GLES\egl.h>
+#define GLdouble GLfloat
+
+GLint gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
+       const GLdouble model[16], const GLdouble proj[16],
+       const GLint viewport[4],
+       GLdouble * winx, GLdouble * winy, GLdouble * winz);
+
+GLint gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
+         const GLdouble model[16], const GLdouble proj[16],
+         const GLint viewport[4],
+         GLdouble * objx, GLdouble * objy, GLdouble * objz);
+
+#endif /* PROJECT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/CDrawFaceBrowsing.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,724 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "CDrawFaceBrowsing.h"
+#include "TextureLoader.h"
+#include "DrawUtility.h"
+#include "ImagicConsts.h"
+
+#define IS_ALMOST_ZERO (0.001)
+
+
+CDrawFaceBrowsing::CDrawFaceBrowsing(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex):
+    iContainer(aContainer)//,
+    //iCurrentIndex(aCurrentIndex)
+    {
+    // No implementation required
+    }
+
+CDrawFaceBrowsing::~CDrawFaceBrowsing()
+    {
+    iCoordinates.Close();
+    iFloatCoordinates.Close();
+    }
+
+CDrawFaceBrowsing* CDrawFaceBrowsing::NewLC(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    CDrawFaceBrowsing* self = new (ELeave) CDrawFaceBrowsing(aContainer,aCurrentIndex);
+    CleanupStack::PushL(self);
+    self->ConstructL(aContainer,aCurrentIndex);
+    return self;
+    }
+
+CDrawFaceBrowsing* CDrawFaceBrowsing::NewL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    CDrawFaceBrowsing* self = CDrawFaceBrowsing::NewLC(aContainer,aCurrentIndex);
+    CleanupStack::Pop(); // self;
+    return self;
+    }
+
+void CDrawFaceBrowsing::ConstructL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    //iContainer = aContainer;
+    }
+
+void CDrawFaceBrowsing::KeyPressed()
+    {
+    iMenuAlpha = 1;
+    }
+
+void CDrawFaceBrowsing::KeyReleased()
+    {
+    iMenuAlpha = 0.99;
+    }
+
+void CDrawFaceBrowsing::KeyEvent()
+    {
+    //iMenuAlpha = 1;
+    }
+
+void CDrawFaceBrowsing::GetFBZoomAndLocation(TReal& aDrawZoom, TReal& aInPictureX, TReal& aInPictureY)
+    {
+    aDrawZoom = iDrawZoom;
+    aInPictureX = iInPictureX;
+    aInPictureY = iInPictureY;
+    }
+
+
+
+void CDrawFaceBrowsing::InitFaceBrowsing()
+    {
+    //iFBMovingSpeed = 1.4*iContainer->iTimeDiff;
+    iFBMovingSpeed = 0.1;
+    iFBRectCounter = 0;
+    //iContainer->iDrawOneByOneTargetZoom=1;
+    iDrawZoom=1;
+    iDrawFBTargetZoom=1;
+    iFBZoomingSpeed = 1.2*iContainer->iTimeDiff;
+    iDrawX=0;
+    iDrawY=0;
+    iDrawTargetX=0;
+    iDrawTargetY=0;
+    //iInPictureX, iInPictureY
+    
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Draws FaceBrowser view
+//
+void CDrawFaceBrowsing::DrawFaceBrowsing(const TSize &aSize)
+    {
+    DP0_IMAGIC(_L("CDrawFaceBrowsing::DrawFaceBrowsing"));
+
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    
+#ifdef SUPERZOOM
+    if(imageData->iGridData.iGlSuperHQTextIndex == 0)
+        {
+        TRAPD(err, iContainer->iTextureLoader->LoadL(imageData, EFullSize));
+        }
+#endif
+    
+    //Calculate screen size
+    iContainer->CalculateImageSize(iImageWidth, iImageHeight, (float)aSize.iWidth/(float)aSize.iHeight);
+    
+    if(imageData->iGridData.iRotationAngle != imageData->iGridData.iTargetRotationAngle)
+        iContainer->HandleRotation(imageData->iGridData.iRotationAngle, imageData->iGridData.iTargetRotationAngle);
+        
+    
+    //Interpolate current screen size into the new one
+    iContainer->Interpolate(iDrawWidth, iImageWidth, 0.75);
+    iContainer->Interpolate(iDrawHeight, iImageHeight, 0.75);
+    
+    //Set orthigonal projection
+    glLoadIdentity();
+    glOrthof(-iDrawWidth,iDrawWidth, -iDrawHeight, iDrawHeight, -1,1);
+    
+    //iContainer->Interpolate(iContainer->iDisplayRotation, iContainer->iDisplayRotationTarget, 0.2);
+    float tmp = iContainer->GetDisplayRotAngle();
+    iContainer->Interpolate(tmp, iContainer->GetDisplayRotTargetAngle(), 0.2);
+    iContainer->SetDisplayRotAngle(tmp);
+    glRotatef(iContainer->GetDisplayRotAngle(), 0,0,1);
+    
+    
+    //Handle coordinates----------------------->
+    if(iFaceNro < 0)
+        iFaceNro = iCoordinates.Count()-1;
+    if(iFaceNro >= iCoordinates.Count())
+        iFaceNro = 0;
+    
+    
+    // Interpolate to new zoom value
+    if( iContainer->iView->GetFaceBrowsingMode() != EFaceBrowsingShowRect )
+        iContainer->Interpolate(iDrawZoom, iDrawFBTargetZoom, iFBZoomingSpeed);
+    
+    //Convert coordinates from corner to center of screen
+    if(iCoordinates.Count() >= 1)
+        {
+        //Convert integer coords to OpenGL float coords and fill array
+        for(TInt i=0; iFloatCoordinates.Count() < iCoordinates.Count();i++)
+            {
+            iFloatCoordinates.Append(ConvertCoordsFromAlgo2OGl(iCoordIndex));
+            iCoordIndex++;
+            }
+        
+        iDrawTargetX = iFloatCoordinates[iFaceNro].iX;
+        iDrawTargetY = iFloatCoordinates[iFaceNro].iY;
+        
+        //Calculate face width and use that for zooming in factor
+        float faceWidth = (iCoordinates[iFaceNro].iBr.iX - iCoordinates[iFaceNro].iTl.iX);
+        float zoomFactor = faceWidth/20;
+        
+        if(iContainer->GetScreenOrientation())
+            iDrawFBTargetZoom = 4.6;
+        else
+            iDrawFBTargetZoom = 5.4;
+
+        iDrawFBTargetZoom /= zoomFactor;
+        if(iDrawFBTargetZoom <=1.6)
+            iDrawFBTargetZoom = 1.6;
+        
+        }
+    
+    /*iContainer->iTouchMoveData.iX=0;
+    iContainer->iTouchMoveData.iY=0;*///mika. to test doe this make anything at all????
+    
+    
+    // Calculate picture size
+    iContainer->CalculateImageSize(iImageWidth, iImageHeight, imageData->GetAspectRatio());
+    
+    iImageWidth*=iDrawFBTargetZoom;
+    iImageHeight*=iDrawFBTargetZoom;
+    
+    //Calculate location/coordinates in screen
+    iInPictureX = iDrawTargetX * iDrawFBTargetZoom;
+    iInPictureY = iDrawTargetY * iDrawFBTargetZoom;
+    
+    iDrawTargetX = iInPictureX / iDrawFBTargetZoom;
+    iDrawTargetY = iInPictureY / iDrawFBTargetZoom;
+    
+    if(!iContainer->GetScreenOrientation())
+        {
+        float temp = iDrawTargetX;
+        iDrawTargetX = iDrawTargetY;
+        iDrawTargetY = -temp ;
+        }
+        
+    // Move in picture------------------------>
+    if( iContainer->iView->GetFaceBrowsingMode() != EFaceBrowsingShowRect )
+        {
+        TInt imageRotation = 0 - (TReal)imageData->GetOrientation();
+        imageRotation%=360;
+        
+        if(imageRotation == 0)
+            {
+            iContainer->Interpolate(iDrawX,iDrawTargetX, iFBMovingSpeed);
+            iContainer->Interpolate(iDrawY,iDrawTargetY, iFBMovingSpeed);
+            }
+        else if(imageRotation == -90)
+            {
+            iContainer->Interpolate(iDrawX,iDrawTargetY, iFBMovingSpeed);
+            iContainer->Interpolate(iDrawY,-iDrawTargetX, iFBMovingSpeed);
+            }
+        else if(imageRotation == -180)
+            {
+            iContainer->Interpolate(iDrawX,-iDrawTargetX, iFBMovingSpeed);
+            iContainer->Interpolate(iDrawY,-iDrawTargetY, iFBMovingSpeed);
+            }
+        else if(imageRotation == -270)
+            {
+            iContainer->Interpolate(iDrawX,-iDrawTargetY, iFBMovingSpeed);
+            iContainer->Interpolate(iDrawY,iDrawTargetX, iFBMovingSpeed);
+            }
+        }
+    
+    iContainer->iCurrentBindedIndex = imageData->iGridData.BestImage();
+    glBindTexture( GL_TEXTURE_2D, iContainer->iCurrentBindedIndex);
+    iContainer->SetMinMagFilterLinearDo(iContainer->iMinMagFilterSetting);
+    
+    // Calculate picture vertices
+    GLfixed vertices[8];
+    iContainer->SetPictureVertices(imageData, vertices);
+    glVertexPointer( 2, GL_FIXED, 0, vertices );
+    glColor4f(1,1,1, 1);
+    glPushMatrix();
+    glScalef(iDrawZoom, iDrawZoom, iDrawZoom);
+    glTranslatef(-iDrawX, iDrawY, 0);
+    glRotatef(imageData->iGridData.iRotationAngle, 0,0,1);
+    glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+
+#ifdef RD_FACEFRAME
+    if( iContainer->iView->GetFaceBrowsingMode() == EFaceBrowsingShowRect )
+        DrawFaceFrame(-1);
+        
+    if(ShowUtilities())
+        DrawFaceFrame(iFaceNro);
+    
+    //Draw face rects for ~ 0.5s time
+    if(iFBRectCounter > 6)
+        iContainer->iView->SetFaceBrowsingMode(EFaceBrowsing);
+    else
+        iFBRectCounter++;
+#endif
+
+    glPopMatrix();
+    
+#ifdef RD_ZOOMICON
+    if(ShowUtilities())
+        {
+        //Draw moving direction arrays
+        if(iFloatCoordinates.Count() >1)
+            {
+            TInt imageRotation = 0 - (TReal)imageData->GetOrientation();
+            
+            if(iContainer->GetScreenOrientation())
+                {
+                if(imageRotation == 0 || imageRotation == -180)
+                    {
+                    iContainer->iDrawUtility->DrawMovingArrow(ETrue, EFalse, iContainer->Size());
+                    }
+                else if(imageRotation == -90 || imageRotation == -270)
+                    {
+                    iContainer->iDrawUtility->DrawMovingArrow(EFalse, ETrue, iContainer->Size());
+                    }    
+                }
+            
+            if(!iContainer->GetScreenOrientation())
+                {
+                if(imageRotation == 0 || imageRotation == -180)
+                    {
+                    iContainer->iDrawUtility->DrawMovingArrow(EFalse, ETrue, iContainer->Size());
+                    }
+                else if(imageRotation == -90 || imageRotation == -270)
+                    {
+                    iContainer->iDrawUtility->DrawMovingArrow(EFalse, ETrue, iContainer->Size());
+                    }    
+                }
+            
+            //iContainer->iDrawUtility->DrawMovingArrow(iContainer->GetScreenOrientation(), !iContainer->GetScreenOrientation(), iContainer->Size());
+            }
+            
+            
+        iContainer->iDrawUtility->DrawZoomIcon( imageData,
+                                                iContainer->Size(), 
+                                                -iDrawX, 
+                                                iDrawY,
+                                                iDrawWidth/iImageWidth, 
+                                                iDrawHeight/iImageHeight,
+                                                iContainer->iView->GetFaceBrowsingMode()==EFaceBrowsing);
+        }
+    
+#endif
+    
+#if 0
+    if(iMenuAlpha < 1)
+        {
+        iMenuAlpha-=0.2;
+        if(iMenuAlpha < 0)
+            iMenuAlpha = 0;
+        }
+
+    iContainer->iDrawUtility->DrawIcon2(iContainer->Size(), iContainer->iLoadingTextureIndex, iMenuAlpha);
+#endif   
+    }
+
+
+TBool CDrawFaceBrowsing::ShowUtilities()
+    {
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    TInt imageRotation = 0 - (TReal)imageData->GetOrientation();
+    
+    if(imageRotation == -90 || imageRotation == -270)
+        {
+        if(Abs(iDrawX) != Abs(iDrawTargetY) || 
+           Abs(iDrawY) != Abs(iDrawTargetX) || 
+           iDrawZoom != iDrawFBTargetZoom ||
+           Abs(imageData->iGridData.iRotationAngle) != Abs(imageData->iGridData.iTargetRotationAngle) )
+            {
+            return ETrue;
+            }
+        else
+            {
+            return EFalse;
+            }
+        }
+    else
+        {
+        if(Abs(iDrawX) != Abs(iDrawTargetX) || 
+           Abs(iDrawY) != Abs(iDrawTargetY) || 
+           iDrawZoom != iDrawFBTargetZoom ||
+           Abs(imageData->iGridData.iRotationAngle) != Abs(imageData->iGridData.iTargetRotationAngle) )
+            {
+            return ETrue;
+            }
+        else
+            {
+            return EFalse;
+            }
+        }
+    }
+
+void CDrawFaceBrowsing::DrawFaceFrame(TInt aFace2bDrawn)
+    {
+    DP0_IMAGIC(_L("CDrawFaceBrowsing::DrawFaceFrame++"));
+
+    
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    RArray<TRect> facecoords;
+    facecoords.Reset();
+    
+    //if(imageData->IsImageReady(ESize512x512))
+        {
+        for(TInt i=0; i< iCoordinates.Count();i++)
+            facecoords.Append(iCoordinates[i]);    
+        
+        
+        GLfixed vertices[8];
+        glPushMatrix();
+        glDisable(GL_TEXTURE_2D);
+        glTranslatef(0, 0, 0.01f);
+        glColor4f(0,0.7,0,1);
+        glLineWidth(3.0f);
+        glVertexPointer(2, GL_FIXED, 0, vertices);
+
+        for(TInt i=0; i< facecoords.Count();i++)
+            {
+            GLfixed vx = (1<<15) * Abs(facecoords[i].iBr.iX + facecoords[i].iTl.iX);
+            GLfixed vy = (1<<15) * Abs(facecoords[i].iBr.iY + facecoords[i].iTl.iY);
+            GLfixed fW = (1<<16) * Abs(facecoords[i].iBr.iX - facecoords[i].iTl.iX);
+            GLfixed fH = (1<<16) * Abs(facecoords[i].iBr.iY - facecoords[i].iTl.iY);
+
+            DP5_IMAGIC(_L("CDrawFaceBrowsing::DrawFaceFrame face:%d (%d,%d), W/H=%d,%d"), i, vx, vy, fW, fH);
+            
+            vx /= 320; // Coords are given in 320x320 coords
+            vy /= 320; // convert to OpenGL 1.0x1.0 coords
+            fW /= 320;
+            fH /= 320;
+
+            float ar = imageData->GetAspectRatio();
+
+            if(ar > 1)
+                {
+                vx -= (1<<15);
+                vy -= (0.5/ar)*(1<<16);
+                }
+            else
+                {
+                vx -= (0.5*ar)*(1<<16);
+                vy -= (1<<15);
+                }
+
+            GLfixed x1 =  vx-fW/2, x2 =  vx+fW/2;
+            GLfixed y1 = -vy-fH/2, y2 = -vy+fH/2; // -vy since y-coord in OpenGL is so
+
+            DP5_IMAGIC(_L("CDrawFaceBrowsing::DrawFaceFrame face:%d (%d,%d), W/H=%d,%d"), i, vx, vy, fW, fH);
+            DP4_IMAGIC(_L("CDrawFaceBrowsing::DrawFaceFrame xy12 (%d,%d), (%d,%d)"), x1, y1, x2, y2);
+
+            vertices[0*2+0] = x1;    vertices[0*2+1] = y1;
+            vertices[1*2+0] = x2;    vertices[1*2+1] = y1;
+            vertices[2*2+0] = x2;    vertices[2*2+1] = y2;
+            vertices[3*2+0] = x1;    vertices[3*2+1] = y2;
+            
+            if(i == aFace2bDrawn || aFace2bDrawn == -1)
+                glDrawArrays(GL_LINE_LOOP,0,4);
+            }
+
+        glColor4f(1,1,1,1);
+        glEnable(GL_TEXTURE_2D);
+        glPopMatrix();
+        }
+
+    DP0_IMAGIC(_L("CDrawFaceBrowsing::DrawFaceFrame--"));
+    }
+
+
+TBool CDrawFaceBrowsing::IsDrawingNeededFaceBrowsing()
+    {
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    if(Abs(iContainer->GetDisplayRotAngle() - iContainer->GetDisplayRotTargetAngle()) > 1)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 6"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(iContainer->GetDisplayRotAngle() != iContainer->GetDisplayRotTargetAngle())
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 6.1"));
+        //iContainer->iDisplayRotation = iContainer->iDisplayRotationTarget;
+        iContainer->SetDisplayRotAngle(iContainer->GetDisplayRotTargetAngle());
+        //iContainer->iDrawOneMoreTime = ETrue;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+    
+    if(Abs(imageData->iGridData.iRotationAngle - imageData->iGridData.iTargetRotationAngle) > 1)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 7"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(imageData->iGridData.iRotationAngle != imageData->iGridData.iTargetRotationAngle)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 7.1"));
+        imageData->iGridData.iRotationAngle = imageData->iGridData.iTargetRotationAngle;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        //iContainer->iDrawOneMoreTime = ETrue;
+        return ETrue;
+        }
+    
+    if(Abs(iDrawZoom - iDrawFBTargetZoom) > 0.01)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 10"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(iDrawZoom != iDrawFBTargetZoom)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 10.1"));
+        iDrawZoom = iDrawFBTargetZoom;
+        //iContainer->iDrawOneMoreTime = ETrue;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+    
+    
+    TInt imageRotation = 0 - (TReal)imageData->GetOrientation();
+    
+    if(imageRotation == -90 || imageRotation == -270)
+        {
+        if(Abs(Abs(iDrawX)-Abs(iDrawTargetY)) > 0.001)
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 11"));
+            iContainer->SetMinMagFilterLinear(EFalse);
+            return ETrue;
+            }
+        else if(Abs(iDrawX) != Abs(iDrawTargetY))
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 11.1"));
+            if(iDrawX < 0)
+                iDrawX = 0-Abs(iDrawTargetY);
+            else
+                iDrawX = Abs(iDrawTargetY);
+            //iContainer->iDrawOneMoreTime = ETrue;
+            iContainer->SetMinMagFilterLinear(ETrue);
+            return ETrue;
+            }
+    
+        if(Abs(Abs(iDrawY)-Abs(iDrawTargetX)) > 0.001)
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 12"));
+            iContainer->SetMinMagFilterLinear(EFalse);
+            return ETrue;
+            }
+        else if(Abs(iDrawY) != Abs(iDrawTargetX))
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 12.1"));
+            if(iDrawY < 0)
+                iDrawY = 0-Abs(iDrawTargetX);
+            else
+                iDrawY = Abs(iDrawTargetX);
+            //iContainer->iDrawOneMoreTime = ETrue;
+            iContainer->SetMinMagFilterLinear(ETrue);
+            return ETrue;
+            }
+        }
+    else
+        {
+        if(Abs(iDrawX-iDrawTargetX) > 0.001)
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 11"));
+            iContainer->SetMinMagFilterLinear(EFalse);
+            return ETrue;
+            }
+        else if(iDrawX != iDrawTargetX)
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 11.1"));
+            iDrawX = iDrawTargetX;
+            //iContainer->iDrawOneMoreTime = ETrue;
+            iContainer->SetMinMagFilterLinear(ETrue);
+            return ETrue;
+            }
+    
+        if(Abs(iDrawY-iDrawTargetY) > 0.001)
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 12"));
+            iContainer->SetMinMagFilterLinear(EFalse);
+            return ETrue;
+            }
+        else if(iDrawY != iDrawTargetY)
+            {
+            DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 12.1"));
+            iDrawY = iDrawTargetY;
+            //iContainer->iDrawOneMoreTime = ETrue;
+            iContainer->SetMinMagFilterLinear(ETrue);
+            return ETrue;
+            }
+        }
+    
+    /*if(iContainer->iDrawOneMoreTime)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 14"));
+        iContainer->iDrawOneMoreTime = EFalse;
+        iContainer->SetMinMagFilterLinear(ETrue);//Draw one more time to change for Linear rendering mode
+        return ETrue;
+        }*/
+    
+    if(!iContainer->iMagFilterLinear)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 15"));
+        iContainer->SetMinMagFilterLinear(ETrue);
+        //iContainer->iDrawOneMoreTime = ETrue;
+        }
+        
+    if(iContainer->iDrawNow)
+        {
+        DP0_IMAGIC(_L("CDrawFaceBrowsing::IsDrawingNeededOneByOne - 1"));
+        /*if(iContainer->iMagGlassOn)
+            {
+            if(!iContainer->iTouchPointThreshold)//moved >2 pixel
+                iContainer->SetMinMagFilterLinear(ETrue);
+            else
+                iContainer->SetMinMagFilterLinear(EFalse);
+            }
+        else*/
+            {
+            iContainer->SetMinMagFilterLinear(ETrue);
+            }
+        
+        //iDrawOneMoreTime = ETrue;
+        iContainer->iDrawNow = EFalse;
+        return ETrue;
+        }
+    
+    return EFalse;
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Calculate coords coords from alogorith to OpenGL -0.5 - +0.5 coords
+//
+FloatCoords CDrawFaceBrowsing::ConvertCoordsFromAlgo2OGl(const TInt aFaceIndex)
+    {
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    TInt pictureWidth, pictureHeigth;
+    //We use always qvga image for Face detection
+    pictureWidth=320;
+    pictureHeigth=320;
+    //landscape
+    if(imageData->GetAspectRatio() > 1)
+        pictureHeigth=pictureWidth/imageData->GetAspectRatio();
+    else//portrait
+        pictureWidth=pictureHeigth*imageData->GetAspectRatio();
+        
+    //calculate midpoint from face rect
+    TInt xAvegCoord = (iCoordinates[aFaceIndex].iTl.iX + iCoordinates[aFaceIndex].iBr.iX)/2;
+    TInt yAvegCoord = (iCoordinates[aFaceIndex].iTl.iY + iCoordinates[aFaceIndex].iBr.iY)/2;
+    //and then convert coordinate zero point to center of screen 
+    xAvegCoord-=(pictureWidth/2);
+    yAvegCoord-=(pictureHeigth/2);
+    
+    //Calculate coords coords from alogorith to OpenGL -0.5 - +0.5 coords and fill the array
+    FloatCoords tmp;
+    if(imageData->GetAspectRatio() > 1)
+        {
+        tmp.iX = (xAvegCoord * 0.5) / (pictureWidth/2);
+        tmp.iY = (yAvegCoord * (0.5/imageData->GetAspectRatio())) / (pictureHeigth/2);
+        }
+    else//portrait
+        {
+        tmp.iX = (xAvegCoord * (0.5*imageData->GetAspectRatio())) / (pictureWidth/2);
+        tmp.iY = (yAvegCoord * 0.5) / (pictureHeigth/2);
+        }
+
+    return tmp;
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Draws one by one view
+//
+void CDrawFaceBrowsing::GetFaceCoordinatesL(TRect& aRect, TFileName& aFilename)
+    {
+    iContainer->iImagicAppUi->GetEngine()->GetFileNameL(iContainer->GetCurrentIndex(), ESize512x512, aFilename);
+    
+    if(iFaceNro < iCoordinates.Count() && iFaceNro >= 0)
+        {
+        aRect.iTl.iX = iCoordinates[iFaceNro].iTl.iX;
+        aRect.iTl.iY = iCoordinates[iFaceNro].iTl.iY;
+        aRect.iBr.iX = iCoordinates[iFaceNro].iBr.iX;
+        aRect.iBr.iY = iCoordinates[iFaceNro].iBr.iY;
+        }
+    }
+
+/*----------------------------------------------------------------------*/
+// Draws one by one view
+//
+TInt CDrawFaceBrowsing::GetNumberOfFaces()
+    {
+    return iCoordinates.Count();
+    }
+
+/*----------------------------------------------------------------------*/
+// Draws one by one view
+//
+void CDrawFaceBrowsing::SetCurrentFaceNro(TInt aNro)
+    {
+    iFaceNro = aNro;
+    
+    if(iFaceNro < 0)
+        iFaceNro = 0;
+    if(iFaceNro >= iCoordinates.Count())
+        iFaceNro = 0;
+    }
+
+/*----------------------------------------------------------------------*/
+// Gets current face nro
+//
+TInt CDrawFaceBrowsing::GetCurrentFaceNro()
+    {
+    return iFaceNro;
+    }
+
+void CDrawFaceBrowsing::SetFaceCoords(RArray<TRect>& aCoordinates)
+    {
+    ClearFaceArray();
+    
+    for(TInt i = 0; i < aCoordinates.Count(); i++)
+        {
+        iCoordinates.Append(aCoordinates[i]);        
+        }
+
+    iDrawFBTargetZoom = 0;
+    iFaceNro = 0;
+    }
+
+void CDrawFaceBrowsing::ClearFaceArray()
+    {
+    //iCoordinates.Reset();
+    TInt tmp = iCoordinates.Count();
+    //delete array if we had old data there
+    for(TInt i = 0; i < tmp; i++)
+        {
+        iCoordinates.Remove(0);
+        }
+    
+    tmp = iFloatCoordinates.Count();
+    for(TInt i = 0; i < tmp; i++)
+        {
+        iFloatCoordinates.Remove(0);
+        }
+    iCoordIndex=0;
+    }
+
+TInt CDrawFaceBrowsing::GetFaceCount()
+    {
+    return iCoordinates.Count();
+    }
+
+void CDrawFaceBrowsing::IncFaceNumber()
+    {
+    iFaceNro++;
+    }
+
+void CDrawFaceBrowsing::DecFaceNumber()
+    {
+    iFaceNro--;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/CDrawGrid.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,992 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "CDrawGrid.h"
+#include "TextureLoader.h"
+#include "DrawUtility.h"
+#include "ImagicConsts.h"
+
+
+const TInt  KDrawLimit = 65;
+const float KInitialZoomGrid = -4.1;//zoom value for grid when application starts drawing grid
+
+const TReal KMaxAngleLandscape = 45;//max tilt angle when moving in grid
+const TReal KMaxAnglePortrait = 10;//max tilt angle when moving in grid
+//const TReal KAngle2Start128Loading = 1;
+const float KTargetZCoord = -1.5;
+const float KZoomInMaxGrid = -3.5;//max possible zoom value 
+const float KZoomOutMaxGrid = -6;//min possible zoom value
+#ifdef DOUBLETAP_ZOOMGRID
+const TInt  KDoubleTapZoomGrid1 = KInitialZoomGrid;
+const TInt  KDoubleTapZoomGrid2 = KZoomOutMaxGrid * 7 / 10;  // 70% of max zoom out
+#endif
+
+CDrawGrid::CDrawGrid(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex):
+    iContainer(aContainer)//,
+    //iCurrentIndex(aCurrentIndex)
+    {
+    // No implementation required
+    }
+
+CDrawGrid::~CDrawGrid()
+    {
+    }
+
+CDrawGrid* CDrawGrid::NewLC(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    CDrawGrid* self = new (ELeave) CDrawGrid(aContainer,aCurrentIndex);
+    CleanupStack::PushL(self);
+    self->ConstructL(aContainer,aCurrentIndex);
+    return self;
+    }
+
+CDrawGrid* CDrawGrid::NewL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    CDrawGrid* self = CDrawGrid::NewLC(aContainer,aCurrentIndex);
+    CleanupStack::Pop(); // self;
+    return self;
+    }
+
+void CDrawGrid::ConstructL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    //iContainer = aContainer;
+    }
+
+
+TReal CDrawGrid::GetCurrentGridTilt()
+    {
+    return iPerspectiveCurrent;
+    }
+
+TReal CDrawGrid::GetGridZoom()
+    {
+    return iDrawGridZoom;
+    }
+
+TGridXY CDrawGrid::GetGridTargetXY()
+    {
+    return iDrawGridTargetXY;
+    }
+
+void CDrawGrid::SetGridTargetXY(TGridXY aValue)
+    {
+    iDrawGridTargetXY = aValue;
+    }
+
+TGridXY CDrawGrid::GetGridXY()
+    {
+    return iDrawGridXY;
+    }
+
+void CDrawGrid::SetGridXY(TGridXY aValue)
+    {
+    iDrawGridXY = aValue;
+    }
+
+void CDrawGrid::KeyPressed()
+    {
+    iMenuAlpha = 1;
+    iKeyTimer = 0;
+    iKeyTimer2 = 10;
+    }
+
+void CDrawGrid::KeyReleased()
+    {
+    iMenuAlpha = 0.99;
+    iKeyTimer = 0;
+    iKeyTimer2 = 10;
+    }
+
+void CDrawGrid::KeyEvent()
+    {
+    //iMenuAlpha = 1;
+    }
+
+/*----------------------------------------------------------------------*/
+// Set perspective projection
+//
+void CDrawGrid::SetPrespective(const TSize &aSize)
+    {
+    DP0_IMAGIC(_L("CDrawGrid::SetPrespective"));
+    // Calculate aspect ratio
+    GLfloat aspectRatio = (GLfloat)(aSize.iWidth) / (GLfloat)(aSize.iHeight);
+
+    // Calculate prespective values
+    const float near = 0.001;
+    const float far = 100.0;
+    const float top = 0.414*near;
+    const float bottom = -top;
+    const float left = aspectRatio * bottom;
+    const float right = aspectRatio * top;
+    
+    // Set perspective
+    glLoadIdentity();
+    glFrustumf(left,right, bottom,top, near,far);
+    
+    float tmp = iContainer->GetDisplayRotAngle();
+    iContainer->Interpolate(tmp, iContainer->GetDisplayRotTargetAngle(), 0.2);
+    iContainer->SetDisplayRotAngle(tmp);
+    glRotatef(iContainer->GetDisplayRotAngle(), 0,0,1);
+    }
+
+void CDrawGrid::UpdateImageCoordinates(const TInt aFirstIndex)
+    {
+    const TReal KMinY = -(CImagicContainerBrowser::KGridSizeY - 1) * CImagicContainerBrowser::KSpacingY;
+    TReal y2 = KMinY;
+    TReal x2 = -CImagicContainerBrowser::KSpacingX;
+    
+    CImageData* prevImageData = iContainer->iIEngine->GetImageData(aFirstIndex - 1);
+    if (prevImageData)
+        {
+        x2 = prevImageData->iGridData.iX;
+        y2 = prevImageData->iGridData.iY;
+        }
+
+    for(TInt i = aFirstIndex; i<iContainer->iIEngine->GetTotalNumOfImages(); i++)
+        {
+        if ((y2 -= iContainer->KSpacingY) < KMinY)
+            {
+            y2 = 0;
+            x2 += CImagicContainerBrowser::KSpacingX;
+            }
+
+        CImageData* imageData = iContainer->iIEngine->GetImageData(i);        
+#ifdef GAP_BETWEEN_FOLDERS
+        TGridMode gridMode = iContainer->iIEngine->GetImageList().GetGridMode();
+        if (gridMode)   
+            {
+            // Make small gap between folders
+            CImageData* prevImageData = iContainer->iIEngine->GetImageData(i - 1);            
+            if (prevImageData != NULL)
+                {
+                TBool gap = EFalse; 
+                if (gridMode == EGridModeFolder)
+                    {
+                    TFileName path, prevPath;
+                    imageData->GetPath(path);
+                    prevImageData->GetPath(prevPath);
+                    gap = (path != prevPath);
+                    }
+                else
+                    {
+                    gap = (imageData->iPersonId != prevImageData->iPersonId);
+                    }
+                    
+                if (gap)
+                    {
+                    x2 += CImagicContainerBrowser::KSpacingX / 2;
+                    if (y2 < 0)
+                        {
+                        x2 += CImagicContainerBrowser::KSpacingX;
+                        y2 = 0;
+                        }
+                    }
+                }
+            }
+#endif // GAP_BETWEEN_FOLDERS            
+        imageData->iGridData.iX = x2;
+        imageData->iGridData.iY = y2;
+        }
+    }
+
+void CDrawGrid::HandleKeys()
+    {
+    iKeyTimer2--;
+    if(iKeyTimer2 < 0)
+        iKeyTimer2 = 0;
+    
+    if(iKeyTimer == 0 || iKeyTimer2 == 0)
+        {
+        iKeyTimer = 3;
+        
+        CKeyData keyData = iContainer->GetKeyData();
+        
+        // Calculate new index from movement keys
+        iContainer->SetCurrentIndex(keyData.iY + iContainer->GetCurrentIndex());
+
+        // Get next image in same row
+        for (TInt i = 0;i < Abs(keyData.iX);i++)
+            {
+            TInt index = iContainer->GetCurrentIndex();
+            CImageData* currentImageData = iContainer->iIEngine->GetImageData(index);
+            while (currentImageData)
+                {
+                index += keyData.iX > 0 ? 1 : -1;
+                CImageData* imageData = iContainer->iIEngine->GetImageData(index);
+                if (imageData == NULL)
+                    {
+                    currentImageData = NULL;
+                    break;
+                    }
+                
+                // Next image is found
+                if (Abs(imageData->iGridData.iY - currentImageData->iGridData.iY) <
+                        CImagicContainerBrowser::KSpacingY / 2)
+                    {
+                    iContainer->SetCurrentIndex(index);
+                    currentImageData = NULL;
+                    break;
+                    }
+                }
+            }
+        
+        //iContainer->SetCurrentIndex(keyData.iX * CImagicContainerBrowser::KGridSizeY + iContainer->GetCurrentIndex());
+		
+        //We have to zero key data after reading it
+        keyData.iX = 0;
+        keyData.iY = 0;
+        }
+    else
+        {
+        iKeyTimer--;
+        }
+    }
+    
+/*----------------------------------------------------------------------*/
+// Initializes Grid view
+//
+void CDrawGrid::InitDrawGrid()
+    {
+    DP0_IMAGIC(_L("CDrawGrid::InitDrawGrid"));
+    
+    iKeyTimer = 0;
+    
+    iPerspectiveCurrent = 0;//current value of perspective when moving on grid by tilting while grid
+    //iPerspectiveTarget = 0;//target value of perspective
+    iDrawGridTargetZoom = KInitialZoomGrid;//Set target zooming value when draving Grid
+    
+    iGridMovingSpeed = 0.05;
+    iGridZoomSpeed = 0.1;
+    iGridZoomStep = 0.3;
+    iDrawGridZoom = KInitialZoomGrid;//Set target zooming value when draving Grid
+    
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    if(imageData)
+        imageData->iGridData.iScale = 6.5;
+    
+    // set scale a little bigger than initial target value to show animation in opening grid
+//    CImageData* imageData = iIEngine->GetImageData(iCurrentIndex, iImagicAppUi->GetUIDrawMode());
+//    if (imageData) imageData->iGridData.iScale += 0.5;
+
+    // set zooming factor a little bigger than initial target value to show animation in opening grid
+//    iDrawGridZoom = iDrawGridZoom + 0.5;
+    }
+
+/*----------------------------------------------------------------------*/
+// Draws grid
+//
+void CDrawGrid::DrawGridL(const TSize &aSize)
+    {
+    DP0_IMAGIC(_L("CDrawGrid::DrawGrid"));
+    
+    SetPrespective(aSize);// Setup perspective
+    
+    // If user hasn't press anything, stay in beginning of the grid
+    if(!iContainer->IsUserInputGiven())
+        {
+        TInt index = -1;  
+        TReal maxX = CImagicContainerBrowser::KSpacingX; 
+        if(iContainer->GetScreenSize().iHeight > 240)
+            maxX = CImagicContainerBrowser::KSpacingX * 2;
+        
+        // Select image which closest to ideal position
+        for(TInt i = 0;i < iContainer->iIEngine->GetTotalNumOfImages();i++)
+            {
+            CImageData* imageData = iContainer->iIEngine->GetImageData(i);
+            if (imageData->iGridData.iX > maxX) 
+                break;
+            if (imageData->iGridData.iY > -CImagicContainerBrowser::KSpacingY * 2)
+                index = i; 
+            }
+        
+        if (index >= 0)
+            iContainer->SetCurrentIndex(index);
+        }
+    
+    
+#ifdef MOMENTUM_MOVE
+    // Move grid x and y automatically when flick
+    // FindImageInScreen() has to be called here, before SetPerspective() to get 
+    // OpenGL matrix before initialised in it.
+    if(iContainer->iMomentumMove)
+        {
+        // so move automatically. Target is set in HandleGestureEnd(), when 
+        // user releases touch.
+
+        // Slowing down when it gets closer than the size of 10% of speed
+        // TODO: use definition. not 0.5
+        float gapX = (iContainer->iMomentumSpeedX)? (iDrawGridTargetXY.iX - iDrawGridXY.iX) / (0.5 * iContainer->iMomentumSpeedX): 0.0f;
+        float gapY = (iContainer->iMomentumSpeedY)? (iDrawGridTargetXY.iY - iDrawGridXY.iY) / (0.5 * iContainer->iMomentumSpeedY): 0.0f;
+        iContainer->CheckLimits(gapX, -1.0, 1.0); // max speed doesn't go beyond user's move
+        iContainer->CheckLimits(gapY, -1.0, 1.0);
+
+        float spdX = gapX * iContainer->iMomentumSpeedX; // speed/1sec. faster with bigger gap
+        float spdY = gapY * iContainer->iMomentumSpeedY;
+        iDrawGridXY.iX += spdX * iContainer->iTimeDiff; // movement = (open gl pixels)/sec * (elapsed time from last draw) 
+        iDrawGridXY.iY += spdY * iContainer->iTimeDiff;
+
+        DP4_IMAGIC(_L("spdX=%6.4f, gapX=%6.4f, iMomentumSpeedX=%6.4f, iTimeDiff=%6.4f"), spdX, gapX, iContainer->iMomentumSpeedX, iContainer->iTimeDiff);
+        DP3_IMAGIC(_L("spdY=%6.4f, gapY=%6.4f, iMomentumSpeedY=%6.4f"), spdY, gapY, iContainer->iMomentumSpeedY);
+        DP2_IMAGIC(_L("iDrawGridTargetX=%6.4f <=== iDrawGridX=%6.4f"), iDrawGridTargetXY.iX, iDrawGridXY.iX);
+        DP2_IMAGIC(_L("iDrawGridTargetY=%6.4f <=== iDrawGridY=%6.4f"), iDrawGridTargetXY.iY, iDrawGridXY.iY);
+        }
+
+    // Pick up the picture in the center of the screen as current selected one.
+    // Also does on dragging if not in the mode of no key event simulation on drag 
+#ifdef HOLD_SELECTION_ONDRAG
+    if(iContainer->iMomentumMove || iContainer->iHoldSelection)
+#else
+    if(iMomentumMove)
+#endif
+        {
+        TInt id;
+        FloatCoords coord;
+        coord.iX = iDrawGridXY.iX;
+        coord.iY = iDrawGridXY.iY;
+#ifdef FLICK_ONLY_IN_X_IN_GRID
+        if (iContainer->FindNearestImageInOGl(coord, id))
+            {
+            if (iContainer->iMomentumMove)
+                {
+                // Change iCurrentIndex only when x coord is changed
+                TInt cX = iContainer->GetCurrentIndex() / CImagicContainerBrowser::KGridSizeY;
+                TInt tX = id / CImagicContainerBrowser::KGridSizeY;
+                if (cX != tX) 
+                    //iCurrentIndex = id;
+                    iContainer->SetCurrentIndex(id);
+                }
+            else
+                //iCurrentIndex = id;
+                iContainer->SetCurrentIndex(id);
+            }
+#else
+        if (FindNearestImageInOGl(coord, id)) 
+            //iCurrentIndex = id;
+            iContainer->SetCurrentIndex(id);
+#endif
+        }
+
+    if(iContainer->iMomentumMove)
+        {
+        // Stop momentum move when it gets close to target or exceeds 
+        if ((!iContainer->iMomentumSpeedX || Abs(iDrawGridTargetXY.iX - iDrawGridXY.iX) < 0.15) && // 0.15 is just a guess.
+            (!iContainer->iMomentumSpeedY || Abs(iDrawGridTargetXY.iY - iDrawGridXY.iY) < 0.15))
+            {
+            iContainer->iMomentumMove = EFalse;
+            }
+        }
+#endif
+    
+    
+    
+#ifdef ZOOM_WHILE_ROTATING
+    if(Abs(iDrawGridZoom-KZoomOutMaxGrid) < 1)
+        iDrawGridTargetZoom = KInitialZoomGrid;
+#endif
+#ifdef ENABLE_GRID_ZOOM
+    Interpolate(iDrawGridZoom, iDrawGridTargetZoom, iGridZoomSpeed);
+#endif
+    
+#ifdef SCREEN_ROTATION_ON
+    Interpolate(iDisplayRotation, iDisplayRotationTarget, 0.005);
+#endif
+    
+    //Handle moving keys-------------------------------->
+    HandleKeys();
+    //Handle Rotation keys, this is for single currently selected picture
+    iContainer->HandleRotationKeys();
+    
+    //Check that current index is in grid area
+    /*TInt index = iContainer->GetCurrentIndex();
+    CheckIndexLimits(index);
+    iContainer->SetCurrentIndex(index);*/
+
+    // Update AppUI class about selected picture index
+    if(iContainer->GetPrevIndex() != iContainer->GetCurrentIndex())
+        {
+        iContainer->iImagicAppUi->SetImageIndex(iContainer->GetCurrentIndex());
+        iContainer->iDynamicLoadingOn = ETrue;
+
+//#define DISPLAY_DATE
+#ifdef DISPLAY_DATE
+        DisplayDate();
+#endif
+        //Update previous Grid index..
+        iContainer->SetPrevIndex(iContainer->GetCurrentIndex());        
+        }
+    
+#ifdef MOMENTUM_MOVE
+    if(!iContainer->iMomentumMove) 
+        {
+#endif
+        //Calculate new target X and Y positions on Grid
+
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    if (imageData)
+        {
+        iDrawGridTargetXY.iX = imageData->iGridData.iX;
+        iDrawGridTargetXY.iY = -imageData->iGridData.iY;
+        }
+
+#ifdef HOLD_SELECTION_ONDRAG
+        if (iContainer->iHoldSelection == EFalse) 
+            {
+#endif
+            //and interpolate between current and target Y and X
+            iContainer->Interpolate(iDrawGridXY.iX, iDrawGridTargetXY.iX, iGridMovingSpeed);
+            iContainer->Interpolate(iDrawGridXY.iY, iDrawGridTargetXY.iY, iGridMovingSpeed);
+    
+#ifdef HOLD_SELECTION_ONDRAG
+            }
+#endif
+#ifdef MOMENTUM_MOVE
+        }
+#endif
+    
+    // Zooming
+    //Calculate new target zooming value for Grid
+//unno temp iGridZoomSpeed = 20 * iTimeDiff;
+#ifdef ENABLE_GRID_ZOOM
+    iDrawGridTargetZoom += keyData.iZoomIn * iGridZoomStep;
+    iDrawGridTargetZoom -= keyData.iZoomOut * iGridZoomStep;
+    CheckLimits(iDrawGridTargetZoom, KZoomOutMaxGrid, KZoomInMaxGrid);
+
+    keyData.iZoom = 0;//we have to reset key data after using it
+    keyData.iZoomIn = keyData.iZoomOut = EFalse;
+#endif
+    
+    //Handle Rotation keys, this is for single currently selected picture
+    //iContainer->HandleRotationKeys();
+    
+    
+    // Draw images ---------------------------------->
+    
+    //Tilt Grid(camera) into moving direction
+    float perspectiveDiff = iDrawGridTargetXY.iX-iDrawGridXY.iX;
+    perspectiveDiff *= 10;
+    
+    //we stop moving of the grid littele bit earlier than we are in real zero
+#ifdef HOLD_SELECTION_ONDRAG
+    if(iContainer->iHoldSelection == EFalse) {
+#endif
+    iTargetPerspective = perspectiveDiff;
+#ifdef HOLD_SELECTION_ONDRAG
+    }
+#endif
+
+    
+    //Speed up tilting when getting closer to target
+    if(iPerspectiveCurrent-iTargetPerspective != 0 && 
+       (Abs(iTargetPerspective) < Abs(iPerspectiveCurrent)) && 
+       Abs(iPerspectiveCurrent) < 20)
+        {
+        iContainer->Interpolate(iPerspectiveCurrent,iTargetPerspective, Abs((KMaxAngleLandscape/iPerspectiveCurrent)/40));
+        }
+    else
+        {
+        iContainer->Interpolate(iPerspectiveCurrent,iTargetPerspective, 0.04);
+        }
+        
+    
+#ifdef _ACCELEROMETER_SUPPORTED_
+//#ifndef _S60_5x_ACCELEROMETER_
+    if(iContainer->iDeviceOrientation == EOrientationDisplayLeftUp)//Landscape
+/*#else if _S60_5x_ACCELEROMETER_
+    if(iContainer->iDeviceOrientation == (TImagicDeviceOrientation)TSensrvOrientationData::EOrientationDisplayRightUp)///this is wrong
+#endif*/
+#else
+    if(ETrue/*iDeviceOrientation*/)//if no accelerometer, use always landscape
+#endif
+        iContainer->CheckLimits(iPerspectiveCurrent, -KMaxAngleLandscape, KMaxAngleLandscape);  
+    else
+        iContainer->CheckLimits(iPerspectiveCurrent, -KMaxAnglePortrait, KMaxAnglePortrait);
+    
+    glRotatef(iPerspectiveCurrent, 0,1,0);//make perspective when moving on grid
+    
+    
+    
+    //Go to grid position ----------->
+    //Center picture grid and set limit of pictures to be drawn
+    float centerOffset=2.9;//bigger value -> less movement in Y-axis
+    
+#ifdef MOMENTUM_MOVE
+    glTranslatef(-iDrawGridXY.iX-iDrawGridZoom*iPerspectiveCurrent/KMaxAngleLandscape,
+            CImagicContainerBrowser::KSpacingY+(iDrawGridXY.iY-CImagicContainerBrowser::KSpacingY)/centerOffset, iDrawGridZoom);
+#else
+    glTranslatef(-iDrawGridX, KSpacingY+(iDrawGridY-KSpacingY)/centerOffset, iDrawGridZoom);
+#endif
+    
+    //OpenGl Vertex data
+    GLfixed vertices[8];
+    glVertexPointer( 2, GL_FIXED, 0, vertices );
+    
+    //Bind into a null picture
+    //iContainer->iCurrentBindedIndex = iContainer->iLoadingTextureIndex;
+    //iContainer->iLoadingTextureIndex = 0;
+    //glBindTexture( GL_TEXTURE_2D, iContainer->iLoadingTextureIndex);
+    glBindTexture( GL_TEXTURE_2D, 0);
+    
+       
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   	
+    // Set gray color for pictures that are not loaded yet
+    glColor4f(0.3,0.3,0.3, 1);
+    
+    TInt drawMax = iContainer->GetCurrentIndex()+KDrawLimit;
+    TInt drawMin = iContainer->GetCurrentIndex()-KDrawLimit;
+
+    CImageData* currentImageData = NULL;
+    TGridMode gridMode = iContainer->iIEngine->GetImageList().GetGridMode();
+    if (gridMode != EGridModeTime)      
+        currentImageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    //This loop draws all the textures in the grid ------------------------------->
+    for(TInt i2=0; i2<iContainer->iIEngine->GetTotalNumOfImages(); i2++)
+        {
+        TInt i = (i2 + iContainer->GetCurrentIndex() + 1) % iContainer->iIEngine->GetTotalNumOfImages();
+        CImageData* imageData = iContainer->iIEngine->GetImageData(i);
+        
+        //If we are in same picture index, ie. not moving, draw both sides equally
+        if(drawMax > iContainer->iIEngine->GetTotalNumOfImages()-1)
+            drawMax = iContainer->iIEngine->GetTotalNumOfImages()-1;
+        if(drawMin < 0)
+            drawMin = 0;
+            
+        //Do not draw all images, just enough to fill the screen
+        if((Abs(imageData->iGridData.iRotationAngle-imageData->iGridData.iTargetRotationAngle) > 0.1) || //Draw all all images in grid if rotated
+           (i>=drawMin && i<=drawMax))
+            {
+            // Calculate current coordinates
+            //TInt x = i/iContainer->iGridSizeY;
+            //TInt y = -(i%iContainer->iGridSizeY);// Y axis is inverted
+            float z=0;
+            //float scale=1;
+            iScaleTarget = 1;
+            
+            
+            //Highlight by scaling up selected picture on Grid
+            if(iContainer->GetCurrentIndex()==i)
+                {
+                z=0.3;
+                iScaleTarget = 1.5;
+                }
+
+            TBool dim = EFalse; //(currentImageData && !currentImageData->IsSamePath(*imageData));            
+            //BubbleEffect(x, y, z);
+            
+            //Zoom out the grid if "camera target" is far away from current position >>>
+            //if (Abs(iDrawGridX-iDrawGridTargetX) > 10*KSpacingX)
+#ifdef MOMENTUM_MOVE
+            float absDeltaX = Abs(iDrawGridXY.iX-iDrawGridTargetXY.iX);
+            if((!iContainer->iMomentumMove && absDeltaX > 2*CImagicContainerBrowser::KSpacingX) ||
+               ( iContainer->iMomentumMove && absDeltaX > 5*CImagicContainerBrowser::KSpacingX))
+#else
+            if(Abs(iDrawGridX-iDrawGridTargetX) > 2*KSpacingX)
+#endif
+                {
+                z=KTargetZCoord;
+                iContainer->Interpolate(imageData->iGridData.iZ, z, 0.05);
+                }    
+            else
+                {
+                iContainer->Interpolate(imageData->iGridData.iZ, z, 0.05);
+                }
+            
+            iContainer->Interpolate(imageData->iGridData.iScale, iScaleTarget, 0.23);
+            //Zoom out the grid if "camera target" is far away from current position <<<
+            
+            //Rotate picture in Grid if needed
+            iContainer->HandleRotation(imageData->iGridData.iRotationAngle, imageData->iGridData.iTargetRotationAngle);
+            
+            //Calculate new picture vertices to fix picture aspect ratio
+            iContainer->SetPictureVertices(imageData, vertices);
+            
+            //Move camera to picture position and rotate and scale it
+            glPushMatrix();    
+            glTranslatef(imageData->iGridData.iX, imageData->iGridData.iY, imageData->iGridData.iZ);// - (dim ? 1.0 : 0));
+            glRotatef(imageData->iGridData.iRotationAngle, 0,0,1);
+            TReal scale = imageData->iGridData.iScale;
+            glScalef(scale, scale, scale);
+            
+#ifdef SHADOW_PHOTOS
+            // Draw shadow behind image
+            glPushMatrix();
+            glBindTexture( GL_TEXTURE_2D, iContainer->iShadowTextureIndex);
+            glTranslatef(0, 0, -0.15);
+            glScalef(1.2, 1.2, 1);
+            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+            glPopMatrix();
+#endif                     
+            
+#ifdef DRAW_FRAME
+            // Draw frame around selected image
+            if (iContainer->GetCurrentIndex()==i)
+                DrawFrame(i);
+#endif
+                    
+            // Calculate color for not loaded picture, more far from selection-> darker box
+            float color = 
+#ifdef EMPTY_IMAGE_AS_WIREFRAME
+                0.05 + 0.2/
+#else
+                1.0/
+#endif                
+                (Abs(iDrawGridXY.iX - imageData->iGridData.iX)/2 + .2);
+            if (color > 0.5)
+                color = 0.5;
+            glColor4f(color,color,color, 1);
+            
+            //Bind to a new picture only if needed, ie. we really have new picture
+            if(imageData->iGridData.iGlLQ128TextIndex != iLastGridTexture ||
+               imageData->iGridData.iGlLQ32TextIndex != iLastGridTexture)
+                {
+                if(imageData->iGridData.iGlLQ128TextIndex)
+                    iLastGridTexture = imageData->iGridData.iGlLQ128TextIndex;
+                else if(imageData->iGridData.iGlLQ32TextIndex)
+                    iLastGridTexture = imageData->iGridData.iGlLQ32TextIndex;
+                else
+                    iLastGridTexture = iContainer->iLoadingTextureIndex;
+                
+                iContainer->iCurrentBindedIndex = iLastGridTexture;
+                glBindTexture( GL_TEXTURE_2D, iLastGridTexture);
+                
+                // Picture is loaded, draw it with white color
+                if (iLastGridTexture)  
+                    {
+                    // Draw as solid black frame
+                    if (dim)
+                        glColor4f(0.4,0.4,0.4, 1);
+                    else
+                        glColor4f(1,1,1, 1);
+                    }
+                }
+            
+            // Draw image
+#ifdef EMPTY_IMAGE_AS_WIREFRAME            
+            if (iLastGridTexture == 0 && iContainer->GetCurrentIndex() != i)
+                {
+                GLfixed p;
+                p = vertices[6]; vertices[6] = vertices[4]; vertices[4] = p;
+                p = vertices[7]; vertices[7] = vertices[5]; vertices[5] = p;
+                glLineWidth(1.8f);  // TODO: depend on resolution
+                glDrawArrays(GL_LINE_LOOP,0,4);
+                p = vertices[6]; vertices[6] = vertices[4]; vertices[4] = p;
+                p = vertices[7]; vertices[7] = vertices[5]; vertices[5] = p;
+                }
+            else
+                {
+                // Draw as solid black frame
+                if (iLastGridTexture == 0)
+                    glColor4f(0,0,0, 1);
+#endif                
+                glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+#ifdef EMPTY_IMAGE_AS_WIREFRAME                
+                }
+#endif            
+           
+            glPopMatrix();
+            }//if
+        
+        //EGLint err = eglGetError();
+        EGLint err = glGetError();
+        //if(err != EGL_SUCCESS)
+        while(err != GL_NO_ERROR)
+            {
+            CImageData* data = iContainer->iIEngine->GetImageData(i);
+            //Delete all textures for this index just in case
+            if(data->iGridData.iGlLQ128TextIndex)
+                glDeleteTextures(1, &data->iGridData.iGlLQ128TextIndex);data->iGridData.iGlLQ32TextIndex = 0;
+            if(data->iGridData.iGlLQ32TextIndex)
+                glDeleteTextures(1, &data->iGridData.iGlLQ32TextIndex);data->iGridData.iGlLQ128TextIndex = 0;
+            if(data->iGridData.iGlHQ512TextIndex)
+                glDeleteTextures(1, &data->iGridData.iGlHQ512TextIndex);data->iGridData.iGlHQ512TextIndex = 0;
+            if(data->iGridData.iGlSuperHQTextIndex)
+                glDeleteTextures(1, &data->iGridData.iGlSuperHQTextIndex);data->iGridData.iGlSuperHQTextIndex = 0;
+            
+            err = eglGetError();
+            }
+                        
+        }//for
+    
+#if 0
+    if(iMenuAlpha < 1)
+        {
+        iMenuAlpha-=0.15;
+        if(iMenuAlpha < 0)
+            iMenuAlpha = 0;
+        }
+
+    iContainer->iDrawUtility->DrawIcon2(iContainer->Size(), iContainer->iMenuTextureIndex, iMenuAlpha);
+#endif
+    
+    iContainer->DynamicLoadingL();
+    }
+
+
+TBool CDrawGrid::IsDrawingNeededGrid()
+    {
+    
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    iContainer->SetMinMagFilterLinear(EFalse);
+#if 0
+    if(iMenuAlpha != 0)
+        {
+        return ETrue;
+        }
+#endif
+    if(Abs(iPerspectiveCurrent) < CImagicContainerBrowser::KAngle2Start128Loading && Abs(iPerspectiveCurrent) > 0.001)
+        {
+        //DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #0"));
+        iContainer->iDynamicLoadingOn = ETrue;
+        }
+    
+    
+    //Make sure that all visible images are rotated
+    //this causes too much processor load
+    /*for(TInt i=0; i<=CImagicContainerBrowser::K128TNImageBuffer; i++)
+        {
+        for(TInt j=0; j<2; j++)
+            {
+            TInt index = iContainer->GetCurrentIndex() + (j ?  i : -i);
+            
+            CImageData* imageData = iContainer->iIEngine->GetImageData(index);
+            
+            if(imageData != NULL)
+                if(Abs(imageData->iGridData.iRotationAngle - imageData->iGridData.iTargetRotationAngle) > 0.01)
+                    {
+                    DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #0.1"));
+                    return ETrue;
+                    }
+                else if(imageData->iGridData.iRotationAngle != imageData->iGridData.iTargetRotationAngle)
+                    {
+                    DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #0.2"));
+                    imageData->iGridData.iRotationAngle = imageData->iGridData.iTargetRotationAngle;
+                    return ETrue;
+                    }
+            }
+        }*/
+    
+    //CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    if(imageData)
+        if(Abs(imageData->iGridData.iScale - iScaleTarget) > 0.1)
+            {
+            return ETrue;
+            }
+        else if(imageData->iGridData.iScale != iScaleTarget)
+            {
+            imageData->iGridData.iScale = iScaleTarget;
+            return ETrue;
+            }
+    
+    
+#ifdef ENABLE_DISPLAY_ROTATION
+    if(Abs(iContainer->GetDisplayRotAngle() - iContainer->GetDisplayRotTargetAngle()) > 1)
+        {
+        DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #2"));
+        return ETrue;
+        }
+    else if(iContainer->GetDisplayRotAngle() != iContainer->GetDisplayRotTargetAngle())
+        {
+        iContainer->SetDisplayRotAngle(iContainer->GetDisplayRotTargetAngle());
+        return ETrue;
+        }
+#endif
+    
+    if(imageData)
+        if(Abs(imageData->iGridData.iRotationAngle-imageData->iGridData.iTargetRotationAngle) > 1)
+            {
+            DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #3"));
+            return ETrue;
+            }
+        else if(imageData->iGridData.iRotationAngle != imageData->iGridData.iTargetRotationAngle)
+            {
+            imageData->iGridData.iRotationAngle = imageData->iGridData.iTargetRotationAngle;
+            //iContainer->iDrawNow = ETrue;
+            return ETrue;
+            }
+    
+#ifdef ENABLE_GRID_ZOOM
+    if(Abs(iDrawGridZoom - iDrawGridTargetZoom) > 0.01)
+        {
+        DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #4"));
+        return ETrue;
+        }
+#endif
+    
+    if(Abs(iDrawGridXY.iX - iDrawGridTargetXY.iX) > 0.02)
+        {
+        DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #5"));
+        return ETrue;
+        }
+    else if(iDrawGridXY.iX != iDrawGridTargetXY.iX)
+        {
+        iDrawGridXY.iX = iDrawGridTargetXY.iX;
+        }
+    
+    if(Abs(iDrawGridXY.iY - iDrawGridTargetXY.iY) > 0.02)
+        {
+        DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #6"));
+        return ETrue;
+        }
+    else if(iDrawGridXY.iY != iDrawGridTargetXY.iY)
+        {
+        iDrawGridXY.iY = iDrawGridTargetXY.iY;
+        }
+    
+    if(Abs(iPerspectiveCurrent - iTargetPerspective) > 0.1)
+        {
+        DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #7"));
+        return ETrue;
+        }
+    else if(iPerspectiveCurrent != iTargetPerspective)
+        {
+        DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #7.1"));
+        iPerspectiveCurrent = iTargetPerspective;
+        return ETrue;
+        }
+    
+    if(iContainer->iDrawNow)
+        {
+        DP0_IMAGIC(_L("CDrawGrid::IsDrawingNeededGrid #1"));
+        iContainer->iDrawNow = EFalse;
+        return ETrue;
+        }
+    
+    return EFalse;
+    }
+
+
+void CDrawGrid::MovingDirection()
+    {
+    if(iContainer->GetPrevIndex() < iContainer->GetCurrentIndex())
+        {
+        iMovingRight = ETrue;
+        iMovingLeft = EFalse;
+        }
+    else if(iContainer->GetPrevIndex() > iContainer->GetCurrentIndex())
+        {
+        iMovingLeft = ETrue;
+        iMovingRight = EFalse;
+        }
+    else if(iContainer->GetPrevIndex() == iContainer->GetCurrentIndex())
+        {
+        iMovingRight = EFalse; 
+        iMovingLeft = EFalse;
+        }
+    }
+
+void CDrawGrid::DisplayDate()
+    {
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    if(imageData)
+        {
+        TDateTime dateTime = imageData->GetCreatedTime().DateTime();
+        if(iPrevDateTime.Month() != dateTime.Month())
+            {
+            TMonth month = dateTime.Month();
+            iContainer->iImagicAppUi->GetImagicUtils()->DisplayYearAndMonth(0, dateTime);
+            }
+        iPrevDateTime = dateTime;
+        }
+    }
+
+/*----------------------------------------------------------------------*/
+// Calculates widht and height with aspect ratio
+//
+void CDrawGrid::DrawFrame(TInt aIndex)
+    {
+    // Draw frame around selected image
+    glPushMatrix();
+    glDisable(GL_TEXTURE_2D);
+    
+    glDisable(GL_DEPTH_TEST);
+    
+    //Frame size
+    float scale=1.09;        
+#ifdef FRAME_COLOR_CHANGE
+    if(iSelectionFrameColor >= 1.0)
+        iSelectionFrameColor-=0.05;
+        
+    if(iSelectionFrameColor <= 0.3)
+        iSelectionFrameColor+= 0.05;
+
+    if(iTNCreationComplete)
+        glColor4f(iSelectionFrameColor,iSelectionFrameColor,iSelectionFrameColor, 1);
+    else
+        glColor4f(1,iSelectionFrameColor,iSelectionFrameColor, 1);
+#else
+#ifdef SHADOW_PHOTOS
+    glColor4f(1,0,0, 1);        // red frame
+#else    
+    glColor4f(1,1,1, 1);        // white frame
+#endif    
+#endif
+    
+    glTranslatef(0,0,-0.03);
+    glScalef(scale,scale,scale);
+    glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+    
+    //glDisable(GL_BLEND);
+    //glDisable(GL_DEPTH_TEST);
+    
+    glEnable(GL_TEXTURE_2D);
+    glPopMatrix();
+    }
+
+/*----------------------------------------------------------------------*/
+// Calculates widht and height with aspect ratio
+//
+void CDrawGrid::BubbleEffect(TInt& x, TInt& y, float& z)
+    {
+    if(iBubbleEffect)
+        {
+        // Selected image in coordinates x,y
+        TInt selectedX = iContainer->GetCurrentIndex()/3 /*iGridSizeY*/;
+        TInt selectedY =- (iContainer->GetCurrentIndex()%3 /*iGridSizeY*/);
+                    
+        // Distance to selected
+        iDistanceX = selectedX-x;
+        iDistanceY = selectedY-y;
+        // Squared
+        if(iDistanceX<0) iDistanceX*= -1;
+        if(iDistanceY<0) iDistanceY*= -1;
+        
+        // Distance
+        iDiff=iDistanceX+iDistanceY;
+        // Convert distance to depth
+        // http://en.wikipedia.org/wiki/Gaussian_function
+        if (iDiff==0) z=5.0;
+        if (iDiff==1) z=4.2;
+        if (iDiff==2) z=3.4;
+        if (iDiff==3) z=2.1;
+        if (iDiff==4) z=1.3;
+        if (iDiff==5) z=0.8;
+        if (iDiff==6) z=0.4;
+        if (iDiff==7) z=0.3;
+        if (iDiff>7) z=0.3;
+        //if (iDiff==8) z=0.1;
+        //if (iDiff==9) z=0.05;
+        //if (iDiff==10) z=0.01;
+        //if (iDiff>10) z=0;
+        }
+    }
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/CDrawMagGlass.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,288 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "CDrawMagGlass.h"
+#include "TextureLoader.h"
+#include "DrawUtility.h"
+#include "ImagicConsts.h"
+
+
+GLfixed CDrawMagGlass::iMagGlassVertices[VERTICES_PER_LINE*VERTICES_PER_LINE*3];
+GLfixed CDrawMagGlass::iMagGlassTex[VERTICES_PER_LINE*VERTICES_PER_LINE*2];
+    
+const TInt CDrawMagGlass::iMagGlassTriCount=(VERTICES_PER_LINE-1)*(VERTICES_PER_LINE-1)*2;
+GLushort CDrawMagGlass::iMagGlassIndices[CDrawMagGlass::iMagGlassTriCount*3];
+
+
+
+// Texture coordinate data
+const GLfixed CDrawMagGlass::iGlobalTexCoords[] =
+   {
+   //bitmap has to be flipped over
+   0,       1<<16,
+   1<<16,   1<<16,
+   0,       0,
+   1<<16,   0
+   };
+
+CDrawMagGlass::CDrawMagGlass()
+    {
+    // No implementation required
+    }
+
+CDrawMagGlass::~CDrawMagGlass()
+    {
+    }
+
+CDrawMagGlass* CDrawMagGlass::NewLC(CImagicContainerBrowser* aContainer, CDrawOneByOne* aDrawOneByOne)
+    {
+    CDrawMagGlass* self = new (ELeave) CDrawMagGlass();
+    CleanupStack::PushL(self);
+    self->ConstructL(aContainer,aDrawOneByOne);
+    return self;
+    }
+
+CDrawMagGlass* CDrawMagGlass::NewL(CImagicContainerBrowser* aContainer, CDrawOneByOne* aDrawOneByOne)
+    {
+    CDrawMagGlass* self = CDrawMagGlass::NewLC(aContainer,aDrawOneByOne);
+    CleanupStack::Pop(); // self;
+    return self;
+    }
+
+void CDrawMagGlass::ConstructL(CImagicContainerBrowser* aContainer, CDrawOneByOne* aDrawOneByOne)
+    {
+    iContainer = aContainer;
+    iDrawOneByOne = aDrawOneByOne;
+    }
+
+TReal CDrawMagGlass::GetMagGlassZoomFactor()
+    {
+    DP1_IMAGIC(_L("CDrawMagGlass::GetMagGlassZoomFactor - magGlass: %f"), iMagGlassZoomFactor);
+    return iMagGlassZoomFactor;
+    }
+
+/*----------------------------------------------------------------------*/
+// Interpolates given value into target value with step
+//
+void CDrawMagGlass::Interpolate(float &aValue, const float aTarget, const float aStep)
+    {
+    //DP0_IMAGIC(_L("CImagicContainerBrowser::Interpolate"));
+    // Calculate new value
+    float diff = aTarget-aValue;
+    aValue += diff * aStep * 0.2/*iTimeDiff*/ * 30; 
+    //float timediff = Min(0.1f, iTimeDiff); // so max value of timediff is 100tick (100ms)
+    //aValue += diff * aStep * timediff * 30; 
+    
+    // Check that value is in range
+    if (aValue > aTarget && diff > 0)
+        aValue = aTarget;
+    if (aValue < aTarget && diff < 0)
+        aValue = aTarget;
+    }
+
+void CDrawMagGlass::InitDrawMagGlass()
+    {
+    iMagGlassZoomFactor = 1;
+    
+    TInt pos=0;
+    for (TInt y=0; y<VERTICES_PER_LINE-1; y++)
+        {
+        TInt startvert=y*VERTICES_PER_LINE;
+        for (TInt x=0; x<VERTICES_PER_LINE-1; x++, pos+=6)
+            {
+            // First triangle
+            iMagGlassIndices[pos+0]=startvert+x;
+            iMagGlassIndices[pos+1]=startvert+x+1;
+            iMagGlassIndices[pos+2]=startvert+x+VERTICES_PER_LINE;
+            
+            // Second triangle
+            iMagGlassIndices[pos+3]=startvert+x+VERTICES_PER_LINE;
+            iMagGlassIndices[pos+4]=startvert+x+1;
+            iMagGlassIndices[pos+5]=startvert+x+VERTICES_PER_LINE+1;
+            }
+        }
+    }
+    
+void CDrawMagGlass::DrawMagGlass(const TSize &aScreenPhysicalSize, TReal aImageAspectRatio)
+    {
+    TInt pos=0;
+    
+#ifdef __WINS__ 
+    // Fake touhcpoint for emulator
+    iContainer->iLastTouchPoint.iX=320/2;
+    iContainer->iLastTouchPoint.iY=240/2;
+#endif
+        
+    // Calculate finger position on screen
+    // First calculate position on 0-1 range
+    GLfixed xFinger;
+    GLfixed yFinger;
+    if(iContainer->GetScreenOrientation())
+        {
+        const TInt fingerOffset = 100;
+        xFinger=iContainer->iLastTouchPoint.iX*(1<<16) / aScreenPhysicalSize.iWidth;
+        yFinger=(iContainer->iLastTouchPoint.iY-fingerOffset)*(1<<16) / aScreenPhysicalSize.iHeight;
+        }
+    else
+        {
+        const TInt fingerOffset = 100;
+        xFinger=(iContainer->iLastTouchPoint.iX-fingerOffset)*(1<<16) / aScreenPhysicalSize.iWidth;
+        yFinger=(iContainer->iLastTouchPoint.iY)*(1<<16) / aScreenPhysicalSize.iHeight;
+        }
+    
+    // Move center to match OpenGL center
+    xFinger=-(0.5*(1<<16)-xFinger);
+    yFinger=0.5*(1<<16)-yFinger;
+    // Then scale it to opengl window size
+    /*xFinger=xFinger*iContainer->iDrawOnebyOneW*2;
+    yFinger=yFinger*iContainer->iDrawOnebyOneH*2;*/
+    xFinger=xFinger*iDrawOneByOne->GetDrawOneByOneWidth()*2;
+    yFinger=yFinger*iDrawOneByOne->GetDrawOneByOneHeight()*2;
+        
+    
+    CImageData* data=iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    if((data->GetOrientation() == 0 || data->GetOrientation() == 180) && !iContainer->GetScreenOrientation())
+        {
+        GLfixed tmpX=xFinger;
+        GLfixed tmpY=yFinger;
+        xFinger = tmpY;
+        yFinger = tmpX * -1;
+        }
+    else if(data->GetOrientation() == 0)
+        ;
+    else if((data->GetOrientation() == 90 || data->GetOrientation() == 270) && iContainer->GetScreenOrientation())
+        {
+        GLfixed tmpX=xFinger;
+        GLfixed tmpY=yFinger;
+        xFinger = tmpY;
+        yFinger = tmpX * -1;
+        }
+    else if((data->GetOrientation() == 90 || data->GetOrientation() == 270) && !iContainer->GetScreenOrientation())
+        {
+        xFinger = xFinger * -1;
+        yFinger = yFinger * -1;
+        }
+    
+    
+    //Interpolate(iMagGlassZoomFactor, 1.8, 0.05);
+    //const float step=0.3; 
+    //const float step=0.2;
+    /*
+    if (iMagGlassZoomFactor < CDrawOneByOne::KMaxMagGlassZoomFactor-step)
+        //iDrawOneByOne->IncMagGlassZoomFactor(step);
+        iMagGlassZoomFactor += step;
+    else
+        //iDrawOneByOne->SetMagGlassZoomFactor(CDrawOneByOne::KMaxMagGlassZoomFactor);
+        iMagGlassZoomFactor = CDrawOneByOne::KMaxMagGlassZoomFactor;
+    */
+    Interpolate(iMagGlassZoomFactor, CDrawOneByOne::KMaxMagGlassZoomFactor, 0.1);
+    DP1_IMAGIC(_L("CDrawMagGlass::DrawMagGlass - magGlass: %f"), iMagGlassZoomFactor);
+    
+    /*CImageData* data=iIEngine->GetImageData(iCurrentIndex, iImagicAppUi->GetUIDrawMode());
+    if(data->GetOrientation() == 90 || data->GetOrientation() == 270)
+        aImageAspectRatio = 1/aImageAspectRatio;*/
+    
+    // Create vertices
+    pos=0;
+    TInt texPos=0;
+    for (TInt y=0; y<VERTICES_PER_LINE; y++)
+        for (TInt x=0; x<VERTICES_PER_LINE; x++,pos+=3,texPos+=2)
+            {
+            // Calculate new vertex coordinates
+            // First, calculate center
+            GLfixed xCoord= x;
+            GLfixed yCoord=-y;
+            GLfixed zCoord= 0;
+            // Then convert to fixed point
+            xCoord*=(1<<16)/(VERTICES_PER_LINE-1);
+            yCoord*=(1<<16)/(VERTICES_PER_LINE-1);
+            // shift 0.5 to locate image center at (0,0) 
+            xCoord -= (1<<15);
+            yCoord += (1<<15);
+            
+            // Set aspect ratio
+            if (aImageAspectRatio > 1)
+                yCoord *= (1/aImageAspectRatio);
+            else
+                xCoord *= (1*aImageAspectRatio);
+            
+            
+            // Zoom ball sizes
+            const float ballSize=0.35;      // Zoom ball size
+            const float zoomSize=0.2;     // Sharp zoom size, has to be at least 0.1 smaller bigger than ball size
+            // Calculate squared values
+            const GLfixed ballSizeSquared=(ballSize*(1<<8))*(ballSize*(1<<8));
+            const GLfixed zoomSizeSquared=(zoomSize*(1<<8))*(zoomSize*(1<<8));
+            
+            // Calculate distance to finger with both axis
+            GLfixed xDist=xFinger-xCoord;
+            GLfixed yDist=yFinger-yCoord;
+            // Calculate squared distance with phytagoras
+            GLfixed dist=(xDist/(1<<8))*(xDist/(1<<8)) + (yDist/(1<<8))*(yDist/(1<<8));
+            
+            // Are we close enough
+            if (dist < ballSizeSquared)
+                {
+                // Zoom factor
+                //const float iMagGlassZoomFactor=1.8;
+                
+                // Determine proper zoom for this vertex
+                //float zoom=iContainer->iMagGlassZoomFactor;
+                float zoom=iMagGlassZoomFactor;
+                
+                if (dist > zoomSizeSquared)
+                    {
+                    // We are between sharp zoom and ball edge
+                    // Calculat escale factor for zoom
+                    float scale=((float)(dist-zoomSizeSquared))/(ballSizeSquared-zoomSizeSquared);
+                    zoom=(zoom-1)*(1.0-scale)+1;
+                    }
+                
+                // Calculate new axis distances with zoom
+                xDist*=zoom;
+                yDist*=zoom;
+                // Calculate new coordinates based on distances
+                xCoord=xFinger-xDist;
+                yCoord=yFinger-yDist;
+                zCoord=128;     // Set coordinate a bit above of original picture
+                }
+            
+            // Store vertex data
+            iMagGlassVertices[pos+0]=xCoord;
+            iMagGlassVertices[pos+1]=yCoord;
+            iMagGlassVertices[pos+2]=zCoord;
+            
+            // Set texture coodrinates
+            iMagGlassTex[texPos+0]=x*(1<<16)/(VERTICES_PER_LINE-1);
+            iMagGlassTex[texPos+1]=y*(1<<16)/(VERTICES_PER_LINE-1);
+            }
+    
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_CULL_FACE);
+    glCullFace(GL_FRONT);
+    
+    // Set vertex and texture coordinates and draw
+    glVertexPointer(3, GL_FIXED, 0, iMagGlassVertices);
+    glTexCoordPointer(2, GL_FIXED, 0, iMagGlassTex);
+    glDrawElements(GL_TRIANGLES,iMagGlassTriCount*3,GL_UNSIGNED_SHORT,iMagGlassIndices);
+    //glDrawElements(GL_LINES,triCount*3,GL_UNSIGNED_SHORT,indices);
+    
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_DEPTH_TEST);
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/CDrawOneByOne.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,909 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "CDrawOneByOne.h"
+#include "TextureLoader.h"
+#include "DrawUtility.h"
+#include "ImagicConsts.h"
+
+#define IS_NOT_IN_ZOOM_ONEBYONE ((iDrawOneByOneTargetZoom) < (iContainer->KDoubleTapZoomOneByOne1 + 0.01f))
+#define IS_ALMOST_ZERO (0.001)
+
+
+const float CDrawOneByOne::KMaxMagGlassZoomFactor = 2.2;//2.0;
+const float KOneByOneSlideSpeed = 0.24;
+
+
+CDrawOneByOne::CDrawOneByOne(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex):
+    iContainer(aContainer)//,
+    {
+    iMagGlassOn = EFalse;
+    iMagGlassOnPrev = EFalse;
+    }
+
+CDrawOneByOne::~CDrawOneByOne()
+    {
+    delete iMagGlass;
+    }
+
+CDrawOneByOne* CDrawOneByOne::NewLC(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    CDrawOneByOne* self = new (ELeave) CDrawOneByOne(aContainer, aCurrentIndex);
+    CleanupStack::PushL(self);
+    self->ConstructL(aContainer, aCurrentIndex);
+    return self;
+    }
+
+CDrawOneByOne* CDrawOneByOne::NewL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    CDrawOneByOne* self = CDrawOneByOne::NewLC(aContainer, aCurrentIndex);
+    CleanupStack::Pop(); // self;
+    return self;
+    }
+
+void CDrawOneByOne::ConstructL(CImagicContainerBrowser* aContainer, TInt& aCurrentIndex)
+    {
+    iMagGlass = CDrawMagGlass::NewL(iContainer, this);
+    }
+
+float CDrawOneByOne::GetMovingStep()
+    {
+    //iMovingStep = 0.01/(iDrawOneByOneZoom/8.0);
+    iMovingStep = 0.015/(iDrawOneByOneZoom/8.0);
+    return iMovingStep;
+    }
+
+float CDrawOneByOne::GetImgeFlowLocation()
+    {
+    return iOneByOneFlow;
+    }
+
+void CDrawOneByOne::SetImgeFlowLocation(float aValue)
+    {
+    iOneByOneFlow = aValue;
+    }
+
+TDrawOneByOneXY CDrawOneByOne::GetDrawOneByOneXY()
+    {
+    return iDrawOneByOneXY;
+    }
+
+TDrawOneByOneXY CDrawOneByOne::GetDrawOneByOneTargetXY()
+    {
+    return iDrawOneByOneTargetXY;
+    }
+
+void CDrawOneByOne::SetDrawOneByOneTargetXY(TDrawOneByOneXY aValue)
+    {
+    iDrawOneByOneTargetXY = aValue;
+    }
+
+void CDrawOneByOne::ChangeDrawOneByOneTargetX(float aValue)
+    {
+    iDrawOneByOneTargetXY.iX += aValue;
+    }
+
+void CDrawOneByOne::ChangeDrawOneByOneTargetY(float aValue)
+    {
+    iDrawOneByOneTargetXY.iY += aValue;
+    }
+
+float CDrawOneByOne::GetDrawOneByOneZoom()
+    {
+    return iDrawOneByOneZoom;
+    }
+
+void CDrawOneByOne::SetDrawOneByOneZoom(float aValue)
+    {
+    iDrawOneByOneZoom = aValue;
+    }
+
+float CDrawOneByOne::GetDrawOneByOneTargetZoom()
+    {
+    return iDrawOneByOneTargetZoom;
+    }
+
+void CDrawOneByOne::SetDrawOneByOneTargetZoom(float aValue)
+    {
+    iDrawOneByOneTargetZoom = aValue;
+    }
+
+float CDrawOneByOne::GetDrawOneByOneWidth()
+    {
+    return iDrawOnebyOneW;
+    }
+
+void CDrawOneByOne::SetDrawOneByOneWidth(float aValue)
+    {
+    iDrawOnebyOneW = aValue;
+    }
+
+float CDrawOneByOne::GetDrawOneByOneHeight()
+    {
+    return iDrawOnebyOneH;
+    }
+
+void CDrawOneByOne::SetDrawOneByOneHeight(float aValue)
+    {
+    iDrawOnebyOneH = aValue;
+    }
+
+TBool CDrawOneByOne::IsMagGlassOn()
+    {
+    return iMagGlassOn;
+    }
+
+void CDrawOneByOne::SetMagGlassStatus(TBool aValue)
+    {
+    iMagGlassOn = aValue;
+    iMagGlass->InitDrawMagGlass();
+    }
+
+TBool CDrawOneByOne::IsMagGlassPrevStateOn()
+    {
+    return iMagGlassOnPrev;
+    }
+
+void CDrawOneByOne::SetMagGlassPrevStatus(TBool aValue)
+    {
+    iMagGlassOnPrev = aValue;
+    }
+
+CDrawMagGlass* CDrawOneByOne::GetMagGlass()
+    {
+    return iMagGlass;
+    }
+
+void CDrawOneByOne::KeyPressed()
+    {
+    iMenuAlpha = 1;
+    }
+
+void CDrawOneByOne::KeyReleased()
+    {
+    iMenuAlpha = 0.99;
+    }
+
+void CDrawOneByOne::KeyEvent()
+    {
+    //iMenuAlpha = 1;
+    }
+
+/*----------------------------------------------------------------------*/
+// Initializes one by one view
+//
+void CDrawOneByOne::InitDrawOnebyOne(TReal aDrawZoom, TReal aInPictureX, TReal aInPictureY)
+    {
+    DP0_IMAGIC(_L("CDrawOneByOne::InitDrawOnebyOne"));
+    
+    //iDrawOneByOneXY.iX = 0;
+    //iDrawOneByOneXY.iY = 0;
+    iDrawOneByOneXY.iX = aInPictureX;
+    iDrawOneByOneXY.iY = aInPictureY;
+    iDrawOneByOneTargetXY.iX = 0;
+    iDrawOneByOneTargetXY.iY = 0;
+    
+    //iDrawOneByOneZoom = 0.1;
+    //if(aDrawZoom == 1)
+        iDrawOneByOneZoom = aDrawZoom;
+    /*else
+        iDrawOneByOneZoom = 0.4;*/
+    
+    iDrawOneByOneTargetZoom = 1;
+    TSize size = iContainer->Size();
+    iContainer->CalculateImageSize(iDrawOnebyOneW, iDrawOnebyOneH, (float)size.iWidth/(float)size.iHeight);
+    
+    iZoomingStep = 0.1 * iDrawOneByOneTargetZoom;
+    iZoomingSpeed = 0.2; // unno 2.5*iTimeDiff;
+    iScalingSpeed = 0.3;
+    iOneByOneFlow = 0;
+    iMagGlassOn = EFalse;
+    iMagGlassOnPrev = EFalse;
+#ifdef HOLD_SELECTION_ONDRAG
+    iContainer->iOneByOneSlideByDrag = EFalse;
+#endif
+    
+    iBorder = 0.03;
+    iScreenW = 0;
+    iScreenH = 0;
+    iInPictureX = 0;
+    iInPictureY = 0;
+    
+    //iContainer->iDrawFunction = CImagicContainerBrowser::EOneByOne;
+    iContainer->SetDrawMode(CImagicContainerBrowser::EOneByOne);
+    iContainer->iKeyPressedDown=EFalse;
+    //iContainer->iZoomInKey=EFalse;
+    //iContainer->iZoomOutKey=EFalse;
+    
+    
+    iMagGlass->InitDrawMagGlass();
+    
+    }
+/*----------------------------------------------------------------------*/
+//Draws one by one view
+// 
+void CDrawOneByOne::DrawOnebyOneL(const TSize &aSize)
+    {
+    DP0_IMAGIC(_L("CDrawOneByOne::DrawOnebyOne"));
+    //RDebug::Print(_L("CDrawOneByOne::DrawOnebyOne"));
+    
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    // Calculate screen size
+    iContainer->CalculateImageSize(iImageWidth, iImageHeight, (float)aSize.iWidth/(float)aSize.iHeight);
+    
+    //Interpolate current screen size into the new one
+    //if(iContainer->iLastEventFromKeys)
+        {
+        iContainer->Interpolate(iDrawOnebyOneW, iImageWidth, 0.55);
+        iContainer->Interpolate(iDrawOnebyOneH, iImageHeight, 0.55);
+        }
+    /*else//faster interpolation for touch bcos slide speed is also faster
+        {
+        iContainer->Interpolate(iDrawOnebyOneW, iImageWidth, 0.85);
+        iContainer->Interpolate(iDrawOnebyOneH, iImageHeight, 0.85);  
+        }*/
+    //iContainer->Interpolate(iDrawOnebyOneW, iImageWidth, 0.55);
+    //iContainer->Interpolate(iDrawOnebyOneH, iImageHeight, 0.55);
+    
+    
+    //Use orthogonal projection in OneByOne mode
+    glLoadIdentity();
+    glOrthof(-iDrawOnebyOneW, iDrawOnebyOneW, -iDrawOnebyOneH, iDrawOnebyOneH, -1,1);
+    
+    //iContainer->Interpolate(iContainer->iDisplayRotation, iContainer->iDisplayRotationTarget, 0.2);
+    float tmp = iContainer->GetDisplayRotAngle();
+    iContainer->Interpolate(tmp, iContainer->GetDisplayRotTargetAngle(), 0.2);
+    iContainer->SetDisplayRotAngle(tmp);
+    glRotatef(iContainer->GetDisplayRotAngle(), 0,0,1);
+        
+    // Handle keys----------------------->
+    HandleMovingKeysOnebyOne();
+    
+    // Calculate picture size
+    iContainer->CalculateImageSize(iImageWidth, iImageHeight, imageData->GetAspectRatio());
+    
+    //Here we check that we do not go over the picture boundaries
+    CheckImageLocation();
+    
+    
+    //Move in picture------------------------>
+    iDrawOneByOneTargetXY.iX = iInPictureX / iDrawOneByOneTargetZoom;
+    iDrawOneByOneTargetXY.iY = iInPictureY / iDrawOneByOneTargetZoom;
+
+    //iMovingStep = 0.01/(iDrawOneByOneZoom/8);
+    
+    iContainer->Interpolate(iDrawOneByOneXY.iX,iDrawOneByOneTargetXY.iX, iMovingSpeed);
+    iContainer->Interpolate(iDrawOneByOneXY.iY,iDrawOneByOneTargetXY.iY, iMovingSpeed);
+    
+    // Zooming-------------------------------->
+    if(iContainer->iKeyPressedDown)
+        {
+        if(iContainer->GetKeyData().iZoomInKey)
+            iDrawOneByOneTargetZoom += iZoomingStep*2;//zoom in
+        else if(iContainer->GetKeyData().iZoomOutKey)
+            iDrawOneByOneTargetZoom -= iZoomingStep*4;//zoom out
+        }
+    
+    
+    //Limit zooming range
+    iContainer->CheckLimits(iDrawOneByOneTargetZoom, CImagicContainerBrowser::KMinOneByOneZoom, CImagicContainerBrowser::KMaxOneByOneZoom);
+    
+    // Interpolate to new zoom value
+    if(iDrawOneByOneZoom < 0.99)
+        iContainer->Interpolate(iDrawOneByOneZoom, iDrawOneByOneTargetZoom, iScalingSpeed);
+    else
+        iContainer->Interpolate(iDrawOneByOneZoom, iDrawOneByOneTargetZoom, iZoomingSpeed);
+    
+    // Rotation
+    iContainer->HandleRotationKeys();
+    iContainer->HandleRotation(imageData->iGridData.iRotationAngle, imageData->iGridData.iTargetRotationAngle);
+    
+    
+    //Load image ----------------------------------->
+    // Load high res picture if possible
+    //if(iOneByOneFlow < IS_ALMOST_ZERO)//when not zero, images are moving
+    if(iOneByOneFlow == 0)//when not zero, images are moving in oneByOne flow
+        {
+        iContainer->LoadHighResImage(imageData, iContainer->GetCurrentIndex());
+        }
+        
+    
+    //Bind and Draw ------------------------------------->
+    //Bind to Grid low res texture index. If high res is not available, so we have always some picture to bind and draw it
+    // Determine image indexes, -1 means no image
+    TInt imageIndexes[3]={-1,iContainer->GetCurrentIndex(),-1};
+    
+    //Do not draw other images when not sliding and we are in zoomed into picture
+    //if(iOneByOneFlow != 0)//when not zero, images are moving    
+    //if(!iMagGlassOn || IS_NOT_IN_ZOOM_ONEBYONE)
+        {
+        if (iContainer->GetCurrentIndex()>0)
+            imageIndexes[0]=iContainer->GetCurrentIndex()-1;
+        if (iContainer->GetCurrentIndex() < iContainer->iIEngine->GetTotalNumOfImages()-1)
+            imageIndexes[2]=iContainer->GetCurrentIndex()+1;
+        }
+    
+    //Fade side images when flow goes 70% of image width
+    if(Abs(iOneByOneFlow) > 0.25)
+        {
+        iFadeColor=1;
+        glColor4f(iFadeColor,iFadeColor,iFadeColor, 1);
+        }
+    if(iOneByOneFlow < 0.5)
+        {
+        //if(iContainer->iLastEventFromKeys)
+            iContainer->Interpolate(iFadeColor, 0, 0.25);
+        /*else
+            iContainer->Interpolate(iFadeColor, 0, 0.35);*/
+        
+        glColor4f(iFadeColor,iFadeColor,iFadeColor, 1);
+        }
+    
+    /*if(iFadeColor == 0)
+        {
+        // Determine image indexes, -1 means no image
+        TInt imageIndexes[3]={-1,iContainer->GetCurrentIndex(),-1};
+        }*/
+    
+    //Move to zero coordinate, which is selected image coordinate
+#ifdef HOLD_SELECTION_ONDRAG
+    //Stop interpolation when user is dragging
+    if(iContainer->iHoldSelection == EFalse)
+        {
+#endif
+        if(iContainer->iLastEventFromKeys)
+            iContainer->Interpolate(iOneByOneFlow, 0, KOneByOneSlideSpeed);//sliding speed
+        else
+            iContainer->Interpolate(iOneByOneFlow, 0, KOneByOneSlideSpeed*1.3);//sliding speed
+        }
+    
+    //glColor4f(1,1,1, 1);
+    glPushMatrix();
+    glScalef(iDrawOneByOneZoom, iDrawOneByOneZoom, iDrawOneByOneZoom);
+    //Move to first image location (= current-1)
+    glTranslatef(iOneByOneFlow-iContainer->KOneByOneSpacing,0,0);
+    
+    TInt currentIndexTexture=0;
+    for(TInt i=0; i<3; i++)
+        {
+        // Check that image index is valid
+        if (imageIndexes[i]!=-1)
+            {
+            //Bind to best picture
+            CImageData* data=iContainer->iIEngine->GetImageData(imageIndexes[i]);
+            if(i==1)
+                {
+                iContainer->iCurrentBindedIndex = data->iGridData.BestImage();
+                //Bind to 512 res image when not zoomed for better image scaling quality
+                if(IS_NOT_IN_ZOOM_ONEBYONE && data->iGridData.iGlHQ512TextIndex!=0 && !iMagGlassOn) 
+                    iContainer->iCurrentBindedIndex = data->iGridData.iGlHQ512TextIndex;
+                }
+            //Side images gets only 128x128 tn because of perf reason
+            else
+                iContainer->iCurrentBindedIndex = data->iGridData.iGlLQ128TextIndex;
+            if(!iContainer->iCurrentBindedIndex)
+                iContainer->iCurrentBindedIndex = data->iGridData.iGlLQ32TextIndex;
+            
+            
+            //If no images ready, bind with loading tn
+            if (iContainer->iCurrentBindedIndex == 0)
+                iContainer->iCurrentBindedIndex = iContainer->iLoadingTextureIndex;
+            
+            glBindTexture(GL_TEXTURE_2D, iContainer->iCurrentBindedIndex);
+            
+            if(i==1){
+                currentIndexTexture=iContainer->iCurrentBindedIndex;
+            }
+            iContainer->SetMinMagFilterLinearDo(iContainer->iMinMagFilterSetting);
+            
+            //Store matrix and rotate picture
+            glPushMatrix();
+               
+            if(i==1 && iMagGlassOn)
+                {
+                glColor4f(1,1,1, 1);
+                glTranslatef(iDrawOneByOneXY.iX, -iDrawOneByOneXY.iY, 0);
+                glRotatef(data->iGridData.iRotationAngle, 0,0,1);
+                iMagGlass->DrawMagGlass(aSize, data->GetAspectRatio());
+                }
+            else
+                {
+                //Set Draw color to white when drawing selection or if we drag images 
+                if(i==1 || (iContainer->iHoldSelection && !iMagGlassOn))
+                    glColor4f(1,1,1, 1);
+                else//othervise "fade" images
+                    glColor4f(iFadeColor,iFadeColor,iFadeColor, 1);
+                
+                glTranslatef(-iDrawOneByOneXY.iX, iDrawOneByOneXY.iY, 0);
+                glRotatef(data->iGridData.iRotationAngle, 0,0,1);
+                // Set vertixes and draw
+                GLfixed vertices[8];
+                iContainer->SetPictureVertices(data, vertices);
+                glVertexPointer( 2, GL_FIXED, 0, vertices );
+                glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+#ifdef EMPTY_IMAGE_AS_WIREFRAME
+                // Draw black frame with white borders
+                if (iContainer->iCurrentBindedIndex == 0)
+                    {
+                    glScalef(0.92, 0.92, 0.92);
+                    glColor4f(0,0,0,1);
+                    glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+                    }
+#endif                
+                
+                }
+
+#ifdef RD_FACEFRAME
+            //if (i==1 && iDrawFaceFrame) DrawFaceFrame();
+#endif
+            
+            //Remove rotation
+            glPopMatrix();
+            }
+        // Move to next image position
+        glTranslatef(iContainer->KOneByOneSpacing,0,0);
+        }
+    glPopMatrix();
+
+    if(currentIndexTexture!=iContainer->iCurrentBindedIndex)
+        {
+        iContainer->iCurrentBindedIndex = currentIndexTexture;
+        glBindTexture(GL_TEXTURE_2D, iContainer->iCurrentBindedIndex);
+        iContainer->SetMinMagFilterLinearDo(iContainer->iMinMagFilterSetting);
+        }
+
+#ifdef SCR_DRAW_DEBUG
+    iDrawUtility->Update();
+    iDrawUtility->Draw(Size());
+#endif
+    
+    
+    
+    //iContainer->iDrawUtility->DrawMenuIndicators(iContainer->Size());
+    
+    
+#ifdef RD_ZOOMICON
+    //Draw moving direction arrays when sliding in OnByOne mode
+    if(!iMagGlassOn && iFadeColor!=0 || iOneByOneFlow != 0)
+        iContainer->iDrawUtility->DrawMovingArrow(ETrue, EFalse, iContainer->Size());
+    
+    //Draw moving direction arrays when zoomed in
+    if (!IS_NOT_IN_ZOOM_ONEBYONE && 
+        (iDrawOneByOneXY.iX != iDrawOneByOneTargetXY.iX || 
+         iDrawOneByOneXY.iY != iDrawOneByOneTargetXY.iY || 
+         iDrawOneByOneZoom != iDrawOneByOneTargetZoom ||
+         imageData->iGridData.iRotationAngle != imageData->iGridData.iTargetRotationAngle ||
+         iContainer->iOnTheEdge))
+        {
+        /*if(!iMagGlassOn)
+            {
+            iContainer->iDrawUtility->DrawMovingArrow(ETrue, !IS_NOT_IN_ZOOM_ONEBYONE, iContainer->Size());
+            }*/
+        
+        iContainer->iDrawUtility->DrawZoomIcon( imageData,
+                                                iContainer->Size(), 
+                                                -iDrawOneByOneXY.iX, 
+                                                iDrawOneByOneXY.iY,
+                                                iDrawOnebyOneW/iImageWidth, 
+                                                iDrawOnebyOneH/iImageHeight,
+                                                ETrue);
+        }
+#endif    
+
+#if 0
+    if(iMenuAlpha < 1)
+        {
+        iMenuAlpha-=0.3;
+        if(iMenuAlpha < 0)
+            iMenuAlpha = 0;
+        }
+
+    iContainer->iDrawUtility->DrawIcon2(iContainer->Size(), iContainer->iMenuTextureIndex, iMenuAlpha);
+#endif   
+    iContainer->DynamicLoadingL();
+    }
+
+
+TBool CDrawOneByOne::IsDrawingNeededOneByOne()
+    {
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+#if 0
+    if(iMenuAlpha != 0)
+        {
+        return ETrue;
+        }
+#endif
+    
+    if(Abs(iOneByOneFlow) > 0.01)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 2"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(iOneByOneFlow!=0)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 3"));
+        iOneByOneFlow=0;
+        //if(imageData->iGridData.iGlHQ512TextIndex != 0)
+        //iContainer->iDrawOneMoreTime = ETrue;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+    
+    if(iMagGlassOnPrev != iMagGlassOn)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 4"));
+        iMagGlassOnPrev = iMagGlassOn;
+        //SetMinMagFilterLinear(ETrue);
+        //iContainer->iDrawOneMoreTime = ETrue;
+        return ETrue;
+        }
+    
+    if(iMagGlassOn && (iMagGlass->GetMagGlassZoomFactor() < KMaxMagGlassZoomFactor-0.1))
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 5"));
+        DP1_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - magGlass: %f"), iMagGlass->GetMagGlassZoomFactor());
+        iMagGlassOnPrev = iMagGlassOn;
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+        
+    if(Abs(iContainer->GetDisplayRotAngle() - iContainer->GetDisplayRotTargetAngle()) > 1)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 6"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(iContainer->GetDisplayRotAngle() != iContainer->GetDisplayRotTargetAngle())
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 6.1"));
+        iContainer->SetDisplayRotAngle(iContainer->GetDisplayRotTargetAngle());
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+    
+    if(Abs(imageData->iGridData.iRotationAngle - imageData->iGridData.iTargetRotationAngle) > 1)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 7"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(imageData->iGridData.iRotationAngle != imageData->iGridData.iTargetRotationAngle)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 7.1"));
+        imageData->iGridData.iRotationAngle = imageData->iGridData.iTargetRotationAngle;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+    
+    if(Abs(iDrawOneByOneZoom - iDrawOneByOneTargetZoom) > 0.01)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 9"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(iDrawOneByOneZoom != iDrawOneByOneTargetZoom)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 9.1"));
+        iDrawOneByOneZoom = iDrawOneByOneTargetZoom;
+        //iContainer->iDrawOneMoreTime = ETrue;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+
+    if(Abs(iDrawOneByOneXY.iX-iDrawOneByOneTargetXY.iX) > 0.001)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 11"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(iDrawOneByOneXY.iX != iDrawOneByOneTargetXY.iX)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 11.1"));
+        iDrawOneByOneXY.iX = iDrawOneByOneTargetXY.iX;
+        //iContainer->iDrawOneMoreTime = ETrue;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+    
+    if(Abs(iDrawOneByOneXY.iY-iDrawOneByOneTargetXY.iY) > 0.001)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 12"));
+        iContainer->SetMinMagFilterLinear(EFalse);
+        return ETrue;
+        }
+    else if(iDrawOneByOneXY.iY != iDrawOneByOneTargetXY.iY)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 12.1"));
+        iDrawOneByOneXY.iY = iDrawOneByOneTargetXY.iY;
+        //iContainer->iDrawOneMoreTime = ETrue;
+        iContainer->SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }
+    
+    /*if(iPreviousTexNum != iCurrentTexNum && !iDrawOneMoreTime)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 13.0"));
+        //iDrawOneMoreTime = ETrue;
+        SetMinMagFilterLinear(ETrue);
+        return ETrue;
+        }*/
+    
+    /*if(imageData->GetAspectRatio() > iScreenAspectRatio && (iDrawOneByOneZoom-1) < 0.01)
+        if(Abs(iDrawOnebyOneW-iImageWidth*2) > 0.01)
+            {
+            DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 13.1"));
+            DP2_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - iDrawOnebyOneW: %f, iImageWidth: %f"),iDrawOnebyOneW, iImageWidth);
+            SetMinMagFilterLinear(EFalse);
+            //iDrawOneMoreTime = ETrue;
+            return ETrue;
+            }
+        else if(iDrawOnebyOneW != iImageWidth*2)
+            {
+            DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 13.2"));
+            DP2_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - iDrawOnebyOneW: %f, iImageWidth: %f"),iDrawOnebyOneW, iImageWidth);
+            iDrawOnebyOneW = iImageWidth*2;
+            iDrawOneMoreTime = ETrue;
+            SetMinMagFilterLinear(ETrue);
+            return ETrue;
+            }*/
+    
+    /*
+    if(imageData->GetAspectRatio() < iContainer->iScreenAspectRatio && (iDrawOneByOneZoom-1) < 0.01)
+        if(Abs(iDrawOnebyOneH-iImageHeight) > 0.01)
+            {
+            DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 13.3"));
+            DP2_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - iDrawOnebyOneH: %f, iImageHeight: %f"),iDrawOnebyOneH, iImageHeight);
+            iContainer->SetMinMagFilterLinear(EFalse);
+            //iDrawOneMoreTime = ETrue;
+            return ETrue;
+            }
+        else if(Abs(iDrawOnebyOneH - iImageHeight) > IS_ALMOST_ZERO)
+            {
+            DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 13.4"));
+            DP2_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - iDrawOnebyOneH: %f, iImageHeight: %f"),iDrawOnebyOneH, iImageHeight);
+            iDrawOnebyOneH = iImageHeight;
+            //iContainer->iDrawOneMoreTime = ETrue;
+            iContainer->SetMinMagFilterLinear(ETrue);
+            return ETrue;
+            }
+    */
+    
+    /*if(iContainer->iDrawOneMoreTime)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 14"));
+        iContainer->iDrawOneMoreTime = EFalse;
+        iContainer->SetMinMagFilterLinear(ETrue);//Draw one more time to change for Linear rendering mode
+        return ETrue;
+        }*/
+    
+    if(!iContainer->iMagFilterLinear)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 15"));
+        iContainer->SetMinMagFilterLinear(ETrue);
+        //iContainer->iDrawOneMoreTime = ETrue;
+        }
+        
+    if(Abs(iOneByOneFlow) < 0.7)
+        if(iFadeColor > 0.1)
+            {
+            DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 16"));
+            iContainer->SetMinMagFilterLinear(EFalse);
+            return ETrue;
+            }
+        else if(iFadeColor!=0)
+            {
+            DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 17"));
+            iFadeColor = 0;
+            iContainer->SetMinMagFilterLinear(ETrue);
+            return ETrue;
+            }
+
+    if(iContainer->iDrawNow)
+        {
+        DP0_IMAGIC(_L("CDrawOneByOne::IsDrawingNeededOneByOne - 1"));
+        if(iMagGlassOn)
+            {
+            if(!iContainer->IsTouchPointThresholdExeed())//moved >2 pixel
+                iContainer->SetMinMagFilterLinear(ETrue);
+            else
+                iContainer->SetMinMagFilterLinear(EFalse);
+            }
+        else
+            {
+            iContainer->SetMinMagFilterLinear(ETrue);
+            }
+        
+        iContainer->iDrawNow = EFalse;
+        return ETrue;
+        }
+    
+    return EFalse;
+    }
+
+//Here we check that we do not go over the picture boundaries
+void CDrawOneByOne::CheckImageLocation(/*float& aImageWidth, float& aImageHeight*/)
+    {
+    
+    CImageData* imageData = iContainer->iIEngine->GetImageData(iContainer->GetCurrentIndex());
+    
+    // Change landscape<->portrait if pic is rotated 90 or 270
+    TInt angle = imageData->iGridData.iTargetRotationAngle;
+    if(angle % 90 == 0 && angle % 180 != 0)
+        {
+        if(imageData->GetAspectRatio() > 1)
+            {
+            /*iImageWidth /= imageData->GetAspectRatio();
+            iImageWidth -= (iImageWidth-iDrawOnebyOneW);*/
+            iImageHeight *= imageData->GetAspectRatio();
+            iImageHeight -= (iImageHeight-iDrawOnebyOneH);
+            iImageWidth = iImageHeight / imageData->GetAspectRatio();
+            
+            }
+        else
+            {
+            /*iImageWidth/= imageData->GetAspectRatio();
+            iImageWidth-= (iImageWidth-iDrawOnebyOneW);*/
+            iImageHeight *= imageData->GetAspectRatio();
+            iImageHeight -= (iImageHeight-iDrawOnebyOneH);
+            iImageWidth = iImageHeight / imageData->GetAspectRatio();
+            }
+        }
+    
+    
+    iImageWidth *= iDrawOneByOneTargetZoom;
+    iImageHeight *= iDrawOneByOneTargetZoom;
+    
+    //Calculate location/coordinates in screen
+    iInPictureX = iDrawOneByOneTargetXY.iX * iDrawOneByOneTargetZoom; 
+    iInPictureY = iDrawOneByOneTargetXY.iY * iDrawOneByOneTargetZoom;
+        
+    //Lets move in picture little bit over the border
+    if(iDrawOneByOneTargetZoom==1)
+        {
+        iBorder=0;
+        iDrawOneByOneTargetXY.iX = 0;
+        iDrawOneByOneTargetXY.iY = 0;
+        }
+    else
+		{
+        iBorder=0.015; // was 0.1. Changed to 0 to limit just at the edge of image in zoom
+		}
+    
+    //Calculate screen size
+    iScreenW = iDrawOnebyOneW - iBorder;
+    iScreenH = iDrawOnebyOneH - iBorder;
+        
+        
+    if (iImageWidth > iScreenW)
+        {
+        if (iInPictureX-iScreenW < -iImageWidth)
+            iInPictureX=-iImageWidth+iScreenW;
+        if (iInPictureX+iScreenW > iImageWidth)
+            iInPictureX=iImageWidth-iScreenW;
+        }
+    else
+        {
+        iInPictureX=0;
+        }
+    if (iImageHeight > iScreenH)
+        {
+        if (iInPictureY-iScreenH < -iImageHeight)
+            iInPictureY=-iImageHeight+iScreenH;
+        if (iInPictureY+iScreenH > iImageHeight)
+            iInPictureY=iImageHeight-iScreenH;
+        }
+    else
+        {
+        iInPictureY=0;
+        }
+    
+    if(IS_NOT_IN_ZOOM_ONEBYONE)
+        {
+        iInPictureY=0;
+        iInPictureX=0;
+        }
+    }
+
+void CDrawOneByOne::HandleMovingKeysOnebyOne()
+    {
+    // Handle keys----------------------->
+    CKeyData keyData = iContainer->GetKeyData();
+    CKeyData touchData = iContainer->GetTouchData();
+    iFlowThresHold=0.8;
+    
+    //Handle keydata and touchdata
+    ChangeDrawOneByOneTargetX(keyData.iRight * GetMovingStep());
+    ChangeDrawOneByOneTargetX(-keyData.iLeft * GetMovingStep());
+    ChangeDrawOneByOneTargetY(keyData.iDown * GetMovingStep());
+    ChangeDrawOneByOneTargetY(-keyData.iUp * GetMovingStep());
+    
+    ChangeDrawOneByOneTargetX(touchData.iRight * GetMovingStep());
+    ChangeDrawOneByOneTargetX(-touchData.iLeft * GetMovingStep());
+    ChangeDrawOneByOneTargetY(touchData.iDown * GetMovingStep());
+    ChangeDrawOneByOneTargetY(-touchData.iUp * GetMovingStep());
+    
+    if(touchData.iRight || touchData.iLeft || touchData.iDown || touchData.iUp)
+        //iMovingSpeed = 2.2;
+        iMovingSpeed = 100;
+    else
+        iMovingSpeed = 0.15;
+        //iMovingSpeed = 0.01;
+        
+    //Calculate new index from movement keys to change picture in onebyone mode
+    //but only if zooming is not done
+    //And we have started sliding/moving
+#ifdef HOLD_SELECTION_ONDRAG
+    if(GetDrawOneByOneTargetZoom()==1 && 
+       //((Abs(GetImgeFlowLocation())<0.99) || 
+       ((Abs(GetImgeFlowLocation())<iFlowThresHold) ||
+       iContainer->GetSlideByDragValue()) &&
+       !IsMagGlassOn())
+       
+#else
+    if(iDrawOneByOneTargetZoom==1 && Abs(iOneByOneFlow)<0.2 && !iMagGlassOn)
+#endif
+        {
+        iContainer->SetCurrentIndex(iContainer->GetCurrentIndex() + keyData.iY);
+        iContainer->SetCurrentIndex(iContainer->GetCurrentIndex() + keyData.iX);
+        
+        iContainer->SetCurrentIndex(iContainer->GetCurrentIndex() + touchData.iY);
+        iContainer->SetCurrentIndex(iContainer->GetCurrentIndex() + touchData.iX);
+        }
+    
+    // Check that index is in grid area
+    while(iContainer->GetCurrentIndex() >= iContainer->iIEngine->GetTotalNumOfImages())
+        iContainer->SetCurrentIndex(iContainer->GetCurrentIndex() - iContainer->iIEngine->GetTotalNumOfImages());
+    while(iContainer->GetCurrentIndex() < 0)
+        iContainer->SetCurrentIndex(iContainer->GetCurrentIndex() + iContainer->iIEngine->GetTotalNumOfImages());
+    
+    // Update selected picture index
+    if(iContainer->GetPrevIndex() != iContainer->GetCurrentIndex())
+        {
+        //iContainer->iTextureLoader->ReleaseHQ512Textures();
+        
+        //iMagGlassOn = EFalse;
+        SetMagGlassStatus(EFalse);
+        
+        iContainer->iImagicAppUi->SetImageIndex(iContainer->GetCurrentIndex());
+        
+        // Set new flow coordinate
+        if (keyData.iLeft || touchData.iLeft)
+            {
+            float tmp = GetImgeFlowLocation();
+            tmp-=CImagicContainerBrowser::KOneByOneSpacing;
+            SetImgeFlowLocation(tmp);
+            //iOneByOneFlow-=KOneByOneSpacing;
+            }
+        if (keyData.iRight || touchData.iRight)
+            {
+            float tmp = GetImgeFlowLocation();
+            tmp+=CImagicContainerBrowser::KOneByOneSpacing;
+            SetImgeFlowLocation(tmp);
+            //iOneByOneFlow+=KOneByOneSpacing;
+            }
+        
+        //Cancel SuperZoom image loading, if it was started
+        iContainer->iIEngine->CancelFullSizeLoading();
+        }
+    iContainer->SetPrevIndex(iContainer->GetCurrentIndex());
+    
+    iContainer->ResetKeyData();
+    iContainer->ResetTouchData();
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/DrawUtility.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,831 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "DrawUtility.h"
+#include "debug.h"
+
+const KTNSize = 10;
+
+/*--------------------------------------------------------------------------*/
+// Class constants
+
+// Mesh data
+
+// Triangle count
+const int CDrawUtility::iTriCount = 4;
+
+// Vertices
+const GLfixed CDrawUtility::iVertices[4*3]=
+	{
+	// Tetrahedron coordinates
+	10*(1<<16),		10*(1<<16),		10*(1<<16),
+	-10*(1<<16),	-10*(1<<16),	10*(1<<16),
+	-10*(1<<16),	10*(1<<16),		-10*(1<<16),
+	10*(1<<16),		-10*(1<<16),	-10*(1<<16),
+	};
+
+// Normals
+const GLfixed CDrawUtility::iNormals[4*3]=
+	{
+	// Tetrahedron normals
+	/*
+	Normal is a vector with unit lenght (length=1)
+	Unit lenght vector = vector/lenght
+	
+	Calculate normals from corners, makes gouraud shading
+	Vector: (1,1,1)
+	Lenght = SQRT( 1*1 + 1*1 + 1*1 ) = SQRT(3) = 1.732050808
+	1/Lenght = 0.577350269
+	In fixed point: 0.577350269*(1<<16) = 37837
+	*/
+	37837,	37837,	37837,
+	-37837,	-37837,	37837,
+	-37837,	37837,	-37837,
+	37837,	-37837,	-37837,
+	};
+
+// Indexes define which vertices make a triangle
+// These are just indexes to iVertices table
+const GLushort CDrawUtility::iIndices[4*3]=
+	{
+	0,2,3,
+	0,1,3,
+	0,1,2,
+	2,1,3,
+	};
+
+/*--------------------------------------------------------------------------*/
+// NewL
+//
+//CDrawableInterface* CDrawUtility::NewL(void)
+CDrawUtility* CDrawUtility::NewL(CImagicContainerBrowser* aContainer)
+	{
+	// Create object
+	CDrawUtility* self = new(ELeave) CDrawUtility();
+	
+	// Call 2nd stage constructor
+	CleanupStack::PushL(self);
+	self->ConstructL(aContainer);
+	CleanupStack::Pop(self);
+	
+	return self;
+	}
+
+/*--------------------------------------------------------------------------*/
+// Constructor
+//
+CDrawUtility::CDrawUtility() :
+		//CDrawableInterface(),
+		iAngleX(0),
+		iAngleY(0),
+		iAngleZ(0)
+	{
+	// Nothing here
+	}
+
+/*--------------------------------------------------------------------------*/
+// Second stage constructor
+//
+void CDrawUtility::ConstructL(CImagicContainerBrowser* aContainer)
+	{
+	iContainer = aContainer;
+	iRotation = 0;
+	iRotationTarget = 0;
+	
+	float ambient[4]={0.3,0.3,0.3, 1};
+	float diffuse[4]={1, 1, 1, 1};
+    glLightfv(GL_LIGHT0,GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0,GL_DIFFUSE, diffuse);
+	}
+
+/*--------------------------------------------------------------------------*/
+// Destructor
+//
+CDrawUtility::~CDrawUtility()
+	{
+	// Nothing here
+	}
+
+/*--------------------------------------------------------------------------*/
+// Makes sure that angle is on valid range
+//
+void CDrawUtility::LimitAngle(TInt &Angle)
+	{
+	while (Angle<0)
+		Angle+=360;
+	while (Angle>360)
+		Angle-=360;
+	}
+
+/*--------------------------------------------------------------------------*/
+// Update animation
+// Returns true if screen should be redrawn
+//
+TBool CDrawUtility::Update(void)
+	{
+	// Rotate
+	iAngleX+=4;
+	iAngleY+=2;
+	iAngleZ-=2;
+	
+	// Check limist
+	LimitAngle(iAngleX);
+	LimitAngle(iAngleY);
+	LimitAngle(iAngleZ);
+	
+	// Since this is loading animation, this doesn't want screen to be updated
+	return EFalse;
+	}
+
+
+
+/*--------------------------------------------------------------------------*/
+// Draws Zoom image thumbnail
+//
+void CDrawUtility::DrawZoomIcon(    const CImageData* aImageData,
+                                    const TSize aScreenSize, 
+                                    float aDrawOneByOneX, 
+                                    float aDrawOneByOneY,
+                                    TReal aDrawOnebyOneW, 
+                                    TReal aDrawOnebyOneH,
+                                    TBool aShowLocationRect)
+    {
+    
+    iScrAspectratio = (TReal)aScreenSize.iWidth/(TReal)aScreenSize.iHeight;
+    
+    if(aImageData->iGridData.iGlLQ128TextIndex != 0)
+        {
+        iDrawOneByOneX = aDrawOneByOneX; 
+        iDrawOneByOneY = aDrawOneByOneY;
+        iDrawOnebyOneW = aDrawOnebyOneW; 
+        iDrawOnebyOneH = aDrawOnebyOneH;
+                                            
+        iAspectRatio = aImageData->GetAspectRatio();
+        iScrSize = aScreenSize;
+        
+        //Define thumbnail size dependinf on screen orientation
+        if(iAspectRatio > 1)
+            {
+            iThumbSize.iWidth=(iScrSize.iWidth/KTNSize);
+            iThumbSize.iHeight=iThumbSize.iWidth/iAspectRatio;
+            iZoomRectSize.iWidth = iScrSize.iWidth/KTNSize;
+            iZoomRectSize.iHeight = iZoomRectSize.iWidth/iScrAspectratio;
+            }
+        else
+            {
+            iThumbSize.iWidth=(iScrSize.iHeight/KTNSize);
+            iThumbSize.iHeight=iThumbSize.iWidth/iAspectRatio;
+            iZoomRectSize.iHeight = iScrSize.iHeight/KTNSize;
+            iZoomRectSize.iWidth = iZoomRectSize.iHeight*iScrAspectratio;
+            }
+        
+        GLfixed vertices[8];
+        SetPictureVertices(vertices, iAspectRatio);
+        
+        glColor4f(1,1,1, 1);
+        
+        // Set OpenGL state
+        glDepthMask(GL_FALSE);
+        glDisable(GL_DEPTH_TEST);
+        glEnable(GL_TEXTURE_2D);
+        glVertexPointer( 2, GL_FIXED, 0, vertices );
+
+        glPushMatrix();
+        
+        // Set ortho to match screen size
+        glLoadIdentity();
+        glOrthof(0,aScreenSize.iWidth, aScreenSize.iHeight,0, -50,50);
+        
+        //Move to top right corner and leave some space around "frame"
+        if(iContainer->GetScreenOrientation())
+            {
+            iRotationTarget = 0 - (TReal)aImageData->GetOrientation();
+            
+            if(iAspectRatio > 1 && iRotationTarget == 0)
+                glTranslatef(iThumbSize.iWidth+4, iScrSize.iHeight-iThumbSize.iHeight-4, 1);
+            else if(iAspectRatio < 1 && iRotationTarget == 0)
+                glTranslatef((iThumbSize.iWidth)*iAspectRatio+4, iScrSize.iHeight-iThumbSize.iWidth-4, 1);
+            else// if(iAspectRatio < 1 && iRotationTarget == 0)
+                glTranslatef((iThumbSize.iHeight)+4, iScrSize.iHeight-iThumbSize.iWidth-4, 1);
+            }
+        else
+            {
+            iRotationTarget = -90 - (TReal)aImageData->GetOrientation();
+            
+            if(iAspectRatio > 1 && iRotationTarget == -90)
+                glTranslatef(iScrSize.iWidth-iThumbSize.iHeight-4, iScrSize.iHeight-iThumbSize.iWidth-4, 1);
+            else if(iAspectRatio < 1 && iRotationTarget == -90)
+                glTranslatef(iScrSize.iWidth-(iThumbSize.iHeight*iAspectRatio)-4, iScrSize.iHeight-(iThumbSize.iWidth*iAspectRatio)-4, 1);
+            else// if(iAspectRatio < 1 && iRotationTarget == -90)
+                glTranslatef(iScrSize.iWidth-(iThumbSize.iHeight*iAspectRatio)-4, iScrSize.iHeight-(iThumbSize.iHeight)-4, 1);
+            }
+        
+        iContainer->Interpolate(iRotation, iRotationTarget, 0.60);
+        glRotatef(iRotation, 0,0,1);
+        
+        DrawFrame(0);
+        
+        glBindTexture(GL_TEXTURE_2D, aImageData->iGridData.iGlLQ128TextIndex);
+        glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+                        
+        // Restore OpenGL state
+        glDepthMask(GL_TRUE);
+        glEnable(GL_DEPTH_TEST);
+        glEnable(GL_TEXTURE_2D);
+        
+        //glDisable(GL_BLEND);
+        if(aShowLocationRect)
+            DrawZoomFrame(iRotationTarget);
+        
+        glDisableClientState(GL_VERTEX_ARRAY);
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        glPopMatrix();
+        }
+    }
+
+//Shows rectangle for zoomed are
+void CDrawUtility::DrawZoomFrame(float aRotationTarget)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DrawFaceFrame++"));
+    DP1_IMAGIC(_L("CImagicContainerBrowser::DrawZoomFrame - aRotationTarget: %f"),aRotationTarget);
+    
+    GLfixed vertices[8];
+    glPushMatrix();
+    glDisable(GL_TEXTURE_2D);
+    glTranslatef(0, 0, 0.01f);
+    glColor4f(0,0.7,0,1);
+    glLineWidth(2.0f);
+    glVertexPointer(2, GL_FIXED, 0, vertices);
+    
+	TReal xPos = iDrawOneByOneX*(TReal)iThumbSize.iWidth*2;
+	TReal yPos = iDrawOneByOneY*(TReal)iThumbSize.iHeight*2*iAspectRatio;
+	
+	//float x,y;
+	TInt x,y;
+	TInt rotationTarget = aRotationTarget;
+	rotationTarget%=360;
+	
+	if(rotationTarget == 0)
+	    {
+	    glTranslatef(-xPos, yPos, 0);
+	    if(iAspectRatio > 1)
+	        {
+	        x=iDrawOnebyOneW*iZoomRectSize.iWidth * (1<<16);
+	        y=iDrawOnebyOneW*iZoomRectSize.iHeight * (1<<16);
+	        }
+	    else
+	        {
+	        x=iDrawOnebyOneH*iZoomRectSize.iWidth * (1<<16);
+            y=iDrawOnebyOneH*iZoomRectSize.iHeight * (1<<16);
+	        }
+	        
+	    }
+	else if(rotationTarget == -90)
+        {
+        glTranslatef(-yPos, -xPos, 0);
+        if(iAspectRatio > 1)
+            {
+            y=iDrawOnebyOneH*iScrAspectratio*iZoomRectSize.iWidth * (1<<16);
+            x=iDrawOnebyOneH*iScrAspectratio*iZoomRectSize.iHeight * (1<<16);
+            }
+        else
+            {
+            y=iDrawOnebyOneH*iZoomRectSize.iWidth * (1<<16);
+            x=iDrawOnebyOneH*iZoomRectSize.iHeight * (1<<16);
+            }
+        }
+	else if(rotationTarget == -180)
+        {
+        glTranslatef(xPos, -yPos, 0);
+        if(iAspectRatio > 1)
+            {
+            x=iDrawOnebyOneW*iZoomRectSize.iWidth * (1<<16);
+            y=iDrawOnebyOneW*iZoomRectSize.iHeight * (1<<16);
+            }
+        else
+            {
+            x=iDrawOnebyOneH*iZoomRectSize.iWidth * (1<<16);
+            y=iDrawOnebyOneH*iZoomRectSize.iHeight * (1<<16);
+            }
+        }
+	else if(rotationTarget == -270)
+        {
+        glTranslatef(yPos, xPos, 0);
+        if(iAspectRatio > 1)
+            {
+            y=iDrawOnebyOneH*iScrAspectratio*iZoomRectSize.iWidth * (1<<16);
+            x=iDrawOnebyOneH*iScrAspectratio*iZoomRectSize.iHeight * (1<<16);
+            }
+        else
+            {
+            y=iDrawOnebyOneH*iZoomRectSize.iWidth * (1<<16);
+            x=iDrawOnebyOneH*iZoomRectSize.iHeight * (1<<16);
+            }
+        }
+
+	TInt tnSizeFixedH = iThumbSize.iHeight*(1<<16);
+	TInt tnSizeFixedW = iThumbSize.iWidth*(1<<16);
+	
+	if(y > tnSizeFixedH)
+	    y=tnSizeFixedH;
+	if(x > tnSizeFixedW)
+        x=tnSizeFixedW;
+	
+	vertices[0*2+0] = -x;	vertices[0*2+1] = -y;
+	vertices[1*2+0] =  x;	vertices[1*2+1] = -y;
+	vertices[2*2+0] =  x;	vertices[2*2+1] =  y;
+	vertices[3*2+0] = -x;	vertices[3*2+1] =  y;
+	
+    glDrawArrays(GL_LINE_LOOP,0,4);
+
+    glColor4f(1,1,1,1);
+    glEnable(GL_TEXTURE_2D);
+    glPopMatrix();
+	
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DrawZoomFrame--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Draws background frame
+//
+void CDrawUtility::DrawFrame(TInt aIndex)
+    {
+
+    // Draw frame around selected image
+    glPushMatrix();
+    glDisable(GL_TEXTURE_2D);
+    
+    //Frame size
+    float scale=1.09;
+    glColor4f(1,1,1, 1);
+    
+    glTranslatef(0,0,-0.03);
+    glScalef(scale,scale,scale);
+    glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+    
+    //glDisable(GL_BLEND);
+    glEnable(GL_TEXTURE_2D);
+    glPopMatrix();
+    }
+
+void CDrawUtility::SetPictureVertices(GLfixed* aVertices, TReal aAspectRatio)
+    {
+    //DP0_IMAGIC(_L("CImagicContainerBrowser::SetPictureVertices"));
+    
+    GLfixed vx = (iThumbSize.iWidth)*(1<<16);
+    GLfixed vy = (iThumbSize.iWidth)*(1<<16);
+    
+    
+    if(aAspectRatio > 1)
+        {
+        vy = ((iThumbSize.iWidth)/aAspectRatio)*(1<<16);
+        }
+    else
+        {
+        vx = ((iThumbSize.iWidth)*aAspectRatio)*(1<<16);
+        }
+
+    
+    aVertices[0*2+0] = -vx;
+    aVertices[0*2+1] = vy;
+    
+    aVertices[1*2+0] = vx;
+    aVertices[1*2+1] = vy;
+    
+    aVertices[2*2+0] = -vx;
+    aVertices[2*2+1] = -vy;
+    
+    aVertices[3*2+0] = vx;
+    aVertices[3*2+1] = -vy;
+
+    }
+
+#if 1
+
+/*--------------------------------------------------------------------------*/
+// Draw moving arrow
+//
+void CDrawUtility::DrawMovingArrow(TBool aPrevArrow, TBool aUpDownArrow, const TSize& aScreenSize)
+    {
+    //Define shape of direction array
+    const GLfixed vertices[4*2] = 
+		{
+		0*1<<16,  0*1<<16,
+		10*1<<16, 7*1<<16,
+		7*1<<16,  0*1<<16,
+		10*1<<16,-7*1<<16,
+		};
+    //Define colors of direction array
+    const GLubyte colors[4*4] = 
+		{
+		//61,174,227, 128,
+		/*255,255,255, 255,
+		81,194,247, 255,
+		61,174,227, 255,
+		41,154,207, 255,*/
+        255,255,255, 255,
+        128,128,128, 255,
+        50,50,50, 255,
+        128,128,128, 255,
+		};
+    //And order of drawing
+	const GLushort indices[2*3]=
+		{
+		0,1,2,
+		2,3,0,
+		};
+	
+	TReal scale = 1;
+	if(aScreenSize.iHeight > 320 || aScreenSize.iWidth > 320)
+	    {
+	    scale = 1.5;
+	    }
+	    
+    // Set OpenGL state
+	// Shade model
+    glShadeModel(GL_SMOOTH);
+    glDepthMask(GL_FALSE);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_TEXTURE_2D);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_COLOR_ARRAY);
+    glPushMatrix();
+	
+#ifdef ENABLE_ALPHA
+	// Setup alpha
+	glEnable(GL_ALPHA_TEST);
+	glEnable(GL_BLEND);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#endif	
+    // Set ortho to match screen size
+    glLoadIdentity();
+    glOrthof(0,aScreenSize.iWidth, aScreenSize.iHeight,0, -100,100);
+    glPushMatrix();
+
+    // Move to arrow position
+	int ArrowDistance=5;
+	if(aPrevArrow)
+		{
+		glTranslatef(ArrowDistance,aScreenSize.iHeight/2,0);
+        glVertexPointer(2,GL_FIXED,0, vertices);
+        glColorPointer(4,GL_UNSIGNED_BYTE,0, colors);
+        glScalef(scale,scale,scale);
+        glDrawElements(GL_TRIANGLES, 2*3, GL_UNSIGNED_SHORT, indices);
+        glScalef(1/scale,1/scale,1/scale);
+		glTranslatef(aScreenSize.iWidth-2*ArrowDistance,0/*aScreenSize.iHeight/2*/,0);
+		// Flip arrow around so it points to right
+	    glRotatef(180,0,0,1);
+		// Also flip it on X
+		//glRotatef(180,1,0,0);
+		glVertexPointer(2,GL_FIXED,0, vertices);
+        glColorPointer(4,GL_UNSIGNED_BYTE,0, colors);
+        glScalef(scale,scale,scale);
+        glDrawElements(GL_TRIANGLES, 2*3, GL_UNSIGNED_SHORT, indices);
+        glScalef(1/scale,1/scale,1/scale);
+		
+        glPopMatrix();
+		glPushMatrix();
+	    }
+	
+    if(aUpDownArrow)
+        {
+        glTranslatef(aScreenSize.iWidth/2, ArrowDistance,0);
+        //glTranslatef(aScreenSize.iWidth/2,(aScreenSize.iHeight)-ArrowDistance,0);
+        // Flip arrow around so it points to right
+        glRotatef(90,0,0,1);
+        // Also flip it on X
+        //glRotatef(180,1,0,0);
+        // Draw arrow
+        glVertexPointer(2,GL_FIXED,0, vertices);
+        glColorPointer(4,GL_UNSIGNED_BYTE,0, colors);
+        glScalef(scale,scale,scale);
+        glDrawElements(GL_TRIANGLES, 2*3, GL_UNSIGNED_SHORT, indices);
+        glScalef(1/scale,1/scale,1/scale);
+        
+        glTranslatef(aScreenSize.iHeight-ArrowDistance*2,0,0);
+		glRotatef(180,0,0,1);
+		
+        // Draw arrow
+        glVertexPointer(2,GL_FIXED,0, vertices);
+        glColorPointer(4,GL_UNSIGNED_BYTE,0, colors);
+        glScalef(scale,scale,scale);
+        glDrawElements(GL_TRIANGLES, 2*3, GL_UNSIGNED_SHORT, indices);
+        glScalef(1,1,1);
+        }
+	
+    glPopMatrix();
+#ifdef ENABLE_ALPHA
+	// Remove alpha
+	glDisable(GL_BLEND);
+	glDisable(GL_ALPHA_TEST);
+#endif
+    // Restore OpenGL state
+    glDepthMask(GL_TRUE);
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_TEXTURE_2D);
+    glShadeModel(GL_FLAT);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+    glPopMatrix();
+    }
+
+/*--------------------------------------------------------------------------*/
+// Draw animation
+//
+void CDrawUtility::Draw(const TSize &aScreenSize)
+    {
+    // Set OpenGL state
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glDepthMask(GL_FALSE);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_TEXTURE_2D);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_NORMAL_ARRAY);
+    glPushMatrix();
+    
+    // Set ortho to match screen size
+    glLoadIdentity();
+    glOrthof(0,aScreenSize.iWidth, aScreenSize.iHeight,0, -100,100);
+    
+    // Move to top right corner
+    glTranslatef(aScreenSize.iWidth-40,40,0);
+    
+    /*
+    // Calculate prespective values
+    GLfloat aspectRatio = (GLfloat)(aScreenSize.iWidth) / (GLfloat)(aScreenSize.iHeight);
+    const float near = 0.001;
+    const float far = 100.0;
+    const float top = 0.414*near;
+    const float bottom = -top;
+    const float left = aspectRatio * bottom;
+    const float right = aspectRatio * top;
+    
+    // Set perspective
+    glLoadIdentity();
+    glFrustumf(left,right, bottom,top, near,far);
+    glTranslatef(0,0,-40);
+    */
+    // Update light direction
+    float direction[4]={1, 0, -1, 0};
+    glLightfv(GL_LIGHT0,GL_POSITION, direction);
+    glColor4f(1,1,1, 1);
+    // Apply rotations
+    glRotatef(iAngleX, 1,0,0);
+    glRotatef(iAngleY, 0,1,0);
+    glRotatef(iAngleZ, 0,0,1);
+    
+    // Draw tetrahedron
+    glVertexPointer(3,GL_FIXED,0, iVertices);
+	glNormalPointer(GL_FIXED,0, iNormals);
+    glDrawElements(GL_TRIANGLES, iTriCount*3,GL_UNSIGNED_SHORT,iIndices);
+    
+    // Restore OpenGL state
+    glDepthMask(GL_TRUE);
+    glEnable(GL_DEPTH_TEST);
+    glDisable(GL_LIGHTING);
+    glEnable(GL_TEXTURE_2D);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_NORMAL_ARRAY);
+    glPopMatrix();
+    }
+#endif
+
+/*--------------------------------------------------------------------------*/
+// Draw moving arrow
+//
+void CDrawUtility::DrawMenuIndicators(const TSize& aScreenSize)
+    {
+    //Define shape of direction array
+    const GLfixed vertices[4*2] = 
+        {
+        0*1<<16,  0*1<<16,
+        10*1<<16, 7*1<<16,
+        7*1<<16,  0*1<<16,
+        10*1<<16,-7*1<<16,
+        };
+    //Define colors of direction array
+    const GLubyte colors[4*4] = 
+        {
+        //61,174,227, 128,
+        255,255,255, 255,
+        81,194,247, 255,
+        61,174,227, 255,
+        41,154,207, 255,
+        };
+    //And order of drawing
+    const GLushort indices[2*3]=
+        {
+        0,1,2,
+        2,3,0,
+        };
+    
+    TReal scale = 1;
+    if(aScreenSize.iHeight > 320 || aScreenSize.iWidth > 320)
+        {
+        scale = 1.5;
+        }
+        
+    // Set OpenGL state
+    // Shade model
+    glShadeModel(GL_SMOOTH);
+    glDepthMask(GL_FALSE);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_TEXTURE_2D);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_COLOR_ARRAY);
+    glPushMatrix();
+    
+#ifdef ENABLE_ALPHA
+    // Setup alpha
+    glEnable(GL_ALPHA_TEST);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#endif  
+    // Set ortho to match screen size
+    glLoadIdentity();
+    glOrthof(0,aScreenSize.iWidth, aScreenSize.iHeight,0, -100,100);
+    glPushMatrix();
+
+    // Move to arrow position
+    TInt ArrowDistance=20;
+    
+    glTranslatef(aScreenSize.iWidth - ArrowDistance, aScreenSize.iHeight/2, 0);
+    
+    //glTranslatef(ArrowDistance, aScreenSize.iWidth/2,0);
+    glVertexPointer(2,GL_FIXED,0, vertices);
+    glColorPointer(4,GL_UNSIGNED_BYTE,0, colors);
+    glScalef(scale,scale,scale);
+    glDrawElements(GL_TRIANGLES, 2*3, GL_UNSIGNED_SHORT, indices);
+    glScalef(1/scale,1/scale,1/scale);
+    glTranslatef(aScreenSize.iWidth-2*ArrowDistance, 0, 0);
+    
+    // Flip arrow around so it points to right
+    glRotatef(180,0,0,1);
+    
+    glVertexPointer(2,GL_FIXED,0, vertices);
+    glColorPointer(4,GL_UNSIGNED_BYTE,0, colors);
+    glScalef(scale,scale,scale);
+    glDrawElements(GL_TRIANGLES, 2*3, GL_UNSIGNED_SHORT, indices);
+    glScalef(1/scale,1/scale,1/scale);
+    
+    
+    
+    glPopMatrix();
+    
+#ifdef ENABLE_ALPHA
+    // Remove alpha
+    glDisable(GL_BLEND);
+    glDisable(GL_ALPHA_TEST);
+#endif
+    // Restore OpenGL state
+    glDepthMask(GL_TRUE);
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_TEXTURE_2D);
+    glShadeModel(GL_FLAT);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+    glPopMatrix();
+    }
+
+/*--------------------------------------------------------------------------*/
+// Draw icon texture
+//
+void CDrawUtility::DrawIcon(const TSize &aScreenSize, GLuint aTexIndex)
+    {
+    if(aTexIndex != 0)
+        {
+        GLfixed vertices[8];
+        SetPictureVertices(vertices, 1);
+        
+        glColor4f(1,1,1, 0.75);
+        
+        // Set OpenGL state
+        glDepthMask(GL_FALSE);
+        glDisable(GL_DEPTH_TEST);
+        glEnable(GL_TEXTURE_2D);
+        
+        //Enable alpha blending
+        glEnable(GL_BLEND);
+        glEnable(GL_ALPHA_TEST);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
+        
+        
+        glVertexPointer( 2, GL_FIXED, 0, vertices );
+        
+        glPushMatrix();
+        
+        // Set ortho to match screen size
+        glLoadIdentity();
+        glOrthof(0,aScreenSize.iWidth, aScreenSize.iHeight,0, -50,50);
+        
+        // Move to top right corner
+        //glTranslatef(29, 29, 1);
+        glTranslatef(0, 0, 0);
+        
+//#ifdef _S60_5x_ACCELEROMETER_
+        if(iContainer->GetScreenOrientation())
+            {
+            iRotationTarget = 0;
+            }
+        else
+            {
+            iRotationTarget = -90;
+            }
+        iContainer->Interpolate(iRotation, iRotationTarget, 0.25);
+        glRotatef(iRotation, 0,0,1);
+//#endif
+        
+        glBindTexture(GL_TEXTURE_2D, aTexIndex);
+        glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+                        
+        // Restore OpenGL state
+        glDepthMask(GL_TRUE);
+        glEnable(GL_DEPTH_TEST);
+        glEnable(GL_TEXTURE_2D);
+        
+        glDisable(GL_BLEND);
+        glDisable(GL_ALPHA_TEST);
+        
+        glDisableClientState(GL_VERTEX_ARRAY);
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+                
+        glPopMatrix();
+        }
+    }
+
+
+void CDrawUtility::DrawIcon2(const TSize &aScreenSize, GLuint aTexIndex, TReal aAlpha)
+    {
+    
+    iScrAspectratio = (TReal)aScreenSize.iWidth/(TReal)aScreenSize.iHeight;
+    
+        GLfixed vertices[8];
+        SetPictureVertices(vertices, 0.3);
+        
+        //glColor4f(1,1,1, 1);
+        glColor4f(1,1,1, aAlpha);
+        // Set OpenGL state
+        glDepthMask(GL_FALSE);
+        glDisable(GL_DEPTH_TEST);
+        glEnable(GL_TEXTURE_2D);
+        
+        //Enable alpha blending
+        glEnable(GL_BLEND);
+        glEnable(GL_ALPHA_TEST);
+        //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                
+        glVertexPointer( 2, GL_FIXED, 0, vertices );
+
+        glPushMatrix();
+        
+        // Set ortho to match screen size
+        glLoadIdentity();
+        glOrthof(0,aScreenSize.iWidth, aScreenSize.iHeight,0, -50,50);
+        
+        
+        glTranslatef(iScrSize.iWidth-7, iScrSize.iHeight-25, 1);
+        iContainer->Interpolate(iRotation, iRotationTarget, 0.60);
+        //glRotatef(90, 0,0,1);
+        glBindTexture(GL_TEXTURE_2D, aTexIndex);
+        glScalef(0.5, 0.5, 0.5);
+        glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+        glScalef(2, 2, 2);
+        glTranslatef(0, -iScrSize.iHeight+50, 1);
+        glScalef(0.5, 0.5, 0.5);
+        glBindTexture(GL_TEXTURE_2D, aTexIndex);
+        glDrawArrays(GL_TRIANGLE_STRIP,0,4);
+        glScalef(2, 2, 2);
+        
+        // Restore OpenGL state
+        glDepthMask(GL_TRUE);
+        glEnable(GL_DEPTH_TEST);
+        glEnable(GL_TEXTURE_2D);
+        
+        glDisable(GL_BLEND);
+        glDisable(GL_ALPHA_TEST);
+        
+        //glDisable(GL_BLEND);
+        /*if(aShowLocationRect)
+            DrawZoomFrame(iRotationTarget);*/
+        
+        glDisableClientState(GL_VERTEX_ARRAY);
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        glPopMatrix();
+        
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/DrawableInterface.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "DrawableInterface.h"
+
+/*--------------------------------------------------------------------------*/
+// Constructor and destructor
+//
+CDrawableInterface::CDrawableInterface()
+	{
+	// Nothing here
+	}
+
+CDrawableInterface::~CDrawableInterface()
+	{
+	// Nothing here
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/Gesture.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,384 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "debug.h"
+#include "Gesture.h"
+#include <aknnotewrappers.h>
+
+// TODO: Add flexibility to support more gesture. e.g. circle
+// TODO: Add tap range (size of allowed moving area for tap)
+// TODO: Add mode-type working. Change config by one call
+
+CGesture::CGesture(MGestureCallBack* aOwner)
+    //: CTimer(CActive::EPriorityUserInput)
+: CTimer(CActive::EPriorityHigh)
+    , iState(EWaiting)
+    , iOwner(aOwner)
+    , iFirstGesture(EGestureNone)
+    , iThresholdOfTap(KDefaultThresholdOfTapPixels)
+    , iThresholdOfCursor(KDefaultThresholdOfCursorPixels)
+    , iStationaryTime(KDefaultStationaryTime)
+    , iLongTapTime(KDefaultLongTapTime)
+    , iMonitoringTime(KDefaultMonitoringTime)
+    , iSafetyTime(KDefaultSafetyTime)
+    {
+    // No implementation required
+    }
+
+CGesture::~CGesture()
+    {
+    Cancel(); // CTimer
+    iDragPoints.Close();
+    iDragTicks.Close();
+    }
+
+CGesture* CGesture::NewLC(MGestureCallBack* aOwner)
+    {
+    CGesture* self = new (ELeave) CGesture(aOwner);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+CGesture* CGesture::NewL(MGestureCallBack* aOwner)
+    {
+    CGesture* self = CGesture::NewLC(aOwner);
+    CleanupStack::Pop(); // self;
+    return self;
+    }
+
+void CGesture::ConstructL()
+    {
+    CTimer::ConstructL();
+    CActiveScheduler::Add(this);
+    }
+
+EXPORT_C void CGesture::PointerEventL( const TPointerEvent& aEvent )
+    {
+#define RESETPOINTS()        {iDragPoints.Reset(); iDragTicks.Reset();}
+#define RECORDPOINTS(p, t)   {iDragPoints.Append(p); iDragTicks.Append(t);}
+#define SETMOVEMENT(d, c, p) {d.iX=c.iX-p.iX; d.iY=c.iY-p.iY;}
+
+    TInt tick = User::NTickCount();
+    TGestureType type = EGestureNone;
+    TPoint delta;
+    TPoint vector;
+    TInt threshold;
+
+    switch( aEvent.iType )
+        {
+        case TPointerEvent::EButton1Down:
+            DP2_IMAGIC(_L("CGesture::PointerEventL: TPointerEvent::EButton1Down (%d, %d)"), aEvent.iPosition.iX, aEvent.iPosition.iY);
+            
+            if (iState == EEnded) break; // do nothing if it's in safety time
+            
+            // Start timer to monitor long tap
+            Cancel(); // CTimer. Stop all timers.
+            DP1_IMAGIC(_L("iStationaryTime=%d"), iStationaryTime);
+            After( TTimeIntervalMicroSeconds32(iStationaryTime));
+
+            // Initialise pointer records and start new record
+            iPointBegan = iPointLastCursor = iPointPreviousEvent = aEvent.iPosition;
+            RESETPOINTS();
+            RECORDPOINTS(aEvent.iPosition, tick);
+
+            if (iState == EMonitoring)
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (2nd gesture starting)"));
+                // store 1st gesture type in high 16 bits if this is 2nd gesture
+                iFirstGesture = iFirstGesture << 16;
+                }
+            else // iState should be Waiting. Resets anyway even if it's not. 
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (1st gesture starting)"));
+                // Set point only for 1st gesture and notify owner
+                iFirstGesture    = EGestureNone;
+                iPointFirstBegan = aEvent.iPosition;
+                iOwner->HandleGestureBeganL(aEvent.iPosition);
+                }
+
+            iState = EBegan;
+
+            DP1_IMAGIC(_L("####### Down:iFirstGesture=%x"), iFirstGesture);
+            break;
+
+        case TPointerEvent::EDrag:
+            DP2_IMAGIC(_L("CGesture::PointerEventL: TPointerEvent::EDrag (%d, %d)"), aEvent.iPosition.iX, aEvent.iPosition.iY);
+
+            if ((iState != EBegan) && (iState != EStationary) && (iState != ETravelling))
+                break; // do nothing if it's not in the state above
+            
+            // record drag points and thier tick counts
+            RECORDPOINTS(aEvent.iPosition, tick);
+
+            SETMOVEMENT(delta, aEvent.iPosition, iPointPreviousEvent);
+
+            threshold = (iState == EBegan)? iThresholdOfTap * 3: iThresholdOfTap;
+            
+            if (IsMovementWithinThreshold(delta, threshold))
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (staying within threshold)"));
+                }
+            else
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (going beyond threshold)"));
+                Cancel(); // CTimer. Stop all timers.
+                iState = ETravelling;
+                }
+
+            if (iState == ETravelling)
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (notify drag event)"));
+                iOwner->HandleGestureMovedL(delta, EGestureDrag);
+                iPointPreviousEvent = aEvent.iPosition;
+                }
+
+#ifdef CURSOR_SIMULATION
+            type = CheckMovement(iPointLastCursor, aEvent.iPosition);
+
+            if (type != EGestureNone)
+                {
+                iOwner->HandleGestureMovedL(aEvent.iPosition, EGestureCursor|type);
+                iPointLastCursor = aEvent.iPosition;
+                }
+            DP5_IMAGIC(_L("iPointLastCursor(%d)"), type);
+#endif
+            break;
+
+        case TPointerEvent::EButton1Up:
+            DP2_IMAGIC(_L("CGesture::PointerEventL: TPointerEvent::EButton1Up (%d, %d)"), aEvent.iPosition.iX, aEvent.iPosition.iY);
+
+            if ((iState != EBegan) && (iState != EStationary) && (iState != ETravelling))
+                break; // do nothing if it's not in the state above
+            
+            Cancel(); // Stop timers
+            
+            iPointPreviousEvent = aEvent.iPosition;
+
+            // record drag points and thier tick counts
+            RECORDPOINTS(aEvent.iPosition, tick);
+
+            if ((iState == EBegan) ||
+                ((iState == EStationary) && !IS_GESTURE_LONGTAPPING(iFirstGesture)))
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (Tap!)"));
+                type = EGestureTap;
+                
+                // TODO: check distance of each tap if it's double tap
+                iFirstGesture |= type;
+
+                TInt t = (IS_GESTURE_TAPPED(iFirstGesture))? 0: iMonitoringTime;
+                After(TTimeIntervalMicroSeconds32(t)); // call immediately if double tap
+                iState = EMonitoring;
+                }
+            else if ((iState == EStationary) && IS_GESTURE_LONGTAPPING(iFirstGesture))
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (Long tap!)"));
+                type = EGestureLongTap;
+
+                iFirstGesture |= type;
+                After(TTimeIntervalMicroSeconds32(iMonitoringTime));
+                iState = EMonitoring;
+                }
+            else if (iState == ETravelling)
+                {
+                DP0_IMAGIC(_L("CGesture::PointerEventL (Was drag. Flick!)"));
+                type = CheckFlick(KDefaultValidityTimeOfFlick, vector);
+                iPointPreviousEvent = vector;
+
+                iFirstGesture |= type;
+                After(TTimeIntervalMicroSeconds32(0)); // call immediately 
+                iState = EMonitoring;
+                }
+
+            DP1_IMAGIC(_L("####### Up:iFirstGesture=%x"), iFirstGesture);
+            break;
+
+        default:
+            break;
+        }
+    }
+
+EXPORT_C void CGesture::SetThresholdOfTap( const TInt aPixels)
+    {
+    iThresholdOfTap = aPixels;
+    }
+
+EXPORT_C void CGesture::SetThresholdOfCursor( const TInt aPixels)
+    {
+    iThresholdOfCursor = aPixels;
+    }
+
+EXPORT_C void CGesture::SetStationaryTime(const TInt aMicroseconds)
+    {
+    iStationaryTime = aMicroseconds;
+    }
+
+EXPORT_C void CGesture::SetLongTapTime(const TInt aMicroSeconds)
+    {
+    iLongTapTime = aMicroSeconds;
+    }
+
+EXPORT_C void CGesture::SetMonitoringTime(const TInt aMicroseconds)
+    {
+    iMonitoringTime = aMicroseconds;
+    }
+
+EXPORT_C void CGesture::SetSafetyTime(const TInt aMicroseconds)
+    {
+    iSafetyTime = aMicroseconds;
+    }
+
+TBool CGesture::IsMovementWithinThreshold(const TPoint aDelta, const TInt aThreshold)
+    {
+    TBool ret = ETrue;
+
+    TInt diff_x      = aDelta.iX;
+    TInt diff_y      = aDelta.iY;
+    TInt abs_diff_2  = diff_x * diff_x + diff_y * diff_y;
+    TInt threshold_2 = aThreshold * aThreshold;
+
+    if (abs_diff_2 > threshold_2) ret = EFalse;
+    
+    return ret;
+    }
+
+TGestureType CGesture::CheckMovement(const TPoint aPointPrevious, const TPoint aPointCurrent, const TBool aSkipThresholdCheck)
+    {
+    TGestureType ret = EGestureNone;
+
+    TInt diff_x  = aPointCurrent.iX - aPointPrevious.iX;
+    TInt diff_y  = aPointCurrent.iY - aPointPrevious.iY;
+
+    TInt abs_diff_x = Abs(diff_x);
+    TInt abs_diff_y = Abs(diff_y);
+    TInt abs_diff_2 = abs_diff_x*abs_diff_x + abs_diff_y*abs_diff_y;  
+
+    if (abs_diff_2 > iThresholdOfCursor*iThresholdOfCursor)
+        {
+        // Movement is mapped to one of 8 directions
+        TBool valid_x = (abs_diff_x && (abs_diff_x * 5 > abs_diff_y * 4))? ETrue: EFalse;
+        TBool valid_y = (abs_diff_y && (abs_diff_y * 5 > abs_diff_x * 4))? ETrue: EFalse;
+
+        if (valid_y)
+            {
+            if (diff_y < 0) ret |= EGestureUp;
+            else            ret |= EGestureDown;
+            }
+        if (valid_x)
+            {
+            if (diff_x < 0) ret |= EGestureLeft;
+            else            ret |= EGestureRight;
+            }
+        }
+    
+    return ret;
+    }
+
+TGestureType CGesture::CheckFlick(const TInt aValidityTime, TPoint& aVector)
+    {
+    DP0_IMAGIC(_L("CGesture::CheckFlick++"));
+
+    // TODO: need to check if counts are same in iDragPoints and iDragTicks
+    TInt first, last;
+    TInt validtick = aValidityTime / 1000; // convert micro sec to milli sec.
+    TGestureType ret = EGestureNone;
+
+    first = last = iDragPoints.Count() - 1;
+    aVector.iX = aVector.iY = 0;
+    
+    for (TInt i=last-1;i>=0;--i)
+        {
+        TInt tickdiff = iDragTicks[last] - iDragTicks[i];
+
+        DP5_IMAGIC(_L("i=%d, tick=%d, tickdiff=%d (x,y)=(%d,%d)"),
+                i, iDragTicks[i], tickdiff, iDragPoints[i].iX, iDragPoints[i].iY);
+
+        if (tickdiff < validtick)
+            {
+            first = i;
+            }
+        else
+            {
+            break;
+            }
+        }
+
+    if (first != last)
+        {
+        TInt tickdiff = iDragTicks[last] - iDragTicks[first];
+        ret = CheckMovement(iDragPoints[first], iDragPoints[last], ETrue);
+
+        // Tick diff is 100 at minimum to avoid returning extreamly big vector.
+        if (tickdiff < 100) tickdiff = 100;
+
+        // Calculate the movement speed = pixels/sec
+        aVector.iX = (iDragPoints[last].iX - iDragPoints[first].iX)*1000/tickdiff;
+        aVector.iY = (iDragPoints[last].iY - iDragPoints[first].iY)*1000/tickdiff;
+        }
+
+    DP5_IMAGIC(_L("%d~%d, %d=>%d =%d"),
+            first, last, iDragPoints[first].iX, iDragPoints[last].iX,
+            CheckMovement(iDragPoints[first], iDragPoints[last]));
+    DP2_IMAGIC(_L("vector (%d,%d)"), aVector.iX, aVector.iY);
+    DP0_IMAGIC(_L("CGesture::CheckFlick--"));
+
+    return ret;
+    }
+
+void CGesture::RunL()
+    {
+    DP0_IMAGIC(_L("CGesture::RunL++"));
+
+    switch (iState)
+        {
+        case EBegan:
+            DP1_IMAGIC(_L("CGesture::RunL (EBegan -> EStationary) iLongTapTime=%d"), iLongTapTime);
+            iOwner->HandleGestureMovedL(iPointPreviousEvent, EGestureStationary);
+            After(TTimeIntervalMicroSeconds32(iLongTapTime));
+            iState = EStationary;
+
+            // Update the position so that movement check occurs against 
+            // last drag event, not against initial touch position
+            if (iDragPoints.Count() > 1)
+                iPointPreviousEvent = iDragPoints[iDragPoints.Count()-1];
+            break;
+        case EStationary:
+            DP0_IMAGIC(_L("CGesture::RunL (EStationary -> EStationary)"));
+            iOwner->HandleGestureMovedL(iPointPreviousEvent, EGestureLongTapping);
+            // record it's possible long tap if movement stays within threshold
+            iFirstGesture |= EGestureLongTapping;
+            // no state change
+            break;
+        case EMonitoring:
+            DP1_IMAGIC(_L("CGesture::RunL (EMonitoring -> EEnded) iSafetyTime=%d"), iSafetyTime);
+            iOwner->HandleGestureEndedL(iPointPreviousEvent, iFirstGesture);
+            After(TTimeIntervalMicroSeconds32(iSafetyTime));
+            iState = EEnded;
+            break;
+        case EEnded:
+            DP0_IMAGIC(_L("CGesture::RunL (EEnded -> EWaiting)"));
+            iState = EWaiting;
+            break;
+        default:
+            DP0_IMAGIC(_L("CGesture::RunL (default)"));
+            // do nothing
+            break;
+        }
+
+    DP0_IMAGIC(_L("CGesture::RunL--"));
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/Imagic.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// INCLUDE FILES
+#include <eikstart.h>
+#include "ImagicApp.h"
+
+/**
+ * factory function to create the Hello World Basic application class
+ */
+LOCAL_C CApaApplication* NewApplication()
+	{
+	 
+	return new CImagicApp;
+	}
+
+/**
+ * A normal Symbian OS executable provides an E32Main() function which is
+ * called by the operating system to start the program.
+ */
+GLDEF_C TInt E32Main()
+	{
+
+	return EikStart::RunApplication( NewApplication );
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/ImagicApp.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+
+// INCLUDE FILES
+#include    "ImagicApp.h"
+#include    "ImagicDocument.h"
+
+ 
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CImagicApp::AppDllUid()
+// Returns application UID
+// ---------------------------------------------------------
+//
+TUid CImagicApp::AppDllUid() const
+    {
+    return KUidImagic;
+    }
+
+   
+// ---------------------------------------------------------
+// CImagicApp::CreateDocumentL()
+// Creates CImagicDocument object
+// ---------------------------------------------------------
+//
+CApaDocument* CImagicApp::CreateDocumentL()
+    {
+ 
+       return (static_cast<CApaDocument*>
+                       ( CImagicDocument::NewL( *this ) ) );
+    }
+
+
+
+
+    
+
+// End of File  
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/ImagicAppUi.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,702 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+ 
+
+// INCLUDE FILES
+#include "ImagicAppUi.h"
+#include <IEImage.h>
+#include "ImagicViewBrowser.h"
+#include "Imagic.hrh"
+#include "MSVSTD.HRH"
+#include <avkon.hrh>
+#include <ImageConversion.h>
+#include <aknutils.h>
+#include "ImagicContainerBrowser.h"
+
+//statuspane
+#include <eikbtgpc.h> 
+#include <avkon.rsg>
+
+//for loading text from resource
+#include <aknnotewrappers.h>
+#include <stringloader.h>
+
+#include <PhotoBrowser.rsg>
+#include "ImagicUtils.h"
+
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+//
+// ----------------------------------------------------------
+// CImagicAppUi::ConstructL()
+// ----------------------------------------------------------
+//
+void CImagicAppUi::ConstructL()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::ConstructL++"));
+    
+    //CArrayFix<TCoeHelpContext>* buf = CCoeAppUi::AppHelpContextL();
+    //HlpLauncher::LaunchHelpApplicationL(iEikonEnv->WsSession(), buf);
+
+    
+    iTNGenerationOnGoing = ETrue;
+    iMenuOn = EFalse;
+    iAppForeGround = ETrue;
+    
+    //Set the font
+    //SetFont();
+    
+    iImagesLoaded = EFalse;
+    iImageIndex = 0;     
+    iWzContainerSatus = EFalse;
+    //iTotalNumOfImages = 0;
+    //iNumOfImagesLoaded = 0;
+    //iNumOfFacesLoaded = 0;
+    iNumberOfIterations = 0;
+    iUIDrawMode = EImages;
+    iBrowserContainer = NULL;
+#ifdef USE_OOM    
+    ROomMonitorSession oomMonitor;
+    oomMonitor.Connect();
+    TInt errorCode = oomMonitor.RequestFreeMemory( 1024*12 );
+    
+    if ( errorCode != KErrNone )
+        {
+        // try one more time 
+        errorCode = oomMonitor.RequestFreeMemory( 1024*12 );
+        }
+    oomMonitor.Close();
+#endif    
+    User::LeaveIfError(iFileServer.Connect());
+    
+    //Initialises this app UI with standard values.
+    //The application’s standard resource file will be read unless
+    //the ENoAppResourceFile or ENonStandardResourceFile flags are passed.
+    BaseConstructL(0x08 | EAknEnableSkin); // Use ELayoutAwareAppFlag (0x08) to make the application support scalable UI on FP3 devices.
+
+    //Create engine and trap if there is error
+    iIEngine = CIEEngine::NewL(*this);
+	CleanupStack::PushL(iIEngine);
+    
+    //Browser view
+    CImagicViewBrowser* viewBrowser = new (ELeave) CImagicViewBrowser;
+    CleanupStack::PushL( viewBrowser );
+    viewBrowser->ConstructL(this);
+    AddViewL( viewBrowser );      // transfer ownership to CAknViewAppUi
+    CleanupStack::Pop( viewBrowser );
+    iViewIdBrowser = viewBrowser->Id(); // view id to get view from CAknViewAppUi
+    
+    SetDefaultViewL( *viewBrowser );
+    SetActiveView(BrowserView);
+    
+    //disable statuspane to get full screen
+    StatusPane()->MakeVisible(EFalse);
+    
+    //Creating Utility class
+    iImagicUtils = CImagicUtils::NewL(iFileServer);
+    
+    //Create timer to release Browser view resources and init opengl
+    iPeriodic = CPeriodic::NewL( CActive::EPriorityIdle );
+    
+    //Force orientation to be always landscape
+    SetOrientationL(CAknAppUiBase::EAppUiOrientationLandscape);
+    //SetOrientationL(CAknAppUiBase::EAppUiOrientationPortrait);
+
+	CleanupStack::Pop(iIEngine);	
+
+    DP0_IMAGIC(_L("CImagicAppUi::ConstructL--"));
+    }
+
+
+CArrayFix<TCoeHelpContext>* CImagicAppUi::HelpContextL() const
+    {
+    /*
+    //#warning "Please see comment about help and UID3..."
+    CArrayFixFlat<TCoeHelpContext>* array = new(ELeave)CArrayFixFlat<TCoeHelpContext>(1);
+    CleanupStack::PushL(array);
+    array->AppendL(TCoeHelpContext(KUidrsdApp, KGeneral_Information));
+    CleanupStack::Pop(array);
+    return array;
+    */
+    }
+
+void CImagicAppUi::CImagicAppUiReady()
+    {
+    iIEngine->AppUIReady();
+    }
+
+// ----------------------------------------------------
+// CImagicAppUi::~CImagicAppUi()
+// Destructor
+// Frees reserved resources
+// ----------------------------------------------------
+//
+CImagicAppUi::~CImagicAppUi()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::~CImagicAppUi++"));
+    if(iImagicUtils)
+        {
+        delete iImagicUtils;
+        iImagicUtils = NULL;
+        }
+    
+    iWizardBitmapArray.Close();
+    
+    if(iPeriodic->IsActive())
+        iPeriodic->Cancel();
+    delete iPeriodic;
+
+    // Doesn't delete engine yet, since container needs it when destroyed!
+    //DestructEngine();
+    
+    iFileServer.Close();
+
+    DP0_IMAGIC(_L("CImagicAppUi::~CImagicAppUi--"));
+    }
+
+void CImagicAppUi::DestructEngine()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::DestructEngine++"));    
+    delete iIEngine;
+    iIEngine = NULL;
+    DP0_IMAGIC(_L("CImagicAppUi::DestructEngine--"));    
+    }
+
+
+/*TInt CImagicAppUi::GetErrorCode()
+    {
+    return iEngineCreationError;
+    }*/
+  
+// ------------------------------------------------------------------------------
+// CImagicAppUi::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)
+//  This function is called by the EIKON framework just before it displays
+//  a menu pane. Its default implementation is empty, and by overriding it,
+//  the application can set the state of menu items dynamically according
+//  to the state of application data.
+// ------------------------------------------------------------------------------
+//
+void CImagicAppUi::DynInitMenuPaneL(
+    TInt /*aResourceId*/,CEikMenuPane* /*aMenuPane*/)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::DynInitMenuPaneL"));
+    }
+
+
+void CImagicAppUi::BrowserContainerInitialized()
+    {
+    if(((CImagicViewBrowser*) View(iViewIdBrowser))->GetContainer() != NULL)
+        {
+        iBrowserContainer = ((CImagicViewBrowser*) View(iViewIdBrowser))->GetContainer();
+        iBrowserContainer->ImageListChanged(0, EFalse); // TODO: cheap trick to update coords
+        }
+    }
+
+
+// ------------------------------------------------------------------------------
+// CImagicAppUi::HandleForegroundEventL(TBool aForeground)
+//  This function is called by the  framework when the screen loses or gains focus.
+//   i.e. when it goes to the background or to the foreground. Incoming call
+//   softnote is an example.
+// This event applies to the entire application, all views.
+// ------------------------------------------------------------------------------
+//
+void CImagicAppUi::HandleForegroundEventL(TBool aForeground)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::HandleForegroundEventL++"));
+    
+    //SetOrientationL(CAknAppUiBase::EAppUiOrientationPortrait);
+    if(iBrowserContainer)
+        if (aForeground)
+            {
+            DP0_IMAGIC(_L("CImagicAppUi::HandleForegroundEventL - App Foreground"));
+            
+            //We were switched to foreground
+            iAppForeGround = ETrue;
+            //ScreenImmeadetaUpdate();
+            
+            if(iPeriodic->IsActive())
+                iPeriodic->Cancel();
+            
+            iIEngine->StartAccSensorMonitoring();
+            
+            iBrowserContainer->SetDeleteTextures(EFalse);
+            
+            iAppActiveState = ETrue;
+            
+            if(iViewNro == BrowserView)
+                {
+                if(iBrowserContainer && !iBrowserContainer->IsOpenGLInit())
+                    {
+                    iBrowserContainer->InitAfterPowerSaveL();
+                    }
+                else
+                    {
+                    if(iBrowserContainer)
+                        iBrowserContainer->EnableDisplayDraw();
+                    }
+                }
+            
+            if(iBrowserContainer)
+                {
+                iBrowserContainer->DrawNow();
+                iBrowserContainer->EnableDisplayDraw();
+                }
+            }
+        else
+            {//We were switched to background
+            DP0_IMAGIC(_L("CImagicAppUi::HandleForegroundEventL - App Background"));
+            
+            iAppForeGround = EFalse;
+            //ScreenImmeadetaUpdate();
+            
+            if(iViewNro == BrowserView)
+                {
+                //... disable frame loop timer ...
+                //iBrowserContainer->DisableDisplayDraw();
+                        
+                //... start a timer for 3 seconds to call to a power save callback ...
+                iPeriodic->Start( 3000000, 1000000000, TCallBack( CImagicAppUi::TimerCallBack, this ) );
+                //iBrowserContainer = ((CImagicViewBrowser*) View(iViewIdBrowser))->GetContainer();
+                }
+            
+            //iIEngine->StopAccSensorMonitoring();
+            
+            iAppActiveState = EFalse;
+            if(iBrowserContainer)
+                {
+                iBrowserContainer->DrawNow();
+                iBrowserContainer->DisableDisplayDraw();
+                }
+            }
+            
+    DP0_IMAGIC(_L("CImagicAppUi::HandleForegroundEventL--"));
+    }
+
+//Power save timer callback function
+//Cleans memory allocations for openGl draving
+TInt CImagicAppUi::TimerCallBack(TAny* aInstance)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::TimerCallBack++"));
+    
+    CImagicAppUi* instance = (CImagicAppUi*) aInstance;
+    
+    instance->iIEngine->StopAccSensorMonitoring();
+    
+    if(instance->iViewNro == BrowserView)
+        {
+        if(instance->iBrowserContainer && instance->iBrowserContainer->IsOpenGLInit())
+            {
+            DP0_IMAGIC(_L("CImagicAppUi::TimerCallBack - DeleteTextures"));
+            //instance->iBrowserContainer->DeleteTextures();
+            instance->iBrowserContainer->SetDeleteTextures(ETrue);
+            }
+        }
+    
+    DP0_IMAGIC(_L("CImagicAppUi::TimerCallBack--"));
+    return 0;
+    }
+
+void  CImagicAppUi::SetTNGenerationFlag(TBool aValue)
+    {
+    iTNGenerationOnGoing = aValue;
+    }
+
+// ----------------------------------------------------
+// CImagicAppUi::HandleKeyEventL(
+//     const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
+// Here we handle key events: Right and left arrow key
+//   to change view.
+// ----------------------------------------------------
+//
+TKeyResponse CImagicAppUi::HandleKeyEventL(const TKeyEvent& /*aKeyEvent*/, TEventCode /*aType*/)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::HandleKeyEventL"));
+    //No need to handle events here
+    return EKeyWasNotConsumed;
+    }
+
+// ----------------------------------------------------
+// CImagicAppUi::HandleCommandL(TInt aCommand)
+// Here we handle commands on the application level.
+// In addition, each view has their own HandleCommandL()
+// ----------------------------------------------------
+//
+void CImagicAppUi::HandleCommandL(TInt aCommand)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::HandleCommandL"));
+    
+    switch ( aCommand )
+        {
+        case EEikCmdExit:
+            {
+            iIEngine->Stop();
+            
+            // send to background
+            TApaTask apaTask( CEikonEnv::Static()->WsSession() );
+            apaTask.SetWgId( iCoeEnv->RootWin().Identifier() );
+            apaTask.SendToBackground();
+
+            // Wait until engine is stopped
+            while (iIEngine->IsRunning())
+                {
+                User::After(200000);   // 200ms
+                }
+            DP0_IMAGIC(_L("CImagicAppUi::HandleCommandL end wait"));
+			if(iTNGenerationOnGoing)
+				{
+				TInt i = KErrNone;
+	            //iIEngine->StopFaceDetection(i);
+    	        iIEngine->StopTNGeneration(i);
+				}
+                
+            Exit();
+            break;
+            }
+            
+        case EImagicCmdViewCmd1:
+            {
+			break;
+            }
+        // You can add your all application applying commands here.
+        // You would handle here menu commands that are valid for all views.
+        }
+    
+    }
+
+TInt CImagicAppUi::ExitTimerCallBack(TAny* aInstance)
+    {
+    CImagicAppUi* instance = (CImagicAppUi*) aInstance;
+    instance->iNumberOfIterations++;
+    if(instance->iTNGenerationOnGoing)
+        {
+        if(instance->iNumberOfIterations == 10)
+            {
+            instance->iNumberOfIterations = 0;
+            instance->iPeriodic->Cancel();
+            //instance->CancelExitDialog();
+            instance->iImagicUtils->CancelWaitDialog();
+            User::Exit(KErrNone);
+            }
+        else
+            {
+            //nothing.. continue...
+            }
+        }
+    else
+        {
+        instance->iPeriodic->Cancel();
+        //instance->CancelExitDialog();
+        instance->iImagicUtils->CancelWaitDialog();
+        
+        User::Exit(KErrNone);
+        }
+        
+    return 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CImagicAppUi::HandleResourceChangeL( TInt aType )
+// Called by framework when layout is changed.
+// -----------------------------------------------------------------------------
+//
+void CImagicAppUi::HandleResourceChangeL( TInt aType )
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::HandleResourceChangeL"));
+    
+    //on = aType = 268457666, off = aType = 268457667     
+    
+    if(iBrowserContainer != NULL)
+        {
+        if(aType == 268457666)
+            {
+            iMenuOn = ETrue;
+            //ScreenImmeadetaUpdate();
+            if(iBrowserContainer)
+                {
+                iBrowserContainer->SetScreenImmeadetaUpdate(ETrue);
+                iBrowserContainer->DisableDisplayDraw();
+                }
+            }
+        else if(aType == 268457667)
+            {
+            iMenuOn = EFalse;
+            //ScreenImmeadetaUpdate();
+            
+            if(iBrowserContainer)
+                {
+                iBrowserContainer->SetScreenImmeadetaUpdate(EFalse);
+                iBrowserContainer->EnableDisplayDraw();    
+                }
+            
+            }
+        
+        iBrowserContainer->DrawNow();
+        }
+    
+    CAknAppUi::HandleResourceChangeL( aType );
+    
+    // ADDED FOR SCALABLE UI SUPPORT
+    // *****************************
+    if ( aType==KEikDynamicLayoutVariantSwitch )
+        {
+		((CImagicViewBrowser*) View( iViewIdBrowser) )->HandleClientRectChange(  );
+		}
+    
+    }
+
+TBool CImagicAppUi::IsAppOnTop()
+    {
+    if(iMenuOn)
+        {
+        DP0_IMAGIC(_L("CImagicAppUi::IsAppOnTop: EFalse"));
+        return EFalse;
+        }
+    else if(!iAppForeGround)
+        {
+        DP0_IMAGIC(_L("CImagicAppUi::IsAppOnTop: EFalse"));
+        return EFalse;
+        }
+    else
+        {
+        DP0_IMAGIC(_L("CImagicAppUi::IsAppOnTop: ETrue"));
+        return ETrue;
+        }
+    }
+
+void CImagicAppUi::ScreenImmeadetaUpdate()
+    {
+    if(iMenuOn || !iAppForeGround)
+        iBrowserContainer->SetScreenImmeadetaUpdate(ETrue);
+    else
+        iBrowserContainer->SetScreenImmeadetaUpdate(EFalse);
+    }
+
+
+void CImagicAppUi::SetImageIndex(TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::SetImageIndex"));
+    
+    if(aIndex >= iIEngine->GetTotalNumOfImages())
+        aIndex = 0;
+    if(aIndex < 0)
+        aIndex = iIEngine->GetTotalNumOfImages()-1;
+    
+    iImageIndex = aIndex;
+    }
+
+TInt CImagicAppUi::GetImageIndex()
+	{
+	DP0_IMAGIC(_L("CImagicAppUi::GetImageIndex"));
+	return iImageIndex;
+	}
+
+#ifdef _ACCELEROMETER_SUPPORTED_
+void CImagicAppUi::ImageRotated(TImagicDeviceOrientation aDeviceOrientation)
+    {
+    DP1_IMAGIC(_L("CImagicAppUi::ImageRotated, angle: %d"),aDeviceOrientation);
+    iBrowserContainer->PhoneRotated(aDeviceOrientation);
+    }
+#endif
+
+void CImagicAppUi::SetActiveView(TUid aViewNro)
+	{
+	DP0_IMAGIC(_L("CImagicAppUi::SetActiveView"));
+	iViewNro = aViewNro;
+	}
+
+TUid CImagicAppUi::GetActiveView()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::GetActiveView"));
+    return iViewNro;
+    }
+
+
+//Callback from engine that loaded Bitmap image is ready for drawing
+void CImagicAppUi::ImagesLoadedL(TInt aError)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::ImagesLoaded++"));
+    
+    if(iViewNro == BrowserView)
+        {
+        ((CImagicViewBrowser*) View(iViewIdBrowser))->BitmapLoadedByEngineL(aError);
+        }
+    
+    DP0_IMAGIC(_L("CImagicAppUi::ImagesLoaded--"));
+    }
+
+
+//To get engine interface for other class usage
+CIEEngine* CImagicAppUi::GetEngine()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::GetEngine"));
+    
+    return iIEngine;
+    }
+
+
+void CImagicAppUi::SetUIDrawMode(TImageArrayMode aMode)
+    {
+    iUIDrawMode = aMode;
+    }
+
+/*
+TImageArrayMode CImagicAppUi::GetUIDrawMode()
+    {
+    return iUIDrawMode;
+    }
+
+TRgb CImagicAppUi::GetTransparentWhite()
+    {
+    return iTransparentWhite;
+    }
+
+TRgb CImagicAppUi::GetTransparentBlack()
+    {
+    return iTransparentBlack;
+    }
+
+const CFont* CImagicAppUi::GetFont()
+    {
+    return iFont;
+    }
+*/
+
+CImagicUtils* CImagicAppUi::GetImagicUtils()
+    {
+    return iImagicUtils;
+    }
+
+
+/*void CImagicAppUi::SetFont()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::SetFont"));
+    
+    // set the font
+    iFont = AknLayoutUtils::FontFromId(EAknLogicalFontPrimaryFont);
+    //Set alpha colors
+    iTransparentWhite=TRgb(KRgbWhite);
+    iTransparentWhite.SetAlpha(128);
+    iTransparentBlack=TRgb(KRgbBlack);
+    iTransparentBlack.SetAlpha(128+64);
+    }*/
+
+
+void CImagicAppUi::ImageListChanged(TInt aIndex, TBool aAdded)
+    {
+    DP2_IMAGIC(_L("CImagicAppUi::ImageListChanged %d %d"), aIndex, aAdded);
+    if (iBrowserContainer)
+        iBrowserContainer->ImageListChanged(aIndex, aAdded);
+    }
+
+//This is called when single face Detection has been completed
+void CImagicAppUi::SingleFaceDetectionComplete()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::SingleFaceDetectionComplete"));
+    
+    //((CImagicViewBrowser*) View(iViewIdBrowser))->SingleFaceDetectionComplete();
+    }
+
+//Callback function from engine that BackGround Face Detection has been completed
+void CImagicAppUi::FaceDetectionComplete()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::FaceDetectionComplete"));
+    
+    ((CImagicViewBrowser*) View(iViewIdBrowser))->FaceDetectionComplete();
+    }
+
+//Callback function from engine that Face Browsing creation has been completed
+
+void CImagicAppUi::SingleTNCreationCompletedL(TInt /*aIndex*/, TThumbSize aTnRes)
+    {
+    DP1_IMAGIC(_L("CImagicAppUi::SingleTNCreationCompletedL - res: %d"),aTnRes);
+    
+    iBrowserContainer->NewImageAdded();
+    iBrowserContainer->SetLoadingOn(ETrue);
+    //iBrowserContainer->DrawScreen();
+    iBrowserContainer->DrawNow();
+    }
+
+//Callback function from engine that TN creation has been completed
+void CImagicAppUi::TNCreationCompleteL(TThumbSize aTnRes)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::TNCreationComplete++"));
+    
+    iTNGenerationOnGoing = EFalse; 
+    ((CImagicViewBrowser*) View(iViewIdBrowser))->TNCreationComplete();
+    
+    iBrowserContainer->DrawNow();
+    
+            
+    /*TApplicationFeature appFeature = ((CImagicViewBrowser*)View(iViewIdBrowser))->GetAppFeature(); 
+    
+    //This is in case we were editing and we did not have 320x320 tn created
+    if(appFeature == EAppFeatureEditing && aTnRes == ESize32x32)
+        {
+        iTNGenerationOnGoing = EFalse; 
+        ((CImagicViewBrowser*) View(iViewIdBrowser))->TNCreationComplete();
+        }
+    
+    else if(appFeature == EAppFeatureNone )
+        {
+        iTNGenerationOnGoing = EFalse; 
+        ((CImagicViewBrowser*) View(iViewIdBrowser))->TNCreationComplete();
+        }
+    
+    else if((appFeature == EAppFeatureEditing || appFeature == EAppFeatureCropping) &&  (aTnRes == ESize512x512 || aTnRes == ENotDefined))
+        {
+        iTNGenerationOnGoing = EFalse;
+        ((CImagicViewBrowser*) View(iViewIdBrowser))->TNCreationComplete();
+        
+        }*/
+    DP0_IMAGIC(_L("CImagicAppUi::TNCreationComplete--"));
+    }
+
+
+TInt CImagicAppUi::DeleteImage(TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::DeleteImage++"));
+    
+    TInt err = iIEngine->DeleteFile(aIndex);
+    
+    DP0_IMAGIC(_L("CImagicAppUi::DeleteImage--"));
+    
+    return err;
+    }
+
+void CImagicAppUi::AllFilesScanned()
+    {
+    DP0_IMAGIC(_L("CImagicAppUi::AllFilesScanned++"));
+    
+    if(iIEngine->GetTotalNumOfImages() <= 0)
+        GetImagicUtils()->ExecuteQueryDialog(0/*GetErrorCode()*/, R_NO_IMAGES_DIALOG);
+    
+    iBrowserContainer->DrawNow();
+    
+    DP0_IMAGIC(_L("CImagicAppUi::AllFilesScanned--"));
+    }
+
+TInt CImagicAppUi::GetGleMaxRes()
+    {
+    return iBrowserContainer->GetGleMaxRes();
+    }
+
+
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/ImagicContainerBrowser.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,3723 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+
+// INCLUDE FILES
+#include "ImagicContainerBrowser.h"
+#include "ImagicViewBrowser.h"
+#include "TextureLoader.h"
+
+#include <e32math.h>
+#include <e32debug.h>
+#include <BitmapTransforms.h> 
+#include <e32cmn.h>
+#include <hal.h>
+#include "Imagic.hrh"
+#include "project.h"
+#include <hal.h>
+#include "DrawUtility.h"
+#include "ImagicConsts.h"
+#include <PhotoBrowser.rsg>
+
+
+const float CImagicContainerBrowser::KMinOneByOneZoom = 1;
+const float CImagicContainerBrowser::KMaxOneByOneZoom = 4.2;
+const TInt  CImagicContainerBrowser::KDoubleTapZoomOneByOne1 = KMinOneByOneZoom;
+const TInt  CImagicContainerBrowser::KDoubleTapZoomOneByOne2 = KMaxOneByOneZoom*0.71;
+const TReal CImagicContainerBrowser::KAngle2Start128Loading = 3;
+const TReal CImagicContainerBrowser::KAngle2Start128LoadingHwAcc = 6;
+const TInt  CImagicContainerBrowser::KGridSizeY = 3;
+
+/*const*/ TInt  CImagicContainerBrowser::K512TNImageBuffer = 1;//number of pictures to be loaded when using dynamic loading in grid
+const TInt  CImagicContainerBrowser::K128TNImageBuffer = 8;//number of pictures to be loaded when using dynamic loading in grid
+/*const*/ TInt  CImagicContainerBrowser::K32TNImageBuffer = 300;//number of pictures to be loaded when using dynamic loading in grid
+/*const*/ TInt  CImagicContainerBrowser::K32TNImageUnLoadBuffer = K32TNImageBuffer*3;
+
+const TReal KLoadingImageAspectRatio = 1.23;
+const TInt  KNumOf32ThumbsLoadedBefore128Thumb = 10;
+
+#ifdef ADAPTIVE_FRAMERATE
+#ifdef __WINS__
+const TInt  KDisplayDrawFreq = 20000; 
+const TInt  KPowerSaveDisplayDrawFreq = 20000;
+const TInt  KWaitTicksAfterDraw = 0;
+#else
+const TInt  KDisplayDrawFreq = 60000; 
+const TInt  KPowerSaveDisplayDrawFreq = 135000;
+const TInt  KWaitTicksAfterDraw = 0;
+#endif
+#else
+const TInt  KDisplayDrawFreq = 60000;//display update freq in micro secons, 60.000us = 16.7FPS
+const TInt  KPowerSaveDisplayDrawFreq = 95000;//display update freq in micro secons, 12.5FPS
+#endif
+
+const float CImagicContainerBrowser::KSpacingX = 1.2;// Picture spacing in the grid
+const float CImagicContainerBrowser::KSpacingY = 1.15;// Picture spacing in the grid
+// Space between pictures in one by one
+const float CImagicContainerBrowser::KOneByOneSpacing=1.1;
+
+const float KFindFaceSearchRange = 0.01;
+const TInt KPowerSavePeriodicDelay = 300000;//0.3s
+const TInt KTouchDelay = 1000000;//1s. longer because it scrolls even after user action
+const TInt KPowerSavePeriodicInterval = 40000000;//0.4s
+const TReal KInitDrawZoom = 0.1;
+
+#define INT_MAX ((int)(((unsigned int)-1)>>1))
+// macro to check if OneByOne view is zooming in. +0.01f for safety
+#define IS_NOT_IN_ZOOM_ONEBYONE ((iDrawOneByOne->GetDrawOneByOneTargetZoom()) < (KDoubleTapZoomOneByOne1 + 0.01f))
+#define IS_ALMOST_ZERO (0.001)
+
+const float KUpdatesPerSecond = 1.0/15;
+
+//App UI Feature definition flags
+#define USE_LOW_DRAW_SPEED_WHILE_LOADING
+
+
+// Texture coordinate data
+const GLfixed CImagicContainerBrowser::iGlobalTexCoords[] =
+   {
+   //bitmap has to be flipped over
+   0,       1<<16,
+   1<<16,   1<<16,
+   0,       0,
+   1<<16,   0
+   };
+     
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::ConstructL(const TRect& aRect)
+// EPOC two phased constructor
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::ConstructL(CImagicAppUi* aImagicAppUi, CImagicViewBrowser* aView, const TRect& /*aRect*/)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::ConstructL++"));
+    
+    iDisplayDrawFreq = KDisplayDrawFreq;
+    iUserInputGiven = EFalse;
+    iDeleteTextures = EFalse;
+    iLastEventFromKeys = EFalse;
+    
+    iImagicAppUi = aImagicAppUi;
+    iIEngine = iImagicAppUi->GetEngine();
+    iView = aView;
+    
+    iDrawGrid = CDrawGrid::NewL(this, iCurrentIndex);
+    iDrawOneByOne = CDrawOneByOne::NewL(this, iCurrentIndex);
+    iDrawFaceBrowsing = CDrawFaceBrowsing::NewL(this, iCurrentIndex);
+    
+
+#ifdef ADAPTIVE_FRAMERATE
+    iWaitDrawTicks = 0;
+#endif  
+    
+    //iPlayedWithDrag = EFalse;
+#ifdef HOLD_SELECTION_ONDRAG
+    iHoldSelection = EFalse;
+    iOneByOneSlideByDrag = EFalse;
+#endif
+#ifdef MOMENTUM_MOVE
+    iMomentumMove = EFalse;
+#endif
+#ifdef RD_FACEFRAME
+    //iDrawFaceFrame = EFalse;
+#endif
+    
+    // Create the native window
+    CreateWindowL();
+    // Take the whole screen into use
+    SetExtentToWholeScreen();
+    
+    // If the device supports touch, construct long tap detector
+    if ( AknLayoutUtils::PenEnabled() )
+        {
+        // Enable drag events listening
+        EnableDragEvents();
+        
+#ifdef USE_AVKON_LONGTAP_DETECTOR
+        // Enable long tap detection
+        iLongTapDetector = CAknLongTapDetector::NewL(this);
+        iLongTapDetector->SetTimeDelayBeforeAnimation(200000); // Delay before animation is set to 2 seconds in this example. Defualt is 0.15 seconds
+        iLongTapDetector->SetLongTapDelay(400000); // Long tap delay is set to 5 seconds in this example. Defualt is 0.8 seconds
+#endif
+#ifdef USE_AVKON_TACTILE_FEEDBACK
+        iTouchFeedBack = MTouchFeedback::Instance();
+        iTouchFeedBack->SetFeedbackEnabledForThisApp(ETrue);
+#endif
+        
+        iGesture = CGesture::NewL(this);
+//        iGesture->SetThresholdOfTap(10);            // tap must have movement with 10 pixels
+//        iGesture->SetThresholdOfMovement(50);       // experimental value on Ivalo
+//        iGesture->SetThresholdOfFastMove(100);      // fast move if > 100 pixel/100ms 
+//        iGesture->SetMonitoringTime(100000);        // 100ms
+        }
+    else
+        {
+#ifdef USE_AVKON_LONGTAP_DETECTOR
+        iLongTapDetector = NULL;
+#endif
+        iGesture = NULL;
+        }
+
+    //Activate view
+    ActivateL();
+    
+    //Create critical section
+    iDrawLock.CreateLocal();
+    
+    //Create an active object for animating the scene, keep priority high!
+    //EPriorityIdle, EPriorityLow, EPriorityStandard, EPriorityUserInput, EPriorityHigh
+    iPeriodic = CPeriodic::NewL( CActive::EPriorityUserInput);
+#ifdef USE_LOW_DRAW_SPEED_WHILE_LOADING
+    iPowerSavePeriodic = CPeriodic::NewL( CActive::EPriorityUserInput);//keep this high, othervice can not quarantee that draw freq drop is getting run time
+    iPowerSavePeriodic->Start(KPowerSavePeriodicDelay, KPowerSavePeriodicInterval, TCallBack( CImagicContainerBrowser::PowerSaveCallBack, this ) );
+#endif
+    
+    // Initialize OpenGL
+    InitAfterPowerSaveL();
+    
+    //Create texture loader
+    iTextureLoader = new (ELeave) CTextureLoader(iImagicAppUi, this, iView, &iDrawLock);
+    iTextureLoader->ConstructL();
+    
+    iTextureLoader->CreateIconTextures();		
+    
+    iDisplayRotation = 0;//Set initial display rotation to 0. This controls the whole display rotation, not single picture 
+    iDisplayRotationTarget = 0;//Set initial display rotation to 0
+    
+    iDrawFunction = EGrid;
+    iPreferHighResLoading = EFalse;
+    iDrawGrid->InitDrawGrid();
+    
+    //iSelector = CRemConInterfaceSelector::NewL();
+    //iTarget = CRemConCoreApiTarget::NewL( *iSelector, *this ); 
+    //iSelector->OpenTargetL();
+        
+    
+	//Create Draw utility class
+	iDrawUtility = CDrawUtility::NewL(this);
+	
+    DP0_IMAGIC(_L("CImagicContainerBrowser::ConstructL--"));
+    }
+    
+void CImagicContainerBrowser::InitAfterPowerSaveL()
+    {
+    OpenGLInitL();
+    InitL();
+    
+    iDrawOnes = 0;
+    // Load loading icon
+    iLoadingTextureIndex = 0;
+#ifdef EMPTY_IMAGE_AS_BMP    
+    CFbsBitmap loadingBitmap;
+    TInt error = loadingBitmap.Load(KLoadingFileName);
+    if (error == KErrNone)
+        {
+        iLoadingTextureIndex = iTextureLoader->CreateTexture(&loadingBitmap, EFalse);
+        }
+#endif    
+    
+#if 0
+    iExitTextureIndex = 0;
+    CFbsBitmap exitBitmap;
+    error = exitBitmap.Load(KExitFileName);
+    if (error == KErrNone)
+        {
+        iExitTextureIndex = iTextureLoader->CreateTexture(&exitBitmap, EFalse);
+        }
+    
+    iMenuTextureIndex = 0;
+    CFbsBitmap menuBitmap;
+    error = menuBitmap.Load(KMenuFileName);
+    if (error == KErrNone)
+        {
+        iMenuTextureIndex = iTextureLoader->CreateTexture(&menuBitmap, EFalse);
+        }
+#endif
+    
+#ifdef SHADOW_PHOTOS    
+    iShadowTextureIndex = 0;
+    CFbsBitmap shadowBitmap;
+    error = shadowBitmap.Load(KShadowFileName);
+    if (error == KErrNone)
+        {
+        iShadowTextureIndex = iTextureLoader->CreateTexture(&shadowBitmap, EFalse);        
+        }
+#endif    
+    
+    }
+
+void CImagicContainerBrowser::InitL()
+   {
+   DP0_IMAGIC(_L("CImagicContainerBrowser::GridDataInit++"));
+       
+#ifdef _ACCELEROMETER_SUPPORTED_
+    //iDeviceOrientation = TSensrvOrientationData::EOrientationDisplayRightUp;//Landscape
+    //iDeviceOrientation = TImagicDeviceOrientation::EOrientationDisplayRightUp;//Portrait
+    //iDeviceOrientation = 3;//EOrientationDisplayRightUp = Landscape
+    iDeviceOrientation = iIEngine->GetDeviceOrientation();
+#endif
+    
+    DP1_IMAGIC(_L("CImagicContainerBrowser::GridDataInit - Device orientation: %d"),iDeviceOrientation);
+    
+       iScreenImmeadetaUpdate = EFalse;
+    
+       iDrawNow = EFalse;
+       iDynamicLoadingOn = ETrue;
+       
+       iNewImageAdded = EFalse;
+       iPreferHighResLoading = EFalse;
+       
+       if(iImagicAppUi->GetImageIndex())
+           iCurrentIndex = iImagicAppUi->GetImageIndex();
+       else
+           iCurrentIndex = 0;
+       
+       //Read user settings from database <--------------------
+       
+       //Set default draw function
+       iDrawFunction = EGrid;
+              
+       //Init key data here
+       ResetKeyData();
+           
+       DP0_IMAGIC(_L("CImagicContainerBrowser::GridDataInit--"));
+   }
+
+
+
+void CImagicContainerBrowser::OpenGLInitL()
+   {
+   DP0_IMAGIC(_L("CImagicContainerBrowser::OpenGLInit++"));
+   
+       // Open GL hasn't been initialized
+       iOpenGlInitialized = EFalse;
+       
+       // Describes the format, type and size of the color buffers and
+       // ancillary buffers for EGLSurface
+       EGLConfig config;
+    
+       // Get the display for drawing graphics
+       iEglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
+       if ( iEglDisplay == NULL )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - eglGetDisplay failed - GL Error: %d"),glGetError());
+           _LIT(KGetDisplayFailed, "eglGetDisplay failed");
+           User::Panic( KGetDisplayFailed, 0 );
+           }
+       
+       // Initialize display
+       if ( eglInitialize( iEglDisplay, NULL, NULL ) == EGL_FALSE )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - eglInitialize failed - GL Error: %d"),glGetError());
+           _LIT(KInitializeFailed, "eglInitialize failed");
+           User::Panic( KInitializeFailed, 0 );
+           }
+    
+       // Pointer for EGLConfigs
+       EGLConfig *configList = NULL;
+       EGLint numOfConfigs   = 0;
+       EGLint configSize     = 0;
+    
+       // Get the number of possible EGLConfigs
+       if ( eglGetConfigs( iEglDisplay, configList, configSize, &numOfConfigs ) == EGL_FALSE )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - eglGetConfigs failed - GL Error: %d"),glGetError());
+           _LIT(KGetConfigsFailed, "eglGetConfigs failed");
+           User::Panic( KGetConfigsFailed, 0 );
+           }
+    
+       configSize = numOfConfigs;
+    
+       // Allocate memory for the configList
+       configList = (EGLConfig*) User::Alloc( sizeof(EGLConfig)*configSize );
+       if ( configList == NULL )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - config alloc failed - GL Error: %d"),glGetError());
+           _LIT(KConfigAllocFailed, "config alloc failed");
+           User::Panic( KConfigAllocFailed, 0 );
+           }
+    
+       // Define properties for the wanted EGLSurface. To get the best possible
+       // performance, choose an EGLConfig with a buffersize matching the current
+       // window's display mode
+       TDisplayMode DMode = Window().DisplayMode();
+       TInt BufferSize = 0;
+    
+       switch(DMode)
+       {
+       case(EColor4K):
+           BufferSize = 12;
+           break;
+       case(EColor64K):
+           BufferSize = 16;
+           break;
+       case(EColor16M):
+           BufferSize = 24;
+           break;
+       case(EColor16MU):
+       case(EColor16MA):
+           BufferSize = 32;
+           break;
+       default:
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - unsupported displaymode - GL Error: %d"),glGetError());
+           _LIT(KDModeError, "unsupported displaymode");
+           User::Panic( KDModeError, 0 );
+           break;
+       }
+       
+       // Define properties for the wanted EGLSurface
+       const EGLint attrib_list[] =
+           {
+           EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+           EGL_BUFFER_SIZE,  BufferSize,
+           EGL_DEPTH_SIZE,   16,
+           EGL_NONE
+           };
+
+
+       // No configs with antialising were found. Try to get the non-antialiased config
+       if ( eglChooseConfig( iEglDisplay, attrib_list, configList, configSize, &numOfConfigs ) == EGL_FALSE )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - eglChooseConfig failed - GL Error: %d"),glGetError());
+           _LIT( KChooseConfigFailed, "eglChooseConfig failed" );
+           User::Panic( KChooseConfigFailed, 0 );
+           }
+
+       if ( numOfConfigs == 0 )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - Can't find the requested config. - GL Error: %d"),glGetError());
+           // No configs found without antialiasing
+           _LIT( KNoConfig, "Can't find the requested config." );
+           User::Panic( KNoConfig, 0 );
+           }
+           
+       // Choose the best EGLConfig. EGLConfigs returned by eglChooseConfig are
+       // sorted so that the best matching EGLConfig is first in the list.
+       config = configList[0];
+    
+       // Free configList, as it's not used anymore.
+       User::Free( configList );
+    
+       // Create a window where the graphics are blitted
+       iEglSurface = eglCreateWindowSurface( iEglDisplay, config, &Window(), NULL );
+       if ( iEglSurface == NULL )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - eglCreateWindowSurface failed - GL Error: %d"),glGetError());
+           _LIT(KCreateWindowSurfaceFailed, "eglCreateWindowSurface failed");
+           User::Panic( KCreateWindowSurfaceFailed, 0 );
+           }
+    
+       // Create a rendering context
+       iEglContext = eglCreateContext( iEglDisplay, config, EGL_NO_CONTEXT, NULL );
+       if ( iEglContext == NULL )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - eglCreateContext failed - GL Error: %d"),glGetError());
+           _LIT(KCreateContextFailed, "eglCreateContext failed");
+           User::Panic( KCreateContextFailed, 0 );
+           }
+    
+       // Make the context current. Binds context to the current rendering thread
+       // and surface.
+       if ( eglMakeCurrent( iEglDisplay, iEglSurface, iEglSurface, iEglContext ) == EGL_FALSE )
+           {
+           DP1_IMAGIC(_L("CImagicContainerBrowser::ConstructL - eglMakeCurrent failed - GL Error: %d"),glGetError());
+           _LIT(KMakeCurrentFailed, "eglMakeCurrent failed");
+           User::Panic( KMakeCurrentFailed, 0 );
+           }
+       
+#ifdef SHADOW_PHOTOS        
+       glClearColor(1,1,1, 0);
+#else       
+       glClearColor(0,0,0, 0);
+#endif       
+       //glClearDepth(1.0f);                                 // Depth Buffer Setup
+       glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing
+       //glDisable(GL_DEPTH_TEST);                            // Enables Depth Testing
+       //glDepthMask(GL_FALSE);
+       glDepthFunc(GL_LEQUAL);                             // The Type Of Depth Testing To Do
+       // TODO,  check the perf gain
+       //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Really Nice Perspective Calculations
+       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);  // Fast Perspective Calculations
+       glShadeModel(GL_FLAT);//GL_FLAT ,GL_SMOOTH TODO, check perf if smooth is on
+       //glShadeModel(GL_SMOOTH);//GL_FLAT ,GL_SMOOTH TODO, check perf if smooth is on
+       //glDisable( GL_LINE_SMOOTH  );
+       //glEnable with the arguments GL_LINE_SMOOTH or GL_POINT_SMOOTH.
+       //glEnable(GL_POLYGON_SMOOTH);
+       //glEnable(GL_POINT_SMOOTH);
+       //glEnable( GL_LINE_SMOOTH  );
+       //glEnable(GL_MULTISAMPLE_ARB);
+       glEnable( GL_TEXTURE_2D  );
+       glDisable( GL_LIGHTING  );//disable for performance reasons
+       //Disable alpha blending
+       glDisable(GL_BLEND);
+       glDisable(GL_ALPHA_TEST);
+       
+       
+       //GLint params;
+       glGetIntegerv( GL_MAX_TEXTURE_SIZE, &iGLMaxRes );
+       DP1_IMAGIC(_L("CImagicContainerBrowser::OpenGLInit - OpenGL max image Res size: %d"), iGLMaxRes);
+       
+       glMatrixMode( GL_MODELVIEW );
+       
+       
+       iOpenGlInitialized = ETrue;
+       
+       //Start draw timer
+       DP0_IMAGIC(_L("CImagicContainerBrowser::OpenGLInit - Start Draw timer"));
+       iPeriodic->Start( 100, KDisplayDrawFreq, TCallBack( CImagicContainerBrowser::DrawCallBackL, this ) );
+       
+       DP0_IMAGIC(_L("CImagicContainerBrowser::OpenGLInit--"));
+   }
+
+//This is called when we want to reduce screen drawing
+TInt CImagicContainerBrowser::PowerSaveCallBack(TAny *aInstance)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::PowerSaveCallBack++"));
+    
+    ((CImagicContainerBrowser*) aInstance)->PowerSave();
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::PowerSaveCallBack--"));
+    return 0;
+    }
+
+    
+void CImagicContainerBrowser::PowerSave()
+    {
+    iPowerSavePeriodic->Cancel();
+    
+    if(iDisplayDrawFreq == KDisplayDrawFreq)
+        {
+#ifndef ADAPTIVE_FRAMERATE		
+        iDisplayDrawFreq = KPowerSaveDisplayDrawFreq;
+        DisableDisplayDraw();
+        if(iImagicAppUi->IsAppOnTop())
+            EnableDisplayDraw();
+#endif		
+        }
+    }
+
+TInt CImagicContainerBrowser::DisableDrawTimer( TAny* aInstance )
+   {
+   DP0_IMAGIC(_L("CImagicContainerBrowser::DisableDrawTimer++"));
+   
+   // Get pointer to instance
+   CImagicContainerBrowser* instance = (CImagicContainerBrowser*) aInstance;
+   //instance->iPeriodicTimerActive = EFalse;
+   instance->DisableDisplayDraw();
+   
+   DP0_IMAGIC(_L("CImagicContainerBrowser::DisableDrawTimer--"));
+   return 0;
+   }
+
+/*----------------------------------------------------------------------*/
+// Destructor
+CImagicContainerBrowser::~CImagicContainerBrowser()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::~CImagicContainerBrowser++"));
+    
+    //delete iPeriodic;
+    if(iPeriodic)
+        {
+        if(iPeriodic->IsActive())
+            iPeriodic->Cancel();
+            
+        delete iPeriodic;   
+        iPeriodic = NULL;
+        }
+        
+    delete iDrawUtility;
+    
+    //Cancelling CTimer...
+    if(iPowerSavePeriodic)
+        {
+        if(iPowerSavePeriodic->IsActive())
+            iPowerSavePeriodic->Cancel();
+            
+        delete iPowerSavePeriodic;   
+        iPowerSavePeriodic = NULL;
+        }
+        
+    DeleteTextures();
+    iDrawLock.Close();
+    
+    if(iTextureLoader)
+        {
+        delete iTextureLoader;
+        iTextureLoader = NULL;
+        }
+    
+    //iFloatCoordinates.Close();
+    
+#ifdef USE_AVKON_LONGTAP_DETECTOR
+    if(iLongTapDetector)
+        {
+        delete iLongTapDetector;
+        iLongTapDetector = NULL;
+        }
+#endif
+
+    if(iGesture)
+        {
+        delete iGesture;
+        iGesture = NULL;
+        }
+
+    //Destruct all engine components
+    iImagicAppUi->DestructEngine();
+    
+    delete iDrawGrid;
+    delete iDrawOneByOne;
+    delete iDrawFaceBrowsing;
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::~CImagicContainerBrowser--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// CTextureManager::DeleteTextures
+// Deletes named textures by calling glDeleteTextures.
+//
+void CImagicContainerBrowser::DeleteTextures()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DeleteTextures++"));
+
+    iIEngine->CancelFullSizeLoading();
+    
+    if(iPeriodic && iPeriodic->IsActive())
+        iPeriodic->Cancel();
+    
+    eglMakeCurrent( iEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
+    eglDestroySurface( iEglDisplay, iEglSurface );
+    eglDestroyContext( iEglDisplay, iEglContext );
+    eglTerminate( iEglDisplay );
+    
+    //Delete OpenGL memory allocations
+    TInt num = iIEngine->GetTotalNumOfImages();
+    for(TInt i=0; i < num; i++ )
+        {
+        CImageData* data = iIEngine->GetImageData(i);
+        
+        if(data->iGridData.iGlLQ128TextIndex)
+            glDeleteTextures( 1, &data->iGridData.iGlLQ128TextIndex );
+        if(data->iGridData.iGlLQ32TextIndex)
+            glDeleteTextures( 1, &data->iGridData.iGlLQ32TextIndex );
+        if(data->iGridData.iGlHQ512TextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlHQ512TextIndex);
+        if(data->iGridData.iGlSuperHQTextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlSuperHQTextIndex);
+        
+        data->iGridData.iGlLQ32TextIndex = 0;
+        data->iGridData.iGlLQ128TextIndex = 0;
+        data->iGridData.iGlHQ512TextIndex = 0;
+        data->iGridData.iGlSuperHQTextIndex = 0;
+        }
+       
+    iOpenGlInitialized = EFalse;
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DeleteTextures--"));
+    }
+
+/*
+//Prepares container to filename array swap
+void CImagicContainerBrowser::SwapArrays()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SwapArrays++"));
+    
+    //Delete OpenGL memory allocations
+    TInt num = iIEngine->GetTotalNumOfImages();
+    for(TInt i=0; i < num; i++ )
+        {
+        CImageData* data = iIEngine->GetImageData(i);
+        
+        if(data->iGridData.iGlLQ128TextIndex)
+            glDeleteTextures( 1, &data->iGridData.iGlLQ128TextIndex );
+        if(data->iGridData.iGlLQ32TextIndex)
+            glDeleteTextures( 1, &data->iGridData.iGlLQ32TextIndex );
+        if(data->iGridData.iGlHQ512TextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlHQ512TextIndex);
+        if(data->iGridData.iGlSuperHQTextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlSuperHQTextIndex);
+        
+        data->iGridData.iGlLQ32TextIndex = 0;
+        data->iGridData.iGlLQ128TextIndex = 0;
+        data->iGridData.iGlHQ512TextIndex = 0;
+        data->iGridData.iGlSuperHQTextIndex = 0;
+        }
+    
+    iOpenGlInitialized = EFalse;
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SwapArrays--"));
+    }
+*/
+
+void CImagicContainerBrowser::InitFaceBrowsing()
+    {
+    iDrawFaceBrowsing->InitFaceBrowsing();    
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Interpolates given value into target value with step
+//
+void CImagicContainerBrowser::Interpolate(float &aValue, const float aTarget, const float aStep)
+	{
+	//DP0_IMAGIC(_L("CImagicContainerBrowser::Interpolate"));
+	// Calculate new value
+	float diff = aTarget-aValue;
+//    aValue += diff * aStep * iTimeDiff * 30; 
+	float timediff = Min(0.1f, iTimeDiff); // so max value of timediff is 100tick (100ms)
+	aValue += diff * aStep * timediff * 30; 
+	
+	// Check that value is in range
+    if (aValue > aTarget && diff > 0)
+        aValue = aTarget;
+    if (aValue < aTarget && diff < 0)
+        aValue = aTarget;
+	}
+
+/*----------------------------------------------------------------------*/
+// Makes sure that given value is within limits
+//
+void CImagicContainerBrowser::CheckLimits(float &aValue, const float aMin, const float aMax)
+	{
+	DP0_IMAGIC(_L("CImagicContainerBrowser::CheckLimits"));
+	if (aValue < aMin)
+		aValue = aMin;
+	if (aValue > aMax)
+		aValue = aMax;
+	}
+
+/*----------------------------------------------------------------------*/
+// Handle rotation keys
+//
+void CImagicContainerBrowser::HandleRotationKeys(void)
+	{
+	//DP0_IMAGIC(_L("CImagicContainerBrowser::HandleRotationKeys"));
+	// Handle rotation
+	CImageData* imageData = iIEngine->GetImageData(iCurrentIndex);
+	if(imageData)
+	    imageData->iGridData.iTargetRotationAngle += iKeyData.iRotate*90;
+	iKeyData.iRotate = 0;
+	}
+
+
+TInt CImagicContainerBrowser::GetFreeRam()
+    {
+    TInt mem = 0;
+    TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+    DP1_IMAGIC(_L("CImagicContainerBrowser::CheckFreeRam - mem: %d"),mem);
+    return mem;
+    }
+
+            
+
+/*----------------------------------------------------------------------*/
+// Checks limits for iFileIndex and starts loading image when 
+// new image was selected
+//
+void CImagicContainerBrowser::DynamicLoadingL()
+    {
+    if(!iDynamicLoadingOn && !iNewImageAdded)
+        {
+        DP2_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL - return #Loading is off, iDynamicLoadingOn:%d, iNewImageAdded:%d"),iDynamicLoadingOn,iNewImageAdded);
+        return;
+        }
+
+    // Check that loader is not running
+    if(iTextureLoader->IsRunning())
+        {
+        DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL - return #Loader is running"));
+        
+/*        if(iIsLoaderRunning > 30)
+            {
+            DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL - return #Loader is running >30 times in loop"));
+            iIsLoaderRunning = 0;
+            iDynamicLoadingOn = EFalse;
+            iNewImageAdded = EFalse;
+            }
+        
+        iIsLoaderRunning++;*/
+        
+        return;
+        }
+    
+    if(iPreferHighResLoading)
+        {
+        DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL - return #Prefer High res loading"));
+        return;
+        }
+
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL++"));
+    
+    /*TInt imageBuffer = iIEngine->IsScanningFiles() ? 
+                        K128TNImageBuffer + KNumOf32ThumbsLoadedBefore128Thumb : 
+                        K32TNImageBuffer;*/
+    
+    TInt imageBuffer = K32TNImageBuffer; 
+    
+    //DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL load closest unloaded image"));
+   
+    for (TInt i = 0;i < imageBuffer; i++)
+        {
+        // Check to positive and negative direction from current picture
+        for (TInt j = 0; j < 2; j++)
+            {
+            // Calculate image index
+            TInt index = iCurrentIndex + (j ?  i : -i);
+            
+            // Check that index is valid
+            if (index >= 0 && index < iIEngine->GetTotalNumOfImages())
+                {
+                CImageData* imageData = iIEngine->GetImageData(index);
+                // Load tiny thumbnail
+                if( !imageData->iGridData.iCorrupted &&
+                    imageData->iGridData.iGlLQ32TextIndex == 0 &&
+                    (imageData->IsImageReady(ESize32x32) || 
+                     imageData->IsImageReady(EExifThumb)) //&& 
+                    //Abs(iCurrentIndex-index) <= K32TNImageBuffer
+                    )
+                    {
+                    TRAPD(err, iTextureLoader->LoadL(imageData, ESize32x32));
+                    if(err == KErrNone)
+                        {
+                        DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL - start loading 32x32"));
+                        i = imageBuffer + 1;
+                        iNewImageAdded = EFalse;//should be set off only when we tried to load new image
+                        break; //Image loading did start, break out
+                        }
+                    }
+                }
+    
+            // Load higher resolution thumb only after couple of tiny thumbs 
+            TInt i2 = i - KNumOf32ThumbsLoadedBefore128Thumb;
+            if (i2 < 0)
+                continue;
+                
+            // Calculate image index
+            index = iCurrentIndex + (j ? i2 : -i2);
+
+            // Check that index is valid
+            if (index < 0 || index >= iIEngine->GetTotalNumOfImages())
+                continue;
+
+            CImageData* imageData = iIEngine->GetImageData(index);
+            // Higher resolution thumbnail exist
+            if(!imageData->iGridData.iCorrupted &&
+               imageData->iGridData.iGlLQ128TextIndex == 0 &&
+                (imageData->IsImageReady(ESize128x128) || 
+                 imageData->IsImageReady(EExifThumb)) && 
+                Abs(iCurrentIndex-index) <= K128TNImageBuffer)
+                {
+                //Do not load 128 TN before tilted to flat
+                if(IsHwAcceleration() && Abs(iDrawGrid->GetCurrentGridTilt()) < KAngle2Start128LoadingHwAcc)
+                    {
+                    TRAPD(err, iTextureLoader->LoadL(imageData, ESize128x128));
+                    if(err == KErrNone)
+                        {
+                        DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL - start loading 128x128"));
+                        i = imageBuffer + 1;                        
+                        iNewImageAdded = EFalse;//should be set off only when we tried to load new image
+                        break; //Image loading did start, break out
+                        }
+                    }   
+                if(!IsHwAcceleration() && Abs(iDrawGrid->GetCurrentGridTilt()) < KAngle2Start128Loading)
+                    {
+                    TRAPD(err, iTextureLoader->LoadL(imageData, ESize128x128));
+                    if(err == KErrNone)
+                        {
+                        DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL - start loading 128x128"));
+                        i = imageBuffer + 1;                        
+                        iNewImageAdded = EFalse;//should be set off only when we tried to load new image
+                        break; //Image loading did start, break out
+                        }
+                    }
+                }
+            }
+        }
+    
+    iNewImageAdded = EFalse;
+    
+    // Wait until something new happen before continue loading
+    iDynamicLoadingOn = iIEngine->IsScanningFiles();
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicLoadingL--"));
+    }
+
+void CImagicContainerBrowser::NewImageAdded()
+    {
+    iNewImageAdded = ETrue;    
+    }
+
+void CImagicContainerBrowser::ImageListChanged(TInt aIndex, TBool aAdded)
+    {
+    if (iDrawGrid)
+        iDrawGrid->UpdateImageCoordinates(aIndex);
+    
+    if (IsUserInputGiven())
+        {
+        /* TODO if (iCurrentIndex >= aIndex) 
+            {
+            if (aAdded)
+                iCurrentIndex++;
+            else 
+                iCurrentIndex--;
+            CheckIndexLimits(iCurrentIndex);
+            }*/
+        }
+    iDynamicLoadingOn = ETrue;
+    }
+
+/*----------------------------------------------------------------------*/
+// Unloads images from Grid
+//
+void CImagicContainerBrowser::DynamicUnLoading()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicUnLoading++"));
+    
+    CImageData* imageData = NULL;
+    
+    // Loop through all pictures
+    for (TInt i=0; i<iIEngine->GetTotalNumOfImages(); i++)
+        {
+        // Check if picture is loaded
+        imageData = iIEngine->GetImageData(i);
+
+        if(imageData->iGridData.iGlLQ32TextIndex!=0)
+            if(i<(iCurrentIndex-(K32TNImageUnLoadBuffer+1)) || i>(iCurrentIndex+(K32TNImageUnLoadBuffer+1)))
+                {
+                // Unload picture
+                iTextureLoader->UnloadLQ32Tex( imageData );
+                DP1_IMAGIC(_L("CImagicContainerBrowser::DynamicUnLoading - Unload 32x32 [%d] texture!!!!!"),i);
+                }
+        if(imageData->iGridData.iGlLQ128TextIndex != 0)
+            if(i<(iCurrentIndex-(K128TNImageBuffer+1)) || i>(iCurrentIndex+(K128TNImageBuffer+1)))
+                {
+                // Unload picture
+                iTextureLoader->UnloadLQ128Tex( imageData );
+                DP1_IMAGIC(_L("CImagicContainerBrowser::DynamicUnLoading - Unload 128x128 [%d] texture!!!!!"),i);
+                }
+        if(imageData->iGridData.iGlHQ512TextIndex != 0 )
+            if((i < (iCurrentIndex-(K512TNImageBuffer+1))) || (i > (iCurrentIndex+(K512TNImageBuffer+1))))
+                {
+                //Unload picture
+                iTextureLoader->UnloadLQ512Tex( imageData );
+                DP1_IMAGIC(_L("CImagicContainerBrowser::DynamicUnLoading - Unload 512x512 [%d] texture!!!!!"),i);
+                }
+                
+        if(imageData->iGridData.iGlSuperHQTextIndex != 0)
+            if(i != iCurrentIndex)
+                {
+                //Unload picture
+                iTextureLoader->ReleaseSuperHResTexture( imageData );
+                DP1_IMAGIC(_L("CImagicContainerBrowser::DynamicUnLoading - Unload Superresolution [%d] texture!!!!!"),i);
+                }
+        }
+        
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DynamicUnLoading--"));
+    }
+
+            
+/*----------------------------------------------------------------------*/
+// Calculates widht and height with aspect ratio
+//
+#if 0
+void CImagicContainerBrowser::BubbleEffect(TInt& x, TInt& y, float& z)
+    {
+    if(iBubbleEffect)
+        {
+        // Selected image in coordinates x,y
+        iSelectedX = iCurrentIndex/iGridSizeY;
+        iSelectedY =- (iCurrentIndex%iGridSizeY);
+                    
+        // Distance to selected
+        iDistanceX = iSelectedX-x;
+        iDistanceY = iSelectedY-y;
+        // Squared
+        if(iDistanceX<0) iDistanceX*= -1;
+        if(iDistanceY<0) iDistanceY*= -1;
+        
+        // Distance
+        iDiff=iDistanceX+iDistanceY;
+        // Convert distance to depth
+        // http://en.wikipedia.org/wiki/Gaussian_function
+        /*
+        if (iDiff==0) z=4.2;
+        if (iDiff==1) z=3.973029769;
+        if (iDiff==2) z=3.363097092;
+        if (iDiff==3) z=2.547428771;
+        if (iDiff==4) z=1.72667162;
+        if (iDiff==5) z=1.047279277;
+        if (iDiff==6) z=0.56840819;
+        if (iDiff==7) z=0.27605982;
+        if (iDiff==8) z=0.119975103;
+        if (iDiff==9) z=0.046657785;
+        if (iDiff==10) z=0.016236865;
+        if (iDiff>10) z=0;
+        */
+        if (iDiff==0) z=5.0;
+        if (iDiff==1) z=4.2;
+        if (iDiff==2) z=3.4;
+        if (iDiff==3) z=2.1;
+        if (iDiff==4) z=1.3;
+        if (iDiff==5) z=0.8;
+        if (iDiff==6) z=0.4;
+        if (iDiff==7) z=0.3;
+        if (iDiff>7) z=0.3;
+        //if (iDiff==8) z=0.1;
+        //if (iDiff==9) z=0.05;
+        //if (iDiff==10) z=0.01;
+        //if (iDiff>10) z=0;
+        }
+    }
+#endif
+
+/*----------------------------------------------------------------------*/
+// Calculates widht and height with aspect ratio
+//
+void CImagicContainerBrowser::CalculateImageSize(float& aWidth, float& aHeight, const float aAspectRatio/*display aspectratio*/)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::CalculateImageSize"));
+	// Check picture orientation
+    TBool landscape = EFalse;
+    TBool tmp = EFalse;
+    CImageData* imageData = iIEngine->GetImageData(iCurrentIndex);
+    
+    if(imageData->GetAspectRatio() > 1)
+        landscape = ETrue;
+    
+	//Change landscape<->portrait if pic is rotated 90 or 270
+    //if(imageData->iGridData.iTargetRotationAngle%90==0 && imageData->iGridData.iTargetRotationAngle%180!=0)
+    //if(Abs(imageData->iGridData.iTargetRotationAngle-90) <= 0.1 && Abs(imageData->iGridData.iTargetRotationAngle-270) <= 0.1)
+    TInt angle = imageData->iGridData.iTargetRotationAngle;
+    if(angle % 90 == 0 && angle % 180 != 0)
+        {
+        tmp=ETrue;
+        landscape = !landscape;
+        }
+    
+	//Calculate new width and height
+    aWidth=0.5;
+    aHeight=0.5;
+
+    if(landscape)
+        {
+        //Fix aspect ratio
+        aHeight/=aAspectRatio;
+        if(imageData->GetAspectRatio() < aAspectRatio && imageData->GetAspectRatio() >= 1)
+            {
+            aHeight = aHeight * (aAspectRatio/imageData->GetAspectRatio());
+            aWidth = aWidth * (aAspectRatio/imageData->GetAspectRatio());
+            }
+        //If portrait picture aspect ratio is between 0.75 - 1 
+        if(imageData->GetAspectRatio() > (1.0 / aAspectRatio) && imageData->GetAspectRatio() < 1)
+            {
+            aHeight = aHeight * (aAspectRatio*imageData->GetAspectRatio());
+            aWidth = aWidth * (aAspectRatio*imageData->GetAspectRatio());
+            }
+        }
+    else
+        {
+        //Fix aspect ratio
+        aWidth *= aAspectRatio;
+        }
+}
+
+
+
+/*----------------------------------------------------------------------*/
+// Draws one by one view
+//
+void CImagicContainerBrowser::GetCurrentFilenameL(TFileName& aFilename, TThumbSize aRes)
+    {
+    iIEngine->GetFileNameL(iCurrentIndex, aRes, aFilename);
+    }
+
+void CImagicContainerBrowser::SetCurrentFaceNro(TInt aNro)
+    {
+    iDrawFaceBrowsing->SetCurrentFaceNro(aNro);
+    }
+
+#if 0
+/*----------------------------------------------------------------------*/
+// Gets current screen coords
+//
+void CImagicContainerBrowser::ConvertScreenCoords2QvgaCoords(TPoint& aPoint, TRect& aRect)
+    {
+    CImageData* imageData = iIEngine->GetImageData(iCurrentIndex);
+    
+    TInt pictureWidth, pictureHeigth;
+    pictureWidth=320;
+    pictureHeigth=320;
+    
+    //Calculate coords from alogorith to OpenGL -0.5 - +0.5 coords and fill the array
+    float tmpX;
+    float tmpY;
+    if(imageData->GetAspectRatio() > 1)
+        {
+        //Convert from center of screen to corner coords
+        tmpX = iDrawOneByOne->GetDrawOneByOneXY().iX + 0.5;
+        tmpY = iDrawOneByOne->GetDrawOneByOneXY().iY + (0.5/imageData->GetAspectRatio());
+        }
+    else//portrait
+        {
+        //Convert from center of screen to corner coords
+        tmpX = iDrawOneByOne->GetDrawOneByOneXY().iX + (0.5*imageData->GetAspectRatio());
+        tmpY = iDrawOneByOne->GetDrawOneByOneXY().iY + 0.5;
+        }
+    
+    aPoint.iX = tmpX * pictureWidth;
+    aPoint.iY = tmpY * pictureHeigth;
+            
+    TInt rectWidth = pictureWidth;
+    TInt rectHeigth = pictureHeigth;
+    
+    rectWidth = rectWidth/(iDrawOneByOne->GetDrawOneByOneZoom()*2);
+    rectHeigth = rectHeigth/(iDrawOneByOne->GetDrawOneByOneZoom()*2);
+    
+    aRect.iTl.iX = aPoint.iX-(rectWidth/2); 
+    aRect.iTl.iY = aPoint.iY-(rectHeigth/2);
+    aRect.iBr.iX = aPoint.iX+(rectWidth/2); 
+    aRect.iBr.iY = aPoint.iY+(rectHeigth/2);
+    
+    }
+#endif
+
+void CImagicContainerBrowser::LoadHighResImage(CImageData* imageData, TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::LoadHighResImage++"));
+    
+    //Make sure that 512 for current image is loaded
+    if(imageData->iGridData.iGlHQ512TextIndex == 0)
+        {
+        LoadHQ512Image(imageData, aIndex);
+        return;
+        }
+        
+#ifdef SUPERZOOM
+    //Load "super zoom" image if in zoom or face browser
+    if(imageData->iGridData.iGlSuperHQTextIndex == 0 && 
+       (!IS_NOT_IN_ZOOM_ONEBYONE || iDrawOneByOne->IsMagGlassOn() ))
+        {
+        //iPreferHighResLoading = ETrue;
+        TRAPD(err, iTextureLoader->LoadL(imageData, EFullSize));
+        if( err == KErrNone || err == KErrInUse )
+            iPreferHighResLoading = ETrue;
+        
+        /*if(err != KErrNone)
+            if(err == KErrAlreadyExists || err == KErrInUse)
+                iPreferHighResLoading = ETrue;
+            else
+                iPreferHighResLoading = EFalse;*/
+        }
+#endif
+
+    CImageData* imageDataLoad = NULL;
+    //Here we load 512x512 resolution images, one to both sides of current up to limit
+    for (TInt i = 1; i <= K512TNImageBuffer; i++)
+        {
+        // Check to positive and negative direction from current picture
+        for (TInt j = 0; j < 2; j++)
+            {
+            // Calculate image index
+            TInt index = iCurrentIndex + (j ?  i : -i);
+            
+            if(index >= 0 && index < iIEngine->GetTotalNumOfImages())
+                {
+                imageDataLoad = iIEngine->GetImageData(index);
+                if(imageDataLoad == NULL)
+                    break;
+                
+                if(imageDataLoad->iGridData.iGlHQ512TextIndex == 0)
+                    {
+                    DP1_IMAGIC(_L("CImagicContainerBrowser::LoadHighResImage -------------- Start High res image loading, index: %d"), index);
+                    LoadHQ512Image(imageDataLoad, index);
+                    return;
+                    }
+                    
+                }
+            }
+        }
+            
+        
+    DP0_IMAGIC(_L("CImagicContainerBrowser::LoadHighResImage--"));
+    }
+
+
+void CImagicContainerBrowser::LoadHQ512Image(CImageData* imageData, TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::LoadHQ512Image++"));
+    
+    //iPreferHighResLoading = ETrue;
+    
+    if(/*iDrawOneByOne->GetDrawOneByOneZoom() > 0.99 &&*/ imageData)
+        {
+        TInt error;
+        if((imageData->iGridData.iGlLQ128TextIndex == 0) && (iCurrentIndex == aIndex))
+            TRAPD(error, iTextureLoader->LoadL(imageData, ESize128x128));
+        
+        if(imageData->iGridData.iGlHQ512TextIndex == 0)
+            {
+            //iPreferHighResLoading = ETrue;
+            TRAPD(err, iTextureLoader->LoadL(imageData, ESize512x512));
+/*            if(err != KErrNone)
+                if(err == KErrAlreadyExists || err == KErrInUse)
+                    iPreferHighResLoading = ETrue;
+                else
+                    iPreferHighResLoading = EFalse;*/
+            
+            if( err == KErrNone || err == KErrInUse )
+                {
+                DP0_IMAGIC(_L("CImagicContainerBrowser::LoadHQ512Image - set dyn loading off"));
+                iPreferHighResLoading = ETrue;
+                iDynamicLoadingOn = EFalse; //set to false to be able to get run time for high res loading
+                }
+            else if(err == KErrAlreadyExists)
+                {
+                DP0_IMAGIC(_L("CImagicContainerBrowser::LoadHQ512Image - set dyn loading on"));
+                iDynamicLoadingOn = ETrue;
+                }
+            }
+
+        }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::LoadHQ512Image--"));
+    }
+    
+	
+void CImagicContainerBrowser::ShowMagGlass(const TBool aState)
+    {
+    // do nothing if it's already in the state
+    if (/*iMagGlassOn*/ iDrawOneByOne->IsMagGlassOn() == aState || !IS_NOT_IN_ZOOM_ONEBYONE)
+        return;
+
+    iDrawOneByOne->SetMagGlassPrevStatus(iDrawOneByOne->IsMagGlassOn());
+    iDrawOneByOne->SetMagGlassStatus(aState);
+    }
+
+
+
+void CImagicContainerBrowser::SetMinMagFilterLinear(TBool aValue)
+    {
+    if(iDrawFunction == EOneByOne || iDrawFunction == EFaceBrowsing)
+        if(IsHwAcceleration())
+            iMinMagFilterSetting=ETrue;
+        else
+            iMinMagFilterSetting=aValue;
+    else
+        iMinMagFilterSetting=aValue;
+    }
+
+TBool CImagicContainerBrowser::IsHwAcceleration()
+    {
+    return (iGLMaxRes == 2048)? ETrue: EFalse;
+    }
+
+void CImagicContainerBrowser::SetMinMagFilterLinearDo(TBool aValue)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetMinMagFilterLinear++"));
+    
+    CImageData* imageData = iIEngine->GetImageData(iCurrentIndex);
+    
+    if(iCurrentBindedIndex == imageData->iGridData.iGlLQ128TextIndex || 
+       iCurrentBindedIndex == imageData->iGridData.iGlLQ32TextIndex)
+        {
+        DP0_IMAGIC(_L("CImagicContainerBrowser::SetMagFilterLinear - Linear"));
+        iMagFilterLinear = ETrue;
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        }
+    else if(aValue)
+        {
+        DP0_IMAGIC(_L("CImagicContainerBrowser::SetMagFilterLinear - Linear"));
+        iMagFilterLinear = ETrue;
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        }
+    else
+        {
+        DP0_IMAGIC(_L("CImagicContainerBrowser::SetMagFilterLinear - Nearest"));
+        iMagFilterLinear = EFalse;
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        }
+    
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    
+    
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetMinMagFilterLinear--"));
+    }
+
+void CImagicContainerBrowser::DrawFaceBrowsingIcon()
+    {
+#ifdef ICONS_ENABLAD
+    if((!iMagGlassOn && iDrawFunction==EFaceBrowser) || 
+       (iDrawFunction==EFaceBrowser) && (iIconTextureIndexes.Count() >= 1))
+        {
+        iDrawUtility->DrawIcon(Size(), iIconTextureIndexes[0]);
+        SetMinMagFilterLinearDo(ETrue);
+        }
+#endif
+    }
+
+void CImagicContainerBrowser::DrawZoomIcon()
+    {
+#ifdef ICONS_ENABLAD
+    if((!iMagGlassOn && iDrawFunction==EOneByOne && (iDrawOneByOneZoom-1.0) > 0.01) && 
+       (iIconTextureIndexes.Count()>=2))
+        {
+        iDrawUtility->DrawIcon(Size(), iIconTextureIndexes[1]);
+        SetMinMagFilterLinearDo(ETrue);
+        }
+#endif
+    }
+
+void CImagicContainerBrowser::SetDeleteTextures(TBool aValue)
+    {
+    DeleteTextures();
+    iDeleteTextures = aValue;    
+    }
+
+
+
+//---------------------------------------------------------------------------------	
+//DrawCallBack for OpenGL
+TInt CImagicContainerBrowser::DrawCallBackL( TAny* aInstance )
+    {
+    //DP0_IMAGIC(_L("CImagicContainerBrowser::DrawCallBack"));
+	// Get pointer to instance
+    ((CImagicContainerBrowser*) aInstance)->DrawL();
+    return 0;
+    }
+    
+void CImagicContainerBrowser::DrawL()
+    {
+#ifdef ADAPTIVE_FRAMERATE
+    // No drawing if timer is not zero
+    if (iWaitDrawTicks != 0)
+        {
+        if (iWaitDrawTicks > 0)
+            iWaitDrawTicks--;    
+        return;
+        }
+    
+    iWaitDrawTicks = -1;
+    
+    //TInt startTick =
+#endif        
+
+    
+    
+    if(iDeleteTextures)
+        {
+        if(iPeriodic->IsActive())
+            iPeriodic->Cancel();
+        DeleteTextures();
+        
+        return;
+        }
+    
+    
+    TSize size = Size();    
+    BeginDrawing();
+
+    
+    
+    if(!iScreenRotateOngoing)
+        {
+        
+        // Call proper draw function
+        switch (iDrawFunction)
+            {
+            case EGrid:
+                
+                if(iIEngine->IsScanningFiles())
+                    {
+                    if(iDrawOnes == 0)
+                        iDrawOnes = 1;//make sure we draw screen ones when start application
+                    }
+#if 0
+                if(iDynamicLoadingOn)
+                    {
+                    DP0_IMAGIC(_L("CImagicContainerBrowser::DrawCallBack - Continue Image Loading"));
+                    DynamicLoadingL();
+                    }
+                
+#endif           
+                                
+                if(iDrawGrid->IsDrawingNeededGrid() || iDrawOnes == 1)
+                    {
+                    drawZoom = 1; inPictureX = 0; inPictureY = 0;
+                    iDrawGrid->DrawGridL(size);
+                    EndDrawing();
+                    if(iIEngine->GetTotalNumOfImages() > 0)
+                        iDrawOnes = -1;
+                    }
+                
+                break;
+            
+            case EOneByOne:
+                if(iDrawOneByOne->IsDrawingNeededOneByOne())
+                    {
+                    iDrawOneByOne->DrawOnebyOneL(size);
+                    EndDrawing();
+                    }
+                break;
+            
+            case EFaceBrowser:
+                if(iDrawFaceBrowsing->IsDrawingNeededFaceBrowsing())
+                    {
+                    iDrawFaceBrowsing->DrawFaceBrowsing(size);
+                    drawZoom = 1; inPictureX = 0; inPictureY = 0;
+                    iDrawFaceBrowsing->GetFBZoomAndLocation(drawZoom, inPictureX, inPictureY);
+                    EndDrawing();
+                    }
+                break;
+            
+            default:
+                // Should never come here
+                break;
+            }
+        }
+
+#ifdef ADAPTIVE_FRAMERATE    
+    iWaitDrawTicks = KWaitTicksAfterDraw;    // wait 20ms
+#endif    
+    }
+
+void CImagicContainerBrowser::BeginDrawing()
+    {
+    // Calculate used time between two frames
+    iTimeNow = User::NTickCount();
+
+#ifdef __WINS__
+    // In the emulator the tickcount runs at 200Hz
+    iTimeDiff = (GLfloat)(iTimeNow - iLastTime)/200;
+    iLastTime = iTimeNow;
+#else    
+    // In the HW the tickcount runs at 1000Hz
+    iTimeDiff = (GLfloat)(iTimeNow - iLastTime)/1000;
+    iLastTime = iTimeNow;
+#endif
+    
+    //Prevent screen draw while rotating screen
+    //if(!iScreenRotateOngoing)
+        {
+        // Get window size
+        //aSize = Size();    
+        
+        // Enable client state
+        glEnableClientState(GL_VERTEX_ARRAY);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glTexCoordPointer( 2, GL_FIXED, 0, iGlobalTexCoords );
+        }
+        
+    }
+    
+void CImagicContainerBrowser::EndDrawing()
+    {
+#ifdef LOADING_ANIMATION
+    // Handle loading animation
+    glColor4f(1,1,1,1);
+    iDrawUtility->Update();
+    iDrawUtility->Draw(Size());
+    
+    TBool tmp = iMagFilterLinear;
+    iMagFilterLinear = ETrue;
+
+
+    DrawFaceBrowsingIcon();
+    DrawZoomIcon();
+
+    iMagFilterLinear = tmp;
+#endif
+
+    /*iMenuAlpha-=0.05;
+    if(iMenuAlpha < 0)
+        iMenuAlpha = 0;
+    iDrawUtility->DrawIcon2(Size(), iLoadingTextureIndex, iMenuAlpha);*/
+    
+    
+    //Prevent screen draw while rotating screen
+    //if(!iScreenRotateOngoing)
+        {
+        // Disable client state
+        glDisableClientState(GL_VERTEX_ARRAY);
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    
+        
+        // Call eglSwapBuffers, which blit the graphics to the window
+        if( !eglSwapBuffers( iEglDisplay, iEglSurface ) )
+            {
+            _LIT(KTextOpenGlError, "ERROR in OpenGL draw: eglSwapBuffers error");
+            CAknErrorNote* note = new ( ELeave ) CAknErrorNote(ETrue);
+            TBuf<256> text;
+            text.Format(KTextOpenGlError);
+            note->ExecuteLD( text );
+            
+            //suspend or some other power event occurred, context lost
+            OpenGLInitL(); /* reinitialize EGL */
+        
+            InitL(); /* reinitialize grid data */
+            iDrawFunction = EGrid;
+            }
+        
+        // Check for errors
+        //EGLint err = eglGetError();
+        EGLint err = glGetError();
+        //err=EGL_CONTEXT_LOST;
+        //if(err != EGL_SUCCESS)
+        TBool init = EFalse;
+        //while(err != EGL_SUCCESS)GL_NO_ERROR
+        while(err != GL_NO_ERROR)
+            {
+            /*_LIT(KTextOpenGlError, "ERROR in OpenGL draw: %d");
+            CAknErrorNote* note = new ( ELeave ) CAknErrorNote(ETrue);
+            TBuf<256> text;
+            text.Format(KTextOpenGlError, err);
+            note->ExecuteLD( text );*/
+            
+            //suspend or some other power event occurred, context lost
+            /*DeleteTextures();
+            OpenGLInitL();
+            InitL();*/
+            iDrawFunction = EGrid;
+            err = glGetError();
+            init = ETrue;
+            }
+        
+        if(init)
+            {
+            DeleteTextures();
+            OpenGLInitL(); /* reinitialize EGL */
+            InitL(); /* reinitialize grid data */
+            }
+    
+        // Clear buffers
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        }
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::SizeChanged()
+// Called by framework when the view size is changed
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::SizeChanged()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SizeChanged"));
+    
+    iScreenRotateOngoing = ETrue;
+    //TSize size = this->Size();
+    iScreenSize = this->Size();
+    iScreenAspectRatio = (TReal)iScreenSize.iWidth / (TReal)iScreenSize.iHeight;
+    
+    // Reinitialize viewport and projection.
+    glViewport( 0, 0, iScreenSize.iWidth, iScreenSize.iHeight );
+    
+    if(iScreenSize.iHeight > iScreenSize.iWidth)
+        {//Portrait
+        iDisplayRotation = -90;
+        iDisplayRotationTarget = 0;
+        }
+    else
+        {//Landscape
+        iDisplayRotation = 90;
+        }
+    
+    iScreenRotateOngoing = EFalse;
+    
+    iDrawNow = ETrue;
+    
+    }
+
+float CImagicContainerBrowser::GetDisplayRotTargetAngle()
+    {
+    return iDisplayRotationTarget;
+    }
+
+float CImagicContainerBrowser::GetDisplayRotAngle()
+    {
+    return iDisplayRotation;
+    }
+
+void CImagicContainerBrowser::SetDisplayRotAngle(float aValue)
+    {
+    iDisplayRotationTarget = aValue;
+    }
+
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::CountComponentControls() const
+// ---------------------------------------------------------
+//
+TInt CImagicContainerBrowser::CountComponentControls() const
+    {
+    return 0; // return nbr of controls inside this container
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::ComponentControl(TInt aIndex) const
+// ---------------------------------------------------------
+//
+CCoeControl* CImagicContainerBrowser::ComponentControl(TInt /*aIndex*/) const
+    {
+   
+    return NULL;
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::Draw(const TRect& aRect) const
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::Draw(const TRect& /*aRect*/) const
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::Draw"));
+
+    CImagicContainerBrowser* self=const_cast<CImagicContainerBrowser*>(this);
+    self->iDrawNow = ETrue;
+    
+    /*if(iScreenImmeadetaUpdate)
+        self->DrawL();*/
+    }
+
+void CImagicContainerBrowser::SetScreenImmeadetaUpdate(TBool aValue)
+    {
+    iScreenImmeadetaUpdate = aValue;    
+    }
+
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::HandleControlEventL(
+//     CCoeControl* aControl,TCoeEvent aEventType)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent /*aEventType*/)
+    {
+    // Add your control event handler code here
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::HandlePointerEventL(
+//     const TPointerEvent& aPointerEvent)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandlePointerEventL++"));
+
+    EnableDisplayDraw();
+    
+    //Set normal display draw speed if we were in low draw freq
+#ifdef USE_LOW_DRAW_SPEED_WHILE_LOADING
+    SetDrawFreqToNormal(KPowerSavePeriodicDelay);
+#endif
+    
+    iUserInputGiven = ETrue;
+    iLastEventFromKeys = EFalse;
+    iOnTheEdge=ETrue;
+            
+    /* Lets not put this on, othervise does not work in S60 3.2
+    // Do nothing if non-touch
+    if (!AknLayoutUtils::PenEnabled() )
+        {
+        return;
+        }
+*/
+
+#ifdef USE_AVKON_LONGTAP_DETECTOR
+    // Pass the pointer event to Long tap detector component
+    iLongTapDetector->PointerEventL(aPointerEvent);
+#endif
+
+#ifdef USE_AVKON_TACTILE_FEEDBACK
+    if (aPointerEvent.iType == TPointerEvent::EButton1Down)
+            {
+            // Give feedback to user (vibration)
+            iTouchFeedBack->InstantFeedback(ETouchFeedbackBasic);
+            }
+#endif
+    
+    if ( AknLayoutUtils::PenEnabled() )
+        {
+        iGesture->PointerEventL(aPointerEvent);
+        }
+
+    // Call base class HandlePointerEventL()
+    CCoeControl::HandlePointerEventL(aPointerEvent);
+
+    SetLastTouchPoint(aPointerEvent.iPosition);
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandlePointerEventL--"));
+    }
+
+void CImagicContainerBrowser::SetLastTouchPoint(const TPoint& aPos)
+    {
+
+    iTouchPointThreshold = EFalse;
+    
+    if(Abs(aPos.iX-iLastTouchPoint.iX) > 2)//TODO, mika: check correct size
+        {
+        iTouchPointThreshold = ETrue;
+        }
+    if(Abs(aPos.iY-iLastTouchPoint.iY) > 2)
+        {
+        iTouchPointThreshold = ETrue;
+        }
+    
+    //Change touch point only if we moved more than 5 pixel
+    //if(changeTouchPoint)
+        iLastTouchPoint = aPos;
+    }
+
+TBool CImagicContainerBrowser::IsTouchPointThresholdExeed()
+    {
+    return iTouchPointThreshold;
+    }
+
+TPoint CImagicContainerBrowser::GetLastTouchPoint(void)
+    {
+    return iLastTouchPoint;
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::HandleLongTapEventL(
+//     const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::HandleLongTapEventL(const TPoint& /*aPenEventLocation*/, 
+                                                  const TPoint& /*aPenEventScreenLocation*/)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandleLongTapEventL++"));
+    
+    //THIS FUNCTION IS NOT USED, USE INSTEAD DoLongTap() TO HANDLE LONG TAP EVENTS!!!
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandleLongTapEventL--"));
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::FindImageInScreen(
+//     const TPoint aPos, TInt& aResultIndex)
+// ---------------------------------------------------------
+//
+TBool CImagicContainerBrowser::FindImageInScreen(const TPoint aPos, TInt& aResultIndex)
+    {
+    GLfloat modelview[16];
+    glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
+
+    GLfloat projection[16];
+    glGetFloatv(GL_PROJECTION_MATRIX, projection);
+
+    int viewport[4];
+    glGetIntegerv(GL_VIEWPORT, viewport);
+
+    GLfloat x = aPos.iX;
+    GLfloat y = this->Size().iHeight - 1 - aPos.iY;
+    GLfloat objX[2], objY[2], objZ[2]; // [0] for near, [1] for far
+
+    // Get coords in near and far plane. The coords give the ray from near to far plane.
+    gluUnProject(x,y,0.0,modelview,projection,viewport,&objX[0],&objY[0],&objZ[0]);
+    gluUnProject(x,y,1.0,modelview,projection,viewport,&objX[1],&objY[1],&objZ[1]);
+
+    DP3_IMAGIC(_L("####### UnProject(z=0, near):X=%6.4f,Y=%6.4f,Z=%6.4f"), objX[0],objY[0],objZ[0]);
+    DP3_IMAGIC(_L("####### UnProject(z=1.0,far):X=%6.4f,Y=%6.4f,Z=%6.4f"), objX[1],objY[1],objZ[1]);
+    DP3_IMAGIC(_L("####### Device (%d):x=%6.3f,y=%6.3f,z=not known"), iCurrentIndex, x,y);
+    DP3_IMAGIC(_L("####### Current(%d):x=%6.4f,y=%6.4f"),iCurrentIndex, (iCurrentIndex / CImagicContainerBrowser::KGridSizeY) * KSpacingX, -(iCurrentIndex % CImagicContainerBrowser::KGridSizeY) * KSpacingY);
+
+    GLfloat perspectiveDepth = objZ[0] - objZ[1]; // near value is bigger. depth = near - far.
+
+    aResultIndex = -1; // gives invalid value if not found
+
+    // The ray is linear. Can get xy at a depth by multiply '(a depth)/(near/far depth)'
+    TInt numOfImages = iIEngine->GetTotalNumOfImages();
+    for (TInt i = 0; i < numOfImages; ++i)
+        {
+        GLfloat itemZ = iIEngine->GetImageData(i)->iGridData.iZ;
+        GLfloat itemDepthCoord = -itemZ - iDrawGrid->GetGridZoom(); // -  objZ[0]; // camera shifted by iDrawGridZoom. perspective starts from near.
+        GLfloat itemDepth = itemDepthCoord / perspectiveDepth;
+
+        GLfloat itemX = objX[0] + itemDepth * (objX[1] - objX[0]); // = near + u(far - near)
+        GLfloat itemY = objY[0] + itemDepth * (objY[1] - objY[0]); // = near + u(far - near)
+
+        CImageData* imageData = iIEngine->GetImageData(i);
+        GLfloat itemScale = imageData->iGridData.iScale;
+    
+        GLfloat width  = KSpacingX; // * itemScale; // TODO: check!. No need to consider scaling. Why?
+        GLfloat height = KSpacingY; // * itemScale;
+        GLfloat objx = imageData->iGridData.iX;
+        GLfloat objy = imageData->iGridData.iY;
+        //GLfloat objx =  (i / CImagicContainerBrowser::KGridSizeY) * width;
+        //GLfloat objy = -(i % CImagicContainerBrowser::KGridSizeY) * height;
+        //TODO: consider aspect ratio
+
+        DP3_IMAGIC(_L("####### UnProject: itemX=%f, itemY=%f, itemZ=%f"), itemX, itemY, itemZ);
+        DP4_IMAGIC(_L("####### UnProject: itemDepthCoord=%f, perspectiveDepth=%f, itemDepth=%f, itemScale=%f"),
+            itemDepthCoord, perspectiveDepth, itemDepth, itemScale);
+        DP4_IMAGIC(_L("#######(%d) %6.4f < x(%6.4f) < %6.4f"), i, objx-width/2, itemX, objx+width/2);
+        DP4_IMAGIC(_L("#######(%d) %6.4f < y(%6.4f) < %6.4f"), i, objy-height/2, itemY, objy+height/2);
+
+        if (objx-width/2 <= itemX && itemX < objx + width/2)
+            {
+            if (objy-height/2 <= itemY && itemY < objy + height/2)
+                {
+                aResultIndex = i;
+                break;
+                }
+            }
+        }
+
+#if 0
+    // just trial code. useful for checking unprojection results
+    z = 0.9997; // best reasonable fixed value from experience
+    gluUnProject(x,y,z,modelview,projection,viewport,&objX,&objY,&objZ);
+    RDebug::Print(_L("####### UnProject(z=%8.6f):X=%6.4f,Y=%6.4f,Z=%6.4f"), z,objX,objY,objZ);
+#endif
+        
+    //DP1_IMAGIC(_L("####### SELECTED =====> %d"), selectedIndex);
+
+    return (aResultIndex != -1)? ETrue: EFalse;
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::GetMaxX()
+// ---------------------------------------------------------
+//
+TReal CImagicContainerBrowser::GetMaxX() const
+    {
+    TInt images = iIEngine->GetTotalNumOfImages();
+    return images > 0 ? iIEngine->GetImageData(images - 1)->iGridData.iX : 0;
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::FindImageInOGl(
+//     const FloatCoords aPos, TInt& aResultIndex)
+// ---------------------------------------------------------
+//
+TBool CImagicContainerBrowser::FindNearestImageInOGl(const FloatCoords aPos, TInt& aResultIndex)
+    {
+    float width  = KSpacingX;
+    float height = KSpacingY;
+    float itemX = aPos.iX;
+    float itemY = aPos.iY;
+    TInt  image_num = iIEngine->GetTotalNumOfImages();
+
+    DP2_IMAGIC(_L("1: itemXY=(%6.4f,%6.4f)"), itemX, itemY);
+
+    itemX = Max(itemX, 0);
+    itemX = Min(itemX, GetMaxX()); //image_num / CImagicContainerBrowser::KGridSizeY) * width);
+    itemY = Max(itemY, 0);
+    itemY = Min(itemY, (CImagicContainerBrowser::KGridSizeY - 1) * height);
+
+    DP2_IMAGIC(_L("2: itemXY=(%6.4f,%6.4f)"), itemX, itemY);
+    
+    aResultIndex = -1; // gives invalid value if not found
+
+    // The ray is linear. Can get xy at a depth by multiply '(a depth)/(near/far depth)'
+    for (TInt i=0; i<image_num; ++i)
+        {
+        CImageData* imageData = iIEngine->GetImageData(i);
+        GLfloat itemZ = imageData->iGridData.iZ;
+        GLfloat objx = imageData->iGridData.iX;
+        GLfloat objy = -imageData->iGridData.iY;
+        //GLfloat objx = (i / iGridSizeY) * width;
+        //GLfloat objy = (i % iGridSizeY) * height;
+
+        if (objx-width/2 <= itemX && itemX < objx + width/2)
+            {
+            if (objy-height/2 <= itemY && itemY < objy + height/2)
+                {
+                aResultIndex = i;
+                break;
+                }
+            }
+        }
+
+    return (aResultIndex != -1)? ETrue: EFalse;
+    }
+
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::ConvertCoordsFromScreen2OGl(
+//     const TPoint aPos, FloatCoords& aCoord)
+// ---------------------------------------------------------
+//
+FloatCoords CImagicContainerBrowser::ConvertCoordsFromScreen2OGl(const TPoint aPos)
+    {
+    // Calculte OpenGL coords in current image for OneByOne view
+    TSize size = this->Size();
+    FloatCoords coord;
+    
+    // OpenGL coord (-0.5 - +0.5) = (relative position in screen) * (coordinate system)
+    coord.iX = (((float)aPos.iX / size.iWidth ) - 0.5) * (iDrawOneByOne->GetDrawOneByOneWidth() * 2);
+    coord.iY = (((float)aPos.iY / size.iHeight) - 0.5) * (iDrawOneByOne->GetDrawOneByOneHeight() * 2);
+
+//    RDebug::Print(_L("ConvertCoordsFromScreen2OGl: aPos(%d,%d)/size(%d,%d)*ortho(%6.4f,%6.4f) = coord(%6.4f,%6.4f)"),
+//            aPos.iX, aPos.iY, size.iWidth, size.iHeight, iDrawOnebyOneW, iDrawOnebyOneH, coord.iX, coord.iY);
+    
+    // scale -> translate -> rotate when display
+    // translate -> scale on calculation. TODO: rotate needs to be considered.
+    coord.iX = (coord.iX + iDrawOneByOne->GetDrawOneByOneXY().iX) / iDrawOneByOne->GetDrawOneByOneZoom(); 
+    coord.iY = (coord.iY - iDrawOneByOne->GetDrawOneByOneXY().iY) / iDrawOneByOne->GetDrawOneByOneZoom();
+
+//    RDebug::Print(_L("ConvertCoordsFromScreen2OGl: coord(%6.4f,%6.4f)+trans(%6.4f,%6.4f)*zoom(%6.4f)"),
+//            coord.iX, coord.iY, iDrawOneByOneX, iDrawOneByOneY, iDrawOneByOneZoom);
+
+    return coord;
+    }
+
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::FindNearestFace(
+//     const TPoint aPos, TInt& aResultIndex)
+// ---------------------------------------------------------
+//
+TBool CImagicContainerBrowser::FindNearestFace(const TPoint aPos, TInt& aResultIndex)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::FindNearestFace++"));
+
+    // number of faces in current image(iCurrentIndex). iCoordinates must be already set
+    TInt facecount = iDrawFaceBrowsing->GetFaceCount();
+
+    TBool isCloseEnough = EFalse;
+    TBool found = EFalse;
+    float closestDistance = 0.0;  // this is actully square of distance.
+
+//    ConvertScreenCoords2QvgaCoords(TPoint& aPoint, TRect& aRect)
+    
+    FloatCoords coord = ConvertCoordsFromScreen2OGl(aPos);
+
+    if(!GetScreenOrientation())
+        {
+        // swap x and y in portrait
+        float temp = coord.iX;
+        coord.iX = -coord.iY;
+        coord.iY = temp ;
+        }
+    
+    DP4_IMAGIC(_L("CImagicContainerBrowser::FindNearestFace: aPos(%d,%d) => Coord(%6.4f,%6.4f)"),aPos.iX,aPos.iY,coord.iX,coord.iY);
+    
+    for(TInt i=0; i<facecount; ++i)
+        {
+        FloatCoords tmp = iDrawFaceBrowsing->ConvertCoordsFromAlgo2OGl(i);
+
+        DP3_IMAGIC(_L("CImagicContainerBrowser::FindNearestFace: ====> face %d(%6.4f,%6.4f)"), i, tmp.iX,tmp.iY);
+        
+        float distance;
+        float diff_x = Abs(tmp.iX - coord.iX);
+        float diff_y = Abs(tmp.iY - coord.iY);
+        
+        distance = diff_x*diff_x + diff_y*diff_y;
+
+        DP3_IMAGIC(_L("CImagicContainerBrowser::FindNearestFace: diff x=%6.4f, y=%6.4f. distance=%8.5f)"), diff_x, diff_y, distance);
+        
+        if (distance < closestDistance || !found)
+            {
+            found = ETrue;
+            aResultIndex = i;
+            closestDistance = distance;
+            }
+        
+        if (distance < KFindFaceSearchRange) isCloseEnough = ETrue;
+        }
+
+    DP1_IMAGIC(_L("CImagicContainerBrowser::FindNearestFace(%d)--"), isCloseEnough);
+
+    return isCloseEnough;
+    }
+
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::HandleGestureBeganL(
+//     const TPoint& aPos)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::HandleGestureBeganL(const TPoint& aPos)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandleGestureBeganL"));
+    // do nothing
+#ifdef SELECT_ON_TOUCHDOWN
+    TInt sel;
+    
+    if ((iDrawFunction == EGrid) && FindImageInScreen(aPos, sel)) {
+        iCurrentIndex = sel;
+        iDrawNow = ETrue;
+    }
+#endif
+    
+#ifdef MOMENTUM_MOVE
+    iMomentumMove = EFalse;
+#endif
+
+#ifdef RD_FACEFRAME
+    //iDrawFaceFrame = ETrue;
+    iDrawNow = ETrue;
+#endif
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::HandleGestureMovedL(
+//     const TPoint& aPos, const TGestureType aType)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::HandleGestureMovedL(const TPoint& aPos, const TGestureType aType)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandleGestureMovedL++"));
+
+    if (IS_GESTURE_TAPnDRAG(aType)) // tap&drag for zoom and rotate
+        {
+        DP0_IMAGIC(_L("IS_GESTURE_TAPnDRAG"));
+        // Gesture movement and coord movement are opposite. EFalse for no wrap
+        DoTapAndDrag(aPos, aType);
+        }
+    else if (IS_GESTURE_DRAG(aType)) // just a drag. not Tap and Drag
+        {
+        DP0_IMAGIC(_L("IS_GESTURE_DRAG"));
+        // actions for dragging
+        // This drag event occurs even finger movement is still within tap threshold
+        DoDrag(aPos, aType);
+#ifdef HOLD_SELECTION_ONDRAG
+        iHoldSelection = ETrue;
+#endif
+        }
+    else if (IS_GESTURE_CURSORSIMULATION(aType))
+        {
+        DP0_IMAGIC(_L("IS_GESTURE_CURSORSIMULATION"));
+        DoCursorSimulation(aPos, aType);
+        }
+    else if (IS_GESTURE_LONGTAPPING(aType))
+        {
+        DP0_IMAGIC(_L("IS_GESTURE_LONGTAPPING"));
+        DoLongTapping(aPos, aType);
+        }
+
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandleGestureMovedL--"));
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::HandleGestureEndedL(
+//     const TPoint& aPos, const TGestureType aType)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::HandleGestureEndedL(const TPoint& aPos, const TGestureType aType)
+    {
+#ifdef HOLD_SELECTION_ONDRAG
+    // User doesn't touching screen and auto-move can start
+    iHoldSelection = EFalse;
+#endif
+#ifdef RD_FACEFRAME
+    //iDrawFaceFrame = EFalse;
+#endif
+    
+// TODO: FIXME: unno temp fix endless cursor movement.
+// These need to be set false when key was released. TODO: how to do in dragging in touch... 
+    iTouchMoveData.iRight = EFalse;
+    iTouchMoveData.iLeft = EFalse;
+    iTouchMoveData.iUp = EFalse;
+    iTouchMoveData.iDown = EFalse;//*mika*
+    
+    iOnTheEdge=EFalse;
+    
+    if (IS_GESTURE_SINGLETAP(aType))
+        {
+        DoSingleTap(aPos, aType);
+        }
+    else if (IS_GESTURE_DOUBLETAP(aType))
+        {
+        DoDoubleTap(aPos, aType);
+        }
+    else if (IS_GESTURE_LONGTAP(aType))
+        {
+        DoLongTap(aPos, aType);
+        }
+    else // Then DoFlick if not single/double tap
+        {
+        DoFlick(aPos, aType);
+        }
+
+    // Disable MagGlass when user releases finger 
+    ShowMagGlass(EFalse);
+    
+    //Set normal display draw speed if we were in low draw freq
+#ifdef USE_LOW_DRAW_SPEED_WHILE_LOADING
+    SetDrawFreqToNormal(KTouchDelay);
+#endif
+    }
+
+void CImagicContainerBrowser::DoTapAndDrag(const TPoint& /*aPos*/, const TGestureType aType)
+    {
+#ifdef TAP_AND_GESTURE
+    // unno experimental code
+    if (aType & EGestureUp)
+        {
+        iTouchMoveData.iZoomOut=ETrue;
+        iDrawNow = ETrue;
+        }
+    if (aType & EGestureDown)
+        {
+        iTouchMoveData.iZoomIn=ETrue;
+        iDrawNow = ETrue;
+        }
+    if (aType & EGestureLeft)
+        {
+        iTouchMoveData.iRotate -= 1;
+        iDrawNow = ETrue;
+        }
+    if (aType & EGestureRight)
+        {
+        iTouchMoveData.iRotate += 1;
+        iDrawNow = ETrue;
+        }
+#endif
+    }
+
+void CImagicContainerBrowser::DoCursorSimulation(const TPoint& /*aPos*/, const TGestureType aType)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoCursorSimulation++"));
+
+    TInt x = 0, y = 0;
+    TBool wrap = (iDrawFunction == EGrid)? EFalse: ETrue;
+
+    // do nothing if it's in the mode with no cursor simulation
+#ifndef CURSORSIMULATION_IN_GRID
+    if (iDrawFunction == EGrid) return;
+#endif
+
+#ifndef CURSORSIMULATION_IN_ONEBYONE
+#ifdef HOLD_SELECTION_ONDRAG
+    if (iDrawFunction == EOneByOne) return;
+#else
+    if (((iDrawFunction == EOneByOne) && (!IS_NOT_IN_ZOOM_ONEBYONE))) return;
+
+    // allow only left&right to move prev/next image. (do nothing if up or down)
+    if((iDrawFunction == EOneByOne) && ((aType & EGestureUp) || (aType & EGestureDown))) return;
+#endif // HOLD_SELECTION_ONDRAG
+#endif
+
+    // cursor move for dragging
+    if (aType & EGestureUp)    ++y;
+    if (aType & EGestureDown)  --y;
+    if (aType & EGestureLeft)  ++x;
+    if (aType & EGestureRight) --x;
+
+    DP3_IMAGIC(_L("CImagicContainerBrowser::DoCursorSimulation : aType=%d, x=%d, y=%d"), aType, x, y);
+
+    if (x || y) // move index only if x or y are changed
+        MoveIndex(x, y, wrap);
+
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoCursorSimulation--"));
+    }
+
+void CImagicContainerBrowser::DoDrag(const TPoint& aPos, const TGestureType aType)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoDrag++"));
+    
+    //ResetTouchData();//mika to test if "stucking" problem is fixed
+    ResetKeyData();
+    ResetTouchData();
+    ResetDirKeyData();
+    
+#ifdef HOLD_SELECTION_ONDRAG
+    float minX, maxX, minY, maxY;
+    TInt num = iIEngine->GetTotalNumOfImages();
+#endif
+#ifndef CURSORSIMULATION_IN_ONEBYONE
+    TSize size = this->Size();
+    FloatCoords coord;
+#endif
+
+    // do nothing if it's stationally (not beyond tap threshold) 
+    if (IS_GESTURE_STATIONARY(aType)) return;
+
+    //iDrawNow = ETrue;
+
+    switch (iDrawFunction)
+        {
+        case EGrid:
+#ifdef HOLD_SELECTION_ONDRAG
+            // Drag to shift view
+            coord.iX = (GLfloat)aPos.iX / 120; //160; // TODO: calc right value from z coord & scale
+            coord.iY = (GLfloat)aPos.iY / 90;  //120; // TODO: calc right value from z coord & scale
+
+            minX = -KSpacingX/2; // allow to move one-picture-size away from the edge
+            maxX = +KSpacingX/2 + GetMaxX();
+
+            minY = 0; // don't allow to move away from the edge
+            maxY = (CImagicContainerBrowser::KGridSizeY-1)*KSpacingY;
+
+            if (iDrawGrid->GetGridXY().iX < minX - minX || maxX + minX < iDrawGrid->GetGridXY().iX) coord.iX /= 3;
+            if (iDrawGrid->GetGridXY().iY < minY - minY || maxY + minY < iDrawGrid->GetGridXY().iY) coord.iY /= 3;
+            
+            TGridXY tmp = iDrawGrid->GetGridXY();
+            tmp.iX -= coord.iX;
+            tmp.iY -= coord.iY;
+            CheckLimits(tmp.iX, minX, maxX);
+            CheckLimits(tmp.iY, minY, maxY);
+            iDrawGrid->SetGridXY(tmp);
+#endif
+            break;
+        case EOneByOne:
+#ifndef CURSORSIMULATION_IN_ONEBYONE
+            if (!IS_NOT_IN_ZOOM_ONEBYONE)
+                {
+                // Drag only in zoomed image
+                coord.iX = (((float)aPos.iX / size.iWidth ) * (iDrawOneByOne->GetDrawOneByOneWidth() * 2)) / iDrawOneByOne->GetDrawOneByOneZoom();
+                coord.iY = (((float)aPos.iY / size.iHeight) * (iDrawOneByOne->GetDrawOneByOneHeight() * 2)) / iDrawOneByOne->GetDrawOneByOneZoom();
+
+                iDrawOneByOne->ChangeDrawOneByOneTargetX(-coord.iX);
+                iDrawOneByOne->ChangeDrawOneByOneTargetY(-coord.iY);
+                }
+#ifdef HOLD_SELECTION_ONDRAG
+            else if (!iDrawOneByOne->IsMagGlassOn() /*iMagGlassOn*/) // not in zoom, magglass off
+                {
+                // drag in x coord direction to move prev/next image
+                coord.iX = (((float)aPos.iX / size.iWidth ) * (iDrawOneByOne->GetDrawOneByOneWidth() * 2)) / iDrawOneByOne->GetDrawOneByOneZoom();
+                //iOneByOneFlow += coord.iX;
+                float tmp = iDrawOneByOne->GetImgeFlowLocation();
+                tmp+=coord.iX;
+                iDrawOneByOne->SetImgeFlowLocation(tmp);
+                
+                iOneByOneSlideByDrag = ETrue;
+                DP1_IMAGIC(_L("Sliding iOneByOneFlow=%6.4f"), iDrawOneByOne->GetImgeFlowLocation());
+                }
+#endif // HOLD_SELECTION_ONDRAG
+#endif
+            break;
+        case EFaceBrowser:
+// TODO: Integrate face browing and dragging!
+            
+            DP0_IMAGIC(_L("CImagicContainerBrowser::DoDrag - EFaceBrowser"));
+            //DoFlick(aPos, aType);
+        default:
+            break;
+        }
+    
+    iDrawNow = ETrue;
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoDrag--"));
+    
+    }
+
+void CImagicContainerBrowser::DoFlick(const TPoint& aPos, const TGestureType aType)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoFlick++"));
+    
+    //ResetTouchData();//mika to test if "stucking" problem is fixed
+    
+#ifndef CURSORSIMULATION_IN_ONEBYONE
+    TSize size = this->Size();
+    FloatCoords coord;
+#endif
+#ifdef MOMENTUM_MOVE
+    float vX, vY, tX, tY;
+    float minX, maxX;
+#ifndef FLICK_ONLY_IN_X_IN_GRID
+    float minY, maxY;
+#endif
+    TInt x, y, absX, absY;
+    TBool valid_x, valid_y;
+    TInt num = iIEngine->GetTotalNumOfImages();
+#endif
+
+    iDrawNow = ETrue;
+    
+    switch (iDrawFunction)
+        {
+        case EGrid:
+            DP0_IMAGIC(_L("CImagicContainerBrowser::DoFlick - EGrid"));
+#ifdef MOMENTUM_MOVE
+            // TODO: FIXME: Good value needed. Not 180. Consider non-liner speed.
+            // TODO: 128 should be the size of images in Screen (pixels) at z = 0 (not zoomed)
+const TInt FLICKUNIT=128; // movement of 128 px/s = 1 flick unit speed
+//const TInt FLICK_2ND_GEAR = 8;
+const TInt FLICK_2ND_GEAR = 16;
+const TInt FLICK_3ND_GEAR = 8;
+            x = aPos.iX;
+            y = aPos.iY;
+            absX = Abs(x);
+            absY = Abs(y);
+
+            valid_x = (absX && (absX * 5 > absY * 3))? ETrue: EFalse;
+            valid_y = (absY && (absY * 5 > absX * 4))? ETrue: EFalse;
+
+            if (!valid_x || (absX < FLICKUNIT / 3))
+                {
+                vX = tX = 0.0f;
+                }
+            else if (absX < FLICKUNIT)
+                {
+                vX = ((float)x / absX) * KSpacingX;
+                tX = (       x / absX) * KSpacingX;
+
+                if (tX>0 && iDrawGrid->GetGridTargetXY().iX < iDrawGrid->GetGridXY().iX) tX = 0;
+                if (tX<0 && iDrawGrid->GetGridTargetXY().iX > iDrawGrid->GetGridXY().iX) tX = 0;
+                }
+            else if (absX < FLICKUNIT * FLICK_2ND_GEAR)
+                {
+                vX = ((float)x / FLICKUNIT) * KSpacingX;
+                tX = (       x / FLICKUNIT) * KSpacingX;
+                }
+            else
+                {
+                float u = absX / FLICKUNIT;
+                float v = u*u - 2*FLICK_3ND_GEAR*u + FLICK_3ND_GEAR*FLICK_3ND_GEAR + FLICK_3ND_GEAR;
+                if (x < 0) v = -v;
+                vX = ((float)v) * KSpacingX;
+                tX = (       v) * KSpacingX;
+                }
+
+            vY = (valid_y)? ((float)y / FLICKUNIT) * KSpacingY: 0.0f;
+            tY = (valid_y)? (       y / FLICKUNIT) * KSpacingY: 0.0f;
+            
+            DP4_IMAGIC(_L("vX/Y=(%6.4f, %6.4f), tX/Y=(%6.4f,%6.4f)"), vX, vY, tX, tY);
+            DP2_IMAGIC(_L("aPos.iX/Y=(%d,%d)"), aPos.iX, aPos.iY);
+            
+            iMomentumMove = ETrue;
+
+            iMomentumSpeedX = Abs(vX);
+            //iDrawGridTargetX += (-tX);
+            TGridXY tmp = iDrawGrid->GetGridTargetXY();
+            tmp.iX += (-tX);
+            
+            minX = -KSpacingX/2; // allow to move one-picture-size away from the edge
+            maxX = +KSpacingX/2 + GetMaxX();
+
+            //CheckLimits(iDrawGridTargetX, minX, maxX);
+            CheckLimits(tmp.iX, minX, maxX);
+            iDrawGrid->SetGridTargetXY(tmp);
+
+#ifndef FLICK_ONLY_IN_X_IN_GRID
+            iMomentumSpeedY = Abs(vY);
+            iDrawGridTargetY += (-tY);
+            minY = 0; // don't allow to move away from the edge
+            maxY = (iGridSizeY-1)*KSpacingY;
+            CheckLimits(iDrawGridTargetY, minY, maxY);
+#else
+            iMomentumSpeedY = 0;
+#endif
+#endif
+            break;
+        case EOneByOne:
+            DP0_IMAGIC(_L("CImagicContainerBrowser::DoFlick - EOneByOne"));
+            
+#ifndef CURSORSIMULATION_IN_ONEBYONE
+            vX = (float)aPos.iX / 2; // pixels of movement in 0.5 sec
+            vY = (float)aPos.iY / 2;
+            
+            coord.iX = ((vX / size.iWidth ) * (iDrawOneByOne->GetDrawOneByOneWidth() * 2)) / iDrawOneByOne->GetDrawOneByOneZoom();
+            coord.iY = ((vY / size.iHeight) * (iDrawOneByOne->GetDrawOneByOneHeight() * 2)) / iDrawOneByOne->GetDrawOneByOneZoom();
+
+            iDrawOneByOne->ChangeDrawOneByOneTargetX(-coord.iX);
+            iDrawOneByOne->ChangeDrawOneByOneTargetY(-coord.iY);
+            
+#endif
+#ifdef HOLD_SELECTION_ONDRAG
+            // Find current index if sliding is done by dragging in OneByOne view
+            // iOneByOneSlideByDrag is set EFalse in HandleMovingKeysOneByOne() 
+            // Flick is not currently affecting even though this is in DoFlick()
+            DP2_IMAGIC(_L("Checking iOneByOneSlideByDrag (%d), iOneByOneFlow=%6.4f"), iOneByOneSlideByDrag, iDrawOneByOne->GetImgeFlowLocation());
+            if (iOneByOneSlideByDrag)
+                {
+                if (iDrawOneByOne->GetImgeFlowLocation() > +KOneByOneSpacing / 10) 
+                    MoveIndex(-1, 0, ETrue);
+                if (iDrawOneByOne->GetImgeFlowLocation() < -KOneByOneSpacing / 10) 
+                    MoveIndex(+1, 0, ETrue);
+                }
+#endif
+            break;
+        case EFaceBrowser:
+            DP0_IMAGIC(_L("CImagicContainerBrowser::DoFlick - EFaceBrowser"));
+            if(GetScreenOrientation())
+                {
+                if (aType & EGestureLeft)  MoveIndex( 1, 0, ETrue);
+                if (aType & EGestureRight) MoveIndex(-1, 0, ETrue);
+                }
+            else
+                {
+                if (aType & EGestureDown)  MoveIndex( 1, 0, ETrue);
+                if (aType & EGestureUp)    MoveIndex(-1, 0, ETrue);
+                }
+            break;
+        default:
+            break;
+        }
+    
+    //ResetTouchData();//mika to test if "stucking" problem is fixed
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoFlick--"));
+    }
+
+void CImagicContainerBrowser::DoSingleTap(const TPoint& aPos, const TGestureType /*aType*/)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoSingleTap++"));
+    
+    //ResetTouchData();//mika to test if "stucking" problem is fixed
+    
+    TInt sel;
+    
+    switch (iDrawFunction)
+        {
+        case EGrid:
+            if (FindImageInScreen(aPos, sel))       // do nothing if user touches none
+                {
+                if (iCurrentIndex == sel)
+                    {
+                    SelectIndex();          // Open image if user touches current image
+                    }
+                else
+                    {
+                    iCurrentIndex = sel;    // focus touched image if it's not current one
+                    iDrawNow = ETrue;
+                    }
+                }
+            break;
+        case EOneByOne:
+            // TODO: Add face browsing by signle tap, maybe on zoom?
+            DP1_IMAGIC(_L("DoSingleTap:iDrawOneByOneZoom=%6.4f"), iDrawOneByOne->GetDrawOneByOneZoom());
+            if (IS_NOT_IN_ZOOM_ONEBYONE)
+                {
+                /*TInt dx = 50 - aPos.iX;
+                TInt dy = 50 - aPos.iY;
+                
+                // start face browing if user taps at top left when face icon is shown 
+                if (iFaceExists && (dx*dx + dy*dy < 50*50))
+                    iView->HandleCommandL(EImagicCmdViewFaceBrowsing);
+                else*/
+                    SelectIndex(); // exits only when non zoomed.
+                }
+#ifdef SINGLETAP_CLOSE_IN_ZOOM
+            else
+                {
+                // Stop zooming if it's in zoom
+                //iDrawOneByOne->SetDrawOneByOneTargetZoom(KDoubleTapZoomOneByOne1);//mika, single tap disabled in zzomed in picture
+                iDrawNow = ETrue;
+                }
+#endif
+            break;
+        case EFaceBrowser:
+#ifdef SINGLETAP_CLOSE_IN_ZOOM
+            // TODO: FIXME. Temporary hack to start OnebyOne view. Pretend it's grid and do select action 
+            //iDrawFunction = EGrid;
+            //SetDrawMode(EGrid);
+            /*SelectIndex();
+            SetDrawMode(EOneByOne);*/
+            
+#endif
+            break;
+        default:
+            break;
+        }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoSingleTap--"));
+    
+    }
+
+void CImagicContainerBrowser::DoDoubleTap(const TPoint& aPos, const TGestureType /*aType*/)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoDoubleTap++"));
+    
+    //ResetTouchData();//mika to test if "stucking" problem is fixed
+    
+#ifdef DOUBLETAP_SELECT_IN_GRID
+    TInt sel;
+#endif
+    iDrawNow = ETrue;
+    
+    switch (iDrawFunction)
+        {
+#define TOGGLE_VALUE(tgt, val1, val2)  (tgt)=((tgt)!=(val1))?(val1):(val2)
+        case EGrid:
+#ifdef DOUBLETAP_SELECT_IN_GRID
+            if (FindImageInScreen(aPos, sel))       // do nothing if user touches none
+                {
+                iCurrentIndex = sel;    // focus touched image if it's not current one
+                SelectIndex();          // Open image if user touches current image
+                }
+#endif
+#ifdef ENABLE_GRID_ZOOM
+#ifdef DOUBLETAP_ZOOMGRID
+            TOGGLE_VALUE(iDrawGridTargetZoom, KDoubleTapZoomGrid1, KDoubleTapZoomGrid2);
+#endif
+#endif
+            break;
+        case EOneByOne:
+#ifdef DOUBLETAP_FACEBROWSING
+            if (IS_NOT_IN_ZOOM_ONEBYONE)
+                {
+                iView->HandleCommandL(EImagicCmdViewFaceBrowsingWithCoordinates);
+                }
+#endif
+            // toggle zooming on and off if MagGlass is off
+            if(!iDrawOneByOne->IsMagGlassOn()/*iMagGlassOn*/)
+                {
+                //TOGGLE_VALUE(iDrawOneByOneTargetZoom, KDoubleTapZoomOneByOne1, KDoubleTapZoomOneByOne2);
+                if(iDrawOneByOne->GetDrawOneByOneTargetZoom() == KDoubleTapZoomOneByOne1)
+                    iDrawOneByOne->SetDrawOneByOneTargetZoom(KDoubleTapZoomOneByOne2);
+                else
+                    iDrawOneByOne->SetDrawOneByOneTargetZoom(KDoubleTapZoomOneByOne1);
+                }
+
+            if (iDrawOneByOne->GetDrawOneByOneTargetZoom() == KDoubleTapZoomOneByOne2)
+                {
+                // if we are zooming in, tapped position is set as center
+                TSize size = this->Size();
+                float imageWidth, imageHeight;
+                CalculateImageSize(imageWidth, imageHeight, (float)size.iWidth/(float)size.iHeight);
+
+                /*iDrawOneByOneTargetX = (2*iImageWidth) *(((float)aPos.iX / size.iWidth ) - 0.5);
+                iDrawOneByOneTargetY = (2*iImageHeight)*(((float)aPos.iY / size.iHeight) - 0.5);*/
+                TDrawOneByOneXY tmp; 
+                tmp.iX = (2*imageWidth) *(((float)aPos.iX / size.iWidth ) - 0.5);
+                tmp.iY = (2*imageHeight)*(((float)aPos.iY / size.iHeight) - 0.5);
+                iDrawOneByOne->SetDrawOneByOneTargetXY(tmp);
+
+                /*if(!GetScreenOrientation())
+                    {
+                    float tmp = iDrawOneByOneTargetX;
+                    iDrawOneByOneTargetX = -iDrawOneByOneTargetY; 
+                    iDrawOneByOneTargetY = tmp;
+                    }*/
+                }
+            break;
+        case EFaceBrowser:
+#ifdef DOUBLETAP_FACEBROWSING
+            // TODO: FIXME. Temporary hack to start OnebyOne view. Pretend it's grid and do select action 
+            //iDrawFunction = EGrid;
+            drawZoom = 1; inPictureX = 0; inPictureY = 0;
+            iDrawFaceBrowsing->GetFBZoomAndLocation(drawZoom, inPictureX, inPictureY);
+            iDrawOneByOne->InitDrawOnebyOne(drawZoom, inPictureX, inPictureY);
+            
+            SelectIndex();
+            SetDrawMode(EOneByOne/*EGrid*/);
+#endif
+            break;
+        }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DoDoubleTap--"));
+    }
+
+void CImagicContainerBrowser::DoLongTapping(const TPoint& aPos, const TGestureType aType)
+    {
+    DP1_IMAGIC(_L("CImagicContainerBrowser::DoLongTapping aPos.iX: %d"), aPos.iX);
+    DP1_IMAGIC(_L("CImagicContainerBrowser::DoLongTapping aPos.iY: %d"), aPos.iY);
+    
+    //ResetTouchData();//mika to test if "stucking" problem is fixed
+    
+    // touch movement is stationary for enough long time 
+    switch (iDrawFunction)
+        {
+        case EOneByOne:
+            ShowMagGlass(ETrue);
+            break;
+        case EGrid:
+            iView->ProcessCommandL(EAknSoftkeyOptions);
+            /*TInt sel;
+            if (FindImageInScreen(aPos, sel))       // do nothing if user touches none
+                {
+                if (iCurrentIndex == sel)
+                    {
+                    iView->ProcessCommandL(EAknSoftkeyOptions);
+                    //iView->ProcessCommandL(EImagicCmdViewBrowserShowImageInfo);
+                    }
+                }*/
+                
+            /*else if(aPos.iX > 100)
+                {
+                iView->ProcessCommandL(EAknSoftkeyOptions);
+                }*/
+#if 0
+            else
+                {
+                //iView->ProcessCommandL(EAknSoftkeyOptions);
+                }
+#endif           
+            //iView->ProcessCommandL(EAknSoftkeyOptions);//TODO, options should be shown from softkeys 
+            break;
+
+        case EFaceBrowser:
+            break;
+        default:
+            // do nothing
+            break;
+        }
+    
+    iDrawNow = ETrue;
+    
+    }
+
+void CImagicContainerBrowser::DoLongTap(const TPoint& aPos, const TGestureType aType)
+    {
+    // do nothing so far.
+    iDrawNow = ETrue;
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::MoveIndex(
+//     TInt aMoveX, TInt aMoveY, TBool aWrap)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::MoveIndex(TInt aMoveX, TInt aMoveY, TBool aWrap)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::MoveIndex++"));
+    
+    TInt num = iIEngine->GetTotalNumOfImages();
+    // Reset key data
+    iTouchMoveData.iRight = EFalse;
+    iTouchMoveData.iLeft = EFalse;
+    iTouchMoveData.iUp = EFalse;
+    iTouchMoveData.iDown = EFalse;//*mika*
+    iTouchMoveData.iX = 0;
+    iTouchMoveData.iY = 0;
+
+    if (aMoveX < 0) // left key press
+        {
+        if (aWrap || iCurrentIndex >= CImagicContainerBrowser::KGridSizeY)
+            {
+            if(iDrawFunction == EFaceBrowser)
+                //iFaceNro--; // prev face in face browser
+                iDrawFaceBrowsing->DecFaceNumber();
+            else
+                {
+                iTouchMoveData.iX    = aMoveX;
+                iTouchMoveData.iLeft = ETrue;
+                }
+            iDrawNow       = ETrue;
+            }
+        }
+    
+    if (aMoveX > 0) // right key press
+        {
+        if (aWrap || iCurrentIndex < num - CImagicContainerBrowser::KGridSizeY)
+            {
+            if(iDrawFunction == EFaceBrowser)
+                //iFaceNro++; // next face in face browser
+                iDrawFaceBrowsing->IncFaceNumber();
+            else
+                {
+                iTouchMoveData.iX     = aMoveX;
+                iTouchMoveData.iRight = ETrue;
+                }
+            iDrawNow        = ETrue;
+            }
+        }
+
+    if (aMoveY < 0) // up key press
+        {
+        if (aWrap || iCurrentIndex % CImagicContainerBrowser::KGridSizeY > 0)
+            {
+            iTouchMoveData.iY  = aMoveY;
+            iTouchMoveData.iUp = ETrue;
+            iDrawNow = ETrue;
+            }
+        }
+    
+    if (aMoveY > 0) // down key press
+        {
+        if ( aWrap || 
+            ((iCurrentIndex % CImagicContainerBrowser::KGridSizeY < CImagicContainerBrowser::KGridSizeY - 1) &&
+             (iCurrentIndex < num - 1)))
+            {
+            iTouchMoveData.iY    = aMoveY;
+            iTouchMoveData.iDown = ETrue;
+            iDrawNow = ETrue;
+            }
+        }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::MoveIndex--"));
+    }
+
+// ---------------------------------------------------------
+// CImagicContainerBrowser::SelectIndex(
+//     void)
+// ---------------------------------------------------------
+//
+void CImagicContainerBrowser::SelectIndex(void)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SelectIndex++"));
+    
+    iDrawNow = ETrue;
+    
+    if(iDrawFunction == EGrid)
+        {
+        //Open one by one mode
+        iDrawOneByOne->InitDrawOnebyOne(KInitDrawZoom/*drawZoom*/, inPictureX, inPictureY);
+        
+        //Set Grid view
+        if(iDrawFunction == EFaceBrowser)
+            {
+            //iDrawFunction = EGrid;
+            SetDrawMode(EGrid);
+            }
+        
+        iView->SetFaceBrowsingMode(EFaceBrowserNone);
+        }
+    else if(iDrawFunction == EOneByOne)
+        {
+/*#ifdef SUPERZOOM
+        //Unload high res textures when going back to Grid
+        CImageData* aGridData = iIEngine->GetImageData(iCurrentIndex); 
+        iTextureLoader->ReleaseSuperHResTexture( aGridData );
+#endif*/  
+        
+        //Return to previous mode
+        iDrawGrid->InitDrawGrid();
+        //iDrawFunction = iDrawOneByOnePreviousFunc;
+        //iDrawFunction = EGrid;
+        SetDrawMode(EGrid);
+        iView->SetFaceBrowsingMode(EFaceBrowserNone);
+        }
+    else if(iDrawFunction == EFaceBrowser)
+        {
+        iDrawGrid->InitDrawGrid();
+        //iDrawFunction = EGrid;
+        //SetDrawMode(EGrid);
+        SetDrawMode(EOneByOne);
+        }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SelectIndex--"));
+    }
+
+//#endif
+
+void CImagicContainerBrowser::SetLoadingOn(TBool aValue)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetLoadingOn++"));
+	DP1_IMAGIC(_L("CImagicContainerBrowser::SetLoadingOn - value: %d"), aValue);
+    
+    iDynamicLoadingOn = aValue;
+    //iDrawNow = ETrue;
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetLoadingOn--"));
+    }
+
+
+void CImagicContainerBrowser::ImageLoadedL(TInt aError, CFbsBitmap* aBitmap, TThumbSize aResolution)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL++"));
+    
+    //Check do we need to unload or load more images ------>
+    //LoadUnloadImages();
+    DynamicUnLoading();
+    
+    TInt mem = 0;
+    TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+    DP1_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL - Free RAM: %d"), mem);
+    
+    if(mem <= 16000000){
+        DP0_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL - buffer size: 1"));
+        K512TNImageBuffer = 1;
+        }
+    if(mem <= 20000000){
+        DP0_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL - buffer size: 2"));
+        K512TNImageBuffer = 2;
+        }
+    if(mem > 24000000){
+        DP0_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL - buffer size: 3"));
+        K512TNImageBuffer = 3;
+        }  
+    if(mem > 28000000){
+        DP0_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL - buffer size: 4"));
+        K512TNImageBuffer = 4;
+        }
+    if(mem > 32000000){
+        DP0_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL - buffer size: 5"));
+        K512TNImageBuffer = 5;
+        }
+    
+    if(aResolution == ESize512x512 || aResolution == EFullSize)
+        {
+        iPreferHighResLoading = EFalse;
+        iDynamicLoadingOn = ETrue;
+        DynamicLoadingL();
+        }
+    
+    iTextureLoader->ImageLoadedL(aError, aBitmap, iGLMaxRes);
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::ImageLoadedL--"));
+    }
+
+
+//This is correcting the aspact ratio to be correct for OpengGL drawing
+void CImagicContainerBrowser::SetPictureVertices(CImageData* aData, GLfixed* aVertices)
+    {
+    //DP0_IMAGIC(_L("CImagicContainerBrowser::SetPictureVertices"));
+    
+    GLfixed vx, vy;		
+   
+    // Use real image
+    if(aData->iGridData.iGlLQ128TextIndex != 0 ||
+       aData->iGridData.iGlLQ32TextIndex != 0 ||
+       aData->iGridData.iGlHQ512TextIndex != 0)
+        {
+        if(aData->GetAspectRatio() > 1)
+            {
+			vx = 1<<15;
+            vy = (0.5/aData->GetAspectRatio())*(1<<16);
+            }
+        else
+            {
+            vx = (0.5*aData->GetAspectRatio())*(1<<16);
+			vy = 1<<15;
+            }
+        }
+    // Use loading image
+	else	
+		{
+		vx = 24000;		
+    	vy = vx / KLoadingImageAspectRatio;
+		}
+    
+    aVertices[0*2+0] = -vx;
+    aVertices[0*2+1] = -vy;
+    
+    aVertices[1*2+0] = vx;
+    aVertices[1*2+1] = -vy;
+    
+    aVertices[2*2+0] = -vx;
+    aVertices[2*2+1] = vy;
+    
+    aVertices[3*2+0] = vx;
+    aVertices[3*2+1] = vy;
+
+    }
+
+void CImagicContainerBrowser::DisplayDeleteQueryDialogL(TInt aResourceId)
+    {
+    CAknQueryDialog* dlg;
+    dlg = new ( ELeave ) CAknQueryDialog();
+    TInt result = dlg->ExecuteLD( aResourceId );
+    if(result != KErrNone)
+        {
+        //Delete file
+        DeleteImageL();
+        }
+    }
+
+//Delete current image
+void CImagicContainerBrowser::DeleteImageL()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DeleteImageL++"));
+    
+    //Delete image from engine
+    //Delete grid image from OpenGL memory
+    //TInt num = iIEngine->GetTotalNumOfImages();
+    CImageData* data = iIEngine->GetImageData(iCurrentIndex);
+    
+    if(data->iGridData.iGlLQ128TextIndex)
+        glDeleteTextures( 1, &data->iGridData.iGlLQ128TextIndex );
+    if(data->iGridData.iGlLQ32TextIndex)
+        glDeleteTextures( 1, &data->iGridData.iGlLQ32TextIndex );
+    if(data->iGridData.iGlHQ512TextIndex != 0)
+        glDeleteTextures(1, &data->iGridData.iGlHQ512TextIndex);
+    if(data->iGridData.iGlSuperHQTextIndex != 0)
+        glDeleteTextures(1, &data->iGridData.iGlSuperHQTextIndex);
+    
+    data->iGridData.iGlLQ32TextIndex = 0;
+    data->iGridData.iGlLQ128TextIndex = 0;
+    data->iGridData.iGlHQ512TextIndex = 0;
+    data->iGridData.iGlSuperHQTextIndex = 0;
+                    
+    //Delete image from engine
+    TInt err = iImagicAppUi->DeleteImage(iCurrentIndex);
+    if (err != KErrNone)
+        {
+        iImagicAppUi->GetImagicUtils()->ExecuteQueryDialog(R_CANNOT_DELETE_DIALOG);
+        }
+    
+    iDrawOneByOne->SetDrawOneByOneTargetZoom(1);
+    iDrawNow = ETrue;
+    
+    iDrawGrid->UpdateImageCoordinates(iCurrentIndex);
+    
+    if(iIEngine->GetTotalNumOfImages() <= 0)
+        {
+        iImagicAppUi->GetImagicUtils()->ExecuteQueryDialog(0, R_NO_IMAGES_DIALOG);
+        }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DeleteImageL--"));
+    }
+     
+
+
+//Returns TRUE if screen is landscape
+TBool CImagicContainerBrowser::GetScreenOrientation()
+    {
+    //Landscape
+#ifdef _ACCELEROMETER_SUPPORTED_
+    //if(iDeviceOrientation == EOrientationDisplayLeftUp)//Landscape
+    if(iDeviceOrientation == EOrientationDisplayLeftUp || iDeviceOrientation == EOrientationDisplayRigthUp)//Landscape
+        {
+        DP1_IMAGIC(_L("CImagicContainerBrowser::GetScreenOrientation - Landscape: %d"),iDeviceOrientation);
+        iDeviceOrientationAngle = 0;
+        return ETrue;
+        }
+    else if(iDeviceOrientation == EOrientationDisplayDown)
+        {
+        DP1_IMAGIC(_L("CImagicContainerBrowser::GetScreenOrientation - Portrait: %d"),iDeviceOrientation);
+        iDeviceOrientationAngle = -90;
+        return EFalse;
+        }
+#else
+    if(this->Size().iWidth > this->Size().iHeight)
+
+        {
+        DP1_IMAGIC(_L("CImagicContainerBrowser::GetScreenOrientation - Landscape: %d"),iDeviceOrientation);
+        return ETrue;
+        }
+    else
+        {
+        DP1_IMAGIC(_L("CImagicContainerBrowser::GetScreenOrientation - Portrait: %d"),iDeviceOrientation);
+        return EFalse;
+        }
+#endif
+    }
+
+//This should be called when reading touch UI events or key events to set draw freq to normal
+void CImagicContainerBrowser::SetDrawFreqToNormal(TInt aTimerDelay)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetDrawFreqToNormal++"));
+    
+    //Set normal display draw speed if we were in power save
+    if(iDisplayDrawFreq == KPowerSaveDisplayDrawFreq)
+        {
+        iDisplayDrawFreq = KDisplayDrawFreq;
+        DisableDisplayDraw();
+        if(iImagicAppUi->IsAppOnTop())
+            EnableDisplayDraw();
+        }
+    //Reset power save timer
+    iPowerSavePeriodic->Cancel();
+    //And start it again, but only if we are loading images
+    if(iTextureLoader->IsActiveAndRunning() && iDrawFunction == EGrid)
+        {
+        iPowerSavePeriodic->Start(/*KPowerSavePeriodicDelay*/aTimerDelay, KPowerSavePeriodicInterval, TCallBack( CImagicContainerBrowser::PowerSaveCallBack, this ) );
+        }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetDrawFreqToNormal--"));
+    }
+        
+void CImagicContainerBrowser::ResetZoomKeys()
+    {
+    iKeyData.iZoomInKey=EFalse;
+    iKeyData.iZoomOutKey=EFalse;    
+    }
+                
+  
+TKeyResponse CImagicContainerBrowser::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::OfferKeyEventL"));
+
+    //Set normal display draw speed if we were in low draw freq
+#ifdef USE_LOW_DRAW_SPEED_WHILE_LOADING
+    SetDrawFreqToNormal(KPowerSavePeriodicDelay);
+#endif
+    
+    //if(iImagicAppUi->IsAppOnTop())
+        EnableDisplayDraw();
+    
+    iUserInputGiven = ETrue;
+    iLastEventFromKeys = ETrue;
+    
+    TKeyResponse ret = EKeyWasNotConsumed;
+	
+	// Set default values
+	TInt addValue=0;
+	TBool pressValue=EFalse;
+	ResetKeyData();
+	ResetTouchData();
+	ResetDirKeyData();
+	iDrawOneByOne->ChangeDrawOneByOneTargetX(0);
+    iDrawOneByOne->ChangeDrawOneByOneTargetY(0);
+	
+	// Set button as pressed and add press counter by one
+    if (aType == EEventKey)
+        {
+        iDrawGrid->KeyEvent();
+        iDrawOneByOne->KeyEvent();
+        iDrawFaceBrowsing->KeyEvent();
+                
+        iDrawNow = ETrue;
+        addValue=1;
+        pressValue=ETrue;
+        }
+    
+    if (aType == EEventKeyDown)
+        {
+        iDrawGrid->KeyPressed();
+        iDrawOneByOne->KeyPressed();
+        iDrawFaceBrowsing->KeyPressed();
+        
+        /*if(iDrawFunction == EOneByOne && IS_NOT_IN_ZOOM_ONEBYONE)
+            iDrawOneByOne->InitDrawOnebyOne();*/
+        
+        iIntheEndOfGrid = EFalse;
+        iOnTheEdge=ETrue;
+        iKeyPressedDown=ETrue;
+        pressValue=ETrue;
+        ///
+        iDrawNow = ETrue;
+        addValue=1;
+        }
+    
+    if (aType == EEventKeyUp)
+        {
+        iDrawGrid->KeyReleased();
+        iDrawOneByOne->KeyReleased();
+        iDrawFaceBrowsing->KeyReleased();
+        
+        iOnTheEdge=EFalse;
+        iKeyPressedDown=EFalse;
+        pressValue=EFalse;
+        addValue=0;
+        //iKeyCounter=0;
+        
+        if(iIntheEndOfGrid)
+            iJumpOver = ETrue;
+        else
+            iJumpOver = EFalse;
+        }
+	    
+    CImageData* imageData = iIEngine->GetImageData(iCurrentIndex);
+    TInt imageRotation = 0 - (TReal)imageData->GetOrientation();
+    
+    
+	//if (aType==EEventKey /*|| aType==EEventKeyUp || aType==EEventKeyDown*/)
+//	if(iKeyCounter == 0)
+		{
+		// Assume that key will be handled
+		ret = EKeyWasConsumed;
+		
+		// Check for key
+		switch (aKeyEvent.iScanCode)
+			{
+			// Vertical movement
+		    case EStdKeyDownArrow:
+		        if(iDrawFunction == EOneByOne && IS_NOT_IN_ZOOM_ONEBYONE){
+		        }
+		        else{
+		        iKeyData.iY+=addValue;
+		        iKeyData.iDown=pressValue;
+		        }
+#ifdef _ACCELEROMETER_SUPPORTED_
+		        if((iDeviceOrientation == EOrientationDisplayDown &&
+                   iDrawFunction == EFaceBrowser && aType == EEventKey))
+		            {
+		            iDrawFaceBrowsing->DecFaceNumber();
+		            }
+		        else if( (iDrawFunction == EFaceBrowser && aType == EEventKey &&
+                         (imageRotation == -90 || imageRotation == -270)) )
+                    {
+                    if(imageRotation == -90)
+                        iDrawFaceBrowsing->DecFaceNumber();
+                    else
+                        iDrawFaceBrowsing->IncFaceNumber();
+                    }
+                    
+#endif
+		        ResetZoomKeys();
+				break;
+				
+	        case EStdKeyUpArrow:
+	            if(iDrawFunction == EOneByOne && IS_NOT_IN_ZOOM_ONEBYONE){
+	            }
+	            else{
+	            iKeyData.iY-=addValue;
+	            iKeyData.iUp=pressValue;
+	            }
+#ifdef _ACCELEROMETER_SUPPORTED_
+	            if((iDeviceOrientation == EOrientationDisplayDown &&
+                   iDrawFunction == EFaceBrowser && aType == EEventKey))
+	                {
+                   iDrawFaceBrowsing->IncFaceNumber();
+	                }
+	            else if( (iDrawFunction == EFaceBrowser && aType == EEventKey &&
+                         (imageRotation == -90 || imageRotation == -270)) )
+                    {
+                    if(imageRotation == -90)
+                        iDrawFaceBrowsing->IncFaceNumber();
+                    else
+                        iDrawFaceBrowsing->DecFaceNumber();
+                    }
+                
+#endif
+	            ResetZoomKeys();
+				break;
+			
+            //Horisontal movement
+		    case EStdKeyLeftArrow:
+			    if(
+#ifdef _ACCELEROMETER_SUPPORTED_
+			       (iDeviceOrientation == EOrientationDisplayLeftUp &&
+#endif
+			       iDrawFunction == EFaceBrowser && aType == EEventKey) ||
+			       
+			       (iDrawFunction == EFaceBrowser && aType == EEventKey &&
+                   imageRotation == (imageRotation == -90 || imageRotation == -270)) )
+			        {
+			        iDrawFaceBrowsing->DecFaceNumber();
+			        }
+			    iKeyData.iX-=addValue;
+			    iKeyData.iLeft=pressValue;
+                ResetZoomKeys();
+			    break;
+				
+			case EStdKeyRightArrow:
+			    if(
+#ifdef _ACCELEROMETER_SUPPORTED_
+			       (iDeviceOrientation == EOrientationDisplayLeftUp &&
+#endif
+			       iDrawFunction == EFaceBrowser && aType == EEventKey) ||
+			       
+			       (iDrawFunction == EFaceBrowser && aType == EEventKey &&
+                   imageRotation == (imageRotation == -90 || imageRotation == -270)) )
+			        {
+			       iDrawFaceBrowsing->IncFaceNumber();
+			        }
+			    iKeyData.iX+=addValue;
+			    iKeyData.iRight=pressValue;
+                ResetZoomKeys();
+			    break;
+			
+			// Rotation
+#if 1
+			case '1':
+			case 'A':
+			case EStdKeyNkp1:
+			    {
+			    if (/*aType==EEventKey *//*|| aType==EEventKeyUp || */aType==EEventKeyDown)
+			        {
+                    CImageData* imageData = iIEngine->GetImageData(iImagicAppUi->GetImageIndex());
+                    TInt rotAngle = imageData->GetOrientation();
+                    imageData->SetOrientation((rotAngle + 90)%360);
+                    iIEngine->SetImageRotation(iImagicAppUi->GetImageIndex());
+                    iIEngine->SetDBChanged(imageData);
+			        }
+			    
+				ResetZoomKeys();
+				ResetDirKeyData();
+			    break;
+			    }
+
+			case '3':
+			case 'S':
+			case EStdKeyNkp3:
+			    {
+			    if (/*aType==EEventKey *//*|| aType==EEventKeyUp || */aType==EEventKeyDown)
+			        {
+                    CImageData* imageData = iIEngine->GetImageData(iImagicAppUi->GetImageIndex());
+                    TInt rotAngle = imageData->GetOrientation();
+                    imageData->SetOrientation((rotAngle + 270)%360);
+                    iIEngine->SetImageRotation(iImagicAppUi->GetImageIndex());
+                    iIEngine->SetDBChanged(imageData);
+			        }
+			                    
+				ResetZoomKeys();
+				ResetDirKeyData();
+				break;
+			    }
+#endif		
+
+			case EStdKeySpace:
+			case EKeySpace:
+			case '0':
+			case EStdKeyNkp0:
+#ifdef _ACCELEROMETER_SUPPORTED_
+			    //Check that accelerometer did not found by engine
+			    DP0_IMAGIC(_L("CImagicContainerBrowser::OfferKeyEvent - rotate pressed"));
+			    if(!iIEngine->IsAccelerometerExists() && aType == EEventKeyDown)
+			        {
+			        if(iIEngine->GetDeviceOrientation() == EOrientationDisplayLeftUp)
+                        iIEngine->SetDeviceOrientation(EOrientationDisplayDown);
+                    else if(iIEngine->GetDeviceOrientation() == EOrientationDisplayDown)
+                        iIEngine->SetDeviceOrientation(EOrientationDisplayLeftUp);
+                    }
+			    
+			    ResetZoomKeys();
+			    ResetDirKeyData();
+#endif
+				break;
+				
+			//case EStdKeySpace:
+            //case EKeySpace:
+			case 'M':	
+			    if(aType == EEventKeyDown)
+			        {
+                    iView->ProcessCommandL(EAknSoftkeyOptions);
+                    ResetZoomKeys();
+                    ResetDirKeyData();
+			        }
+				break;
+				
+			// Zooming
+			case 'Q':
+			case EStdKeyNkpAsterisk:
+			case '*':
+			case EStdKeyIncVolume:
+			    
+			    ResetDirKeyData();
+			    
+			    if(iDrawFunction == EOneByOne)
+			        {
+			        //iKeyData.iZoom+=addValue;
+			        //iKeyData.iZoomIn=pressValue;
+			        iKeyData.iZoomInKey=ETrue;
+			        iKeyData.iZoomOutKey=EFalse;
+			        }
+			    if(iDrawFunction == EGrid)
+			        {
+			        //Open one by one mode
+			        iDrawOneByOne->InitDrawOnebyOne(KInitDrawZoom/*drawZoom*/, inPictureX, inPictureY);
+                    //Set Grid view
+                    if(iDrawFunction == EFaceBrowser)
+                        {
+                        //iDrawFunction = EGrid;
+                        SetDrawMode(EGrid);
+                        }
+                    
+                    iView->SetFaceBrowsingMode(EFaceBrowserNone);
+                    }
+			    //ResetDirKeyData();
+				break;
+			
+            case 'W':
+            case EStdKeyHash:
+			case '#':
+			case EStdKeyDecVolume:
+			    
+			    ResetDirKeyData();
+			    
+			    if(iDrawFunction == EOneByOne)
+			        {
+			        //iKeyData.iZoom-=addValue;
+			        //iKeyData.iZoomOut=pressValue;
+			        iKeyData.iZoomInKey=EFalse;
+			        iKeyData.iZoomOutKey=ETrue;
+			        }
+			        
+			    if(iDrawFunction == EOneByOne && IS_NOT_IN_ZOOM_ONEBYONE && aType == EEventKeyDown)
+			        {
+/*#ifdef SUPERZOOM
+                    iIEngine->CancelFullSizeLoading();
+                    
+                    //Unload high res textures when going back to Grid
+                    CImageData* aGridData = iIEngine->GetImageData(iCurrentIndex); 
+                    iTextureLoader->ReleaseSuperHResTexture( aGridData );
+#endif*/  
+                    //Return to previous mode
+                    iDrawGrid->InitDrawGrid();
+                    SetDrawMode(EGrid);
+                    
+                    iView->SetFaceBrowsingMode(EFaceBrowserNone);
+			        }
+			    //ResetDirKeyData();
+				break;
+			
+			/*case 'F':
+				iView->HandleCommandL(EImagicCmdViewFaceBrowsing);
+				break;*/
+			
+			case EKeyBackspace:
+			case EStdKeyBackspace:
+                iView->HandleCommandL(EImagicCmdViewBrowserDelete);
+                ResetZoomKeys();
+                ResetDirKeyData();
+                break;
+                
+			case 'I':
+			    if(aType == EEventKeyDown)
+			        {
+                    iView->HandleCommandL(EImagicCmdViewBrowserShowImageInfo);
+                    ResetZoomKeys();
+                    ResetDirKeyData();
+			        }
+                break;
+                
+                
+			// Selection
+            case EStdKeyEnter:
+			case EKeyEnter:
+			case EStdKeyDevice3: //rocker selection key
+                if (aType == EEventKey)
+                    {
+                    HandleDrawingModeSwitch(iDrawFunction);
+                    }
+                ResetZoomKeys();
+                ResetDirKeyData();
+			break;
+			
+			default:
+				// Unknown key, it was not consumed
+				ret = EKeyWasNotConsumed;
+				ResetZoomKeys();
+				ResetDirKeyData();
+				break;
+			}
+		}
+		
+    DrawNow();
+	
+    return ret;
+    }
+
+void CImagicContainerBrowser::HandleDrawingModeSwitch(TDrawFunction& aDrawFunction)
+    {
+    //EGrid
+    if(aDrawFunction == EGrid)
+        {
+        //Open one by one mode
+        iDrawOneByOne->InitDrawOnebyOne(KInitDrawZoom/*drawZoom*/, inPictureX, inPictureY);
+        
+        //Set Grid view
+        if(aDrawFunction == EFaceBrowser)
+            SetDrawMode(EGrid);
+            //aDrawFunction = EGrid;
+        
+        iView->SetFaceBrowsingMode(EFaceBrowserNone);
+        }
+    
+    //EOneByOne
+    else if(aDrawFunction == EOneByOne)
+        {
+        if(IS_NOT_IN_ZOOM_ONEBYONE)
+            {
+            //Return to previous mode
+            iDrawGrid->InitDrawGrid();
+            //aDrawFunction = EGrid;
+            SetDrawMode(EGrid);
+            iView->SetFaceBrowsingMode(EFaceBrowserNone);
+            }
+        else
+            {
+            iDrawOneByOne->SetDrawOneByOneTargetZoom(1);
+            }
+            
+        }
+    
+    //EFaceBrowser
+    else if(aDrawFunction == EFaceBrowser)
+        {
+        SetDrawMode(EOneByOne);
+        //aDrawFunction = EOneByOne;
+        iDrawOneByOne->InitDrawOnebyOne(/*KInitDrawZoom*/drawZoom, inPictureX, inPictureY);
+        iView->SetFaceBrowsingMode(EFaceBrowserNone);
+        }
+    }
+
+void CImagicContainerBrowser::SetFullScreen()
+    {
+    SetExtentToWholeScreen();
+    }
+
+void CImagicContainerBrowser::HandleRotation(float& aRotationAngle, float& aTargetRotationAngle)
+    {
+	// Force target to be in steps of 90
+	aTargetRotationAngle=((int)(aTargetRotationAngle/90))*90;
+	
+	// Force both angles to be between 0-360
+	while (aRotationAngle<0)			aRotationAngle+=360;
+	while (aRotationAngle>360)			aRotationAngle-=360;
+	while (aTargetRotationAngle<0)		aTargetRotationAngle+=360;
+	while (aTargetRotationAngle>360)	aTargetRotationAngle-=360;
+	
+	// Calculate difference between angles
+	float diff=aTargetRotationAngle-aRotationAngle;
+	// Limit difference to be between [-180:180]
+	while (diff<-180)		diff+=360;
+	while (diff>180)		diff-=360;
+	
+	// Copy paste from Interpolate, just uses diff calculated above
+	float aStep=0.26;
+	float timediff = Min(0.1f, iTimeDiff); // so max value of timediff is 100tick (100ms)
+	aRotationAngle += diff * aStep * timediff * 30;
+	
+	// Calculate new difference
+	float newDiff=aTargetRotationAngle-aRotationAngle;
+	while (newDiff<-180)	newDiff+=360;
+	while (newDiff>180)		newDiff-=360;
+	// If difference-angles have different signs, then we went past the target angle
+	if (diff*newDiff < 0)
+		aRotationAngle = aTargetRotationAngle;
+	}
+
+TBool CImagicContainerBrowser::IsOpenGLInit()
+    {
+    return iOpenGlInitialized;
+    }
+
+//Disables display drawing
+void CImagicContainerBrowser::EnableDisplayDraw()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::EnableDisplayDraw++"));
+    
+    if(!iPeriodic->IsActive())
+        iPeriodic->Start( 1, iDisplayDrawFreq, TCallBack( CImagicContainerBrowser::DrawCallBackL, this ) );
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::EnableDisplayDraw--"));
+    }
+
+//Enables display drawing
+void CImagicContainerBrowser::DisableDisplayDraw()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DisableDisplayDraw++"));
+    
+    if(iPeriodic)
+        if(iPeriodic->IsActive())
+            {
+            iPeriodic->Cancel();
+            //Clear buffers
+            //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+            }
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::DisableDisplayDraw--"));
+    }
+
+void CImagicContainerBrowser::SetDrawMode(TDrawFunction aDrawFunction)
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetDrawMode++"));
+    
+    ResetZoomKeys();
+    ResetDirKeyData();
+    
+    if(/*aDrawFunction == EOneByOne && */!IS_NOT_IN_ZOOM_ONEBYONE)
+        {
+        iDrawOneByOne->SetDrawOneByOneTargetZoom(1);
+        }
+    else
+        {
+        iDrawFunction = aDrawFunction;
+        }
+    
+    if(aDrawFunction == EGrid)
+        {
+        iPreferHighResLoading = EFalse;
+#ifdef SUPERZOOM
+        iIEngine->CancelFullSizeLoading();
+        
+        //Unload high res textures when going back to Grid
+        CImageData* aGridData = iIEngine->GetImageData(iCurrentIndex); 
+        iTextureLoader->ReleaseSuperHResTexture( aGridData );
+#endif
+        iDrawGrid->InitDrawGrid();
+        }
+    
+    DrawNow();
+    
+    DP0_IMAGIC(_L("CImagicContainerBrowser::SetDrawMode--"));
+    }
+
+CImagicContainerBrowser::TDrawFunction CImagicContainerBrowser::GetDrawMode()
+    {
+    return iDrawFunction;
+    }
+
+
+void CImagicContainerBrowser::SetBGPSStatus(TBool aValue)
+    {
+    //False = BGPS is running
+    //True = BGPS is completed
+    iTNCreationComplete = aValue;
+    }
+
+CTextureLoader* CImagicContainerBrowser::GetTextureLoader()
+    {
+    return iTextureLoader;
+    }
+
+float CImagicContainerBrowser::GetAspectRatio(TInt aIndex)
+    {
+    return iIEngine->GetImageData(aIndex)->GetAspectRatio();
+    }
+
+void CImagicContainerBrowser::SetFaceCoords(RArray<TRect>& aCoordinates)
+    {
+    iDrawFaceBrowsing->SetFaceCoords(aCoordinates);
+    }
+
+void CImagicContainerBrowser::ClearFaceArray()
+    {
+    iDrawFaceBrowsing->ClearFaceArray();
+    }
+
+void CImagicContainerBrowser::SetTextIndex(GLuint aIndex)
+    {
+    iCurrentBindedIndex = aIndex;
+    }
+
+#ifdef _ACCELEROMETER_SUPPORTED_
+
+TImagicDeviceOrientation CImagicContainerBrowser::GetDeviceOrientation()
+    {
+    return iDeviceOrientation;    
+    }
+
+
+void CImagicContainerBrowser::PhoneRotated(TImagicDeviceOrientation aDeviceOrientation)
+    {
+    /*if(iDeviceOrientation == aDeviceOrientation)
+        {
+        return;
+        }*/
+    
+    iDeviceOrientation = aDeviceOrientation;
+    
+    //iDrawGridZoom = KZoomOutMaxGrid;//Set initial zooming value when draving Grid
+#ifdef ENABLE_GRID_ZOOM
+#ifdef ZOOM_WHILE_ROTATING
+    if(iDrawFunction == EGrid)
+        iDrawGridTargetZoom = KZoomOutMaxGrid;
+#endif
+#endif
+    
+    if(iDrawFunction == EOneByOne)
+        {
+        //Set currect rotation angle immeadetly to target, except for current image index
+        TInt num = iIEngine->GetTotalNumOfImages();
+        for(TInt i=0; i < num; i++ )
+            {
+            if(i != iCurrentIndex)
+                {
+                CImageData* data = iIEngine->GetImageData(i);
+                data->iGridData.iRotationAngle = data->iGridData.iTargetRotationAngle;
+                }  
+            }
+        }
+    else if(iDrawFunction == EFaceBrowser)
+        {
+        //Do nothing
+        }
+    else if(iDrawFunction == EGrid)
+        {
+        //Do nothing
+        }
+    
+    //DrawScreen();
+    DrawNow();
+    }
+
+#endif
+
+void CImagicContainerBrowser::IconTexturesLoaded(RArray<GLuint> aIconTextureIndexes)
+    {
+    for(TInt i=0; i<aIconTextureIndexes.Count(); i++)
+        {
+        iIconTextureIndexes.Append(aIconTextureIndexes[i]);        
+        }
+    }
+
+void CImagicContainerBrowser::HandleSend2BackgroundEvent()
+    {
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandleSend2BackgroundEvent++"));
+    
+    //Cancel SuperZoom image loading, if it was started
+    iIEngine->CancelFullSizeLoading();
+    /*
+    //Delete OpenGL memory allocations
+    TInt num = iIEngine->GetTotalNumOfImages();
+    for(TInt i=0; i < num; i++ )
+        {
+        CImageData* data = iIEngine->GetImageData(i);
+        
+        if(data->iGridData.iGlHQ512TextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlHQ512TextIndex);
+        if(data->iGridData.iGlSuperHQTextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlSuperHQTextIndex);
+        
+        data->iGridData.iGlHQ512TextIndex = 0;
+        data->iGridData.iGlSuperHQTextIndex = 0;
+        }
+    */
+    
+    //Delete OpenGL memory allocations
+    TInt num = iIEngine->GetTotalNumOfImages();
+    for(TInt i=0; i < num; i++ )
+        {
+        CImageData* data = iIEngine->GetImageData(i);
+        
+        if(data->iGridData.iGlLQ128TextIndex)
+            glDeleteTextures( 1, &data->iGridData.iGlLQ128TextIndex );
+        if(data->iGridData.iGlLQ32TextIndex)
+            glDeleteTextures( 1, &data->iGridData.iGlLQ32TextIndex );
+        if(data->iGridData.iGlHQ512TextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlHQ512TextIndex);
+        if(data->iGridData.iGlSuperHQTextIndex != 0)
+            glDeleteTextures(1, &data->iGridData.iGlSuperHQTextIndex);
+        
+        data->iGridData.iGlLQ32TextIndex = 0;
+        data->iGridData.iGlLQ128TextIndex = 0;
+        data->iGridData.iGlHQ512TextIndex = 0;
+        data->iGridData.iGlSuperHQTextIndex = 0;
+        }
+        
+        
+    DP0_IMAGIC(_L("CImagicContainerBrowser::HandleSend2BackgroundEvent--"));
+    
+    }
+
+
+/*
+void CImagicContainerBrowser::MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct)
+    {
+    TBool pressValue=EFalse;
+    
+    switch(aOperationId)
+        {
+        case ERemConCoreApiVolumeDown: 
+            {
+            //do your own stuff
+            iKeyData.iZoom-=1;
+            iKeyData.iZoomOut=ETrue;
+            break;
+            }
+        case ERemConCoreApiVolumeUp:
+            {
+            //do your own stuff
+            iKeyData.iZoom+=1;
+            iKeyData.iZoomIn=ETrue;
+            break;
+            }
+        }
+
+    }
+    */
+
+
+TBool CImagicContainerBrowser::GetSlideByDragValue()
+    {
+    return iOneByOneSlideByDrag;    
+    }
+
+TInt CImagicContainerBrowser::GetCurrentIndex()
+    {
+    return iCurrentIndex;    
+    }
+
+TInt CImagicContainerBrowser::GetPrevIndex()
+    {
+    return iPreviousIndex;    
+    }
+
+void CImagicContainerBrowser::SetCurrentIndex(TInt aIndex)
+    {
+    CheckIndexLimits(aIndex);
+    iCurrentIndex = aIndex;    
+    }
+
+void CImagicContainerBrowser::CheckIndexLimits(TInt &aIndex)
+    {
+    //Check that current index is in grid area
+    TInt num = iIEngine->GetTotalNumOfImages();
+    
+    if(!iJumpOver)
+        {
+        if(aIndex >= num)
+            {
+            aIndex = num-1;
+            iIntheEndOfGrid=ETrue;
+            }
+        if(aIndex < 0)
+            {
+            aIndex = 0;
+            iIntheEndOfGrid=ETrue;
+            }
+        }
+    else//if(iJumpOver)
+        {
+        if (num)
+            {
+            aIndex %= num;
+            if (aIndex < 0)
+                aIndex = num + aIndex;
+            }
+        }
+    }
+
+void CImagicContainerBrowser::SetPrevIndex(TInt aIndex)
+    {
+    iPreviousIndex = aIndex;
+    }
+
+
+CKeyData& CImagicContainerBrowser::GetKeyData()
+    {
+    return iKeyData;
+    }
+
+void CImagicContainerBrowser::SetKeyData(CKeyData aData)
+    {
+    iKeyData = aData;
+    }
+
+void CImagicContainerBrowser::ResetKeyData()
+    {
+    iKeyData.iRotate=0;
+    
+    iKeyData.iX=0;
+    iKeyData.iY=0;
+    }
+
+void CImagicContainerBrowser::ResetDirKeyData()
+    {
+    iKeyData.iUp=0;
+    iKeyData.iDown=0;
+    iKeyData.iLeft=0;
+    iKeyData.iRight=0;
+    }
+    
+CKeyData& CImagicContainerBrowser::GetTouchData()
+    {
+    return iTouchMoveData;
+    }
+
+void CImagicContainerBrowser::SetTouchData(CKeyData aData)
+    {
+    iTouchMoveData = aData;
+    }
+
+void CImagicContainerBrowser::ResetTouchData()
+    {
+    iTouchMoveData.iRotate=0;
+    iTouchMoveData.iX=0;
+    iTouchMoveData.iY=0;
+    iTouchMoveData.iZoomInKey=0;
+    iTouchMoveData.iZoomOutKey=0;
+    iTouchMoveData.iRight = EFalse;
+    iTouchMoveData.iLeft = EFalse;
+    iTouchMoveData.iUp = EFalse;
+    iTouchMoveData.iDown = EFalse;
+    }
+
+
+TInt CImagicContainerBrowser::GetGleMaxRes()
+    {
+    return iGLMaxRes;
+    }
+
+TBool CImagicContainerBrowser::IsUserInputGiven()
+    {
+    return iUserInputGiven;
+    }
+
+
+TSize CImagicContainerBrowser::GetScreenSize()
+    {
+    return iScreenSize;
+    }
+
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/ImagicDocument.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// INCLUDE FILES
+#include "ImagicDocument.h"
+#include "ImagicAppUi.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+// constructor
+CImagicDocument::CImagicDocument(CEikApplication& aApp)
+: CAknDocument(aApp)    
+    {
+    
+    }
+
+// destructor
+CImagicDocument::~CImagicDocument()
+    {
+    
+    }
+
+// EPOC default constructor can leave.
+void CImagicDocument::ConstructL()
+    {
+    
+    }
+
+// Two-phased constructor.
+CImagicDocument* CImagicDocument::NewL(CEikApplication& aApp)     // CImagicApp reference
+    {
+ 
+    CImagicDocument* self = new (ELeave) CImagicDocument( aApp );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+    
+// ----------------------------------------------------
+// CImagicDocument::CreateAppUiL()
+// constructs CImagicAppUi
+// ----------------------------------------------------
+//
+CEikAppUi* CImagicDocument::CreateAppUiL()
+    {
+   
+  
+    // Create the application user interface, and return a pointer to it;
+    // the framework takes ownership of this object
+    return ( static_cast <CEikAppUi*> ( new ( ELeave ) CImagicAppUi ) );
+    
+    }
+
+// End of File  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/ImagicViewBrowser.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,920 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+
+// INCLUDE FILES
+#include  <viewcli.h>
+#include  <aknviewappui.h>
+#include  <avkon.hrh>
+#include  <aknquerydialog.h>
+#include  <PhotoBrowser.rsg>
+#include  "ImagicViewBrowser.h"
+#include  "ImagicContainerBrowser.h"
+#include  "Imagic.hrh"
+#include  "ImagicAppUi.h"
+#include  <S32FILE.H> 
+#include  "ImagicUtils.h"
+#include  "SendImageFile.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CImagicViewBrowser::ConstructL(const TRect& aRect)
+// EPOC two-phased constructor
+// ---------------------------------------------------------
+//
+void CImagicViewBrowser::ConstructL(CImagicAppUi* aImagicAppUi)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::ConstructL++"));
+    
+    iImagicAppUi = aImagicAppUi;
+    iApplicationFeature = EAppFeatureNone;
+    iFaceCroppingComplete = ETrue;
+    
+    BaseConstructL( R_IMAGIC_VIEWBROWSER );
+    
+    //Create bitmap for high res image loading
+    iBitmap = new (ELeave) CFbsBitmap();
+#ifdef USE_RGBA
+    iBitmap->Create(TSize(10,10), EColor16MU);
+#else
+    iBitmap->Create(TSize(10,10), EColor16M);
+#endif
+    iTNCreationComplete = EFalse;
+    iFaceBrowsingComplete = EFalse;
+    
+    //For dynamic options menu
+    iEditModeEnabledCmd1 = ETrue;
+    
+    User::LeaveIfError(iFsSession.Connect());
+    
+#ifdef USE_SETTINGS_FILE
+    // Load user settings
+    TRAP_IGNORE(ReadSettingsFileL(KSettingFileName));  
+#endif
+    SetGridMode((TGridMode)iSettings.GetValue(CSettings::ESettingGridMode));
+    
+    DP0_IMAGIC(_L("CImagicViewBrowser::ConstructL--"));
+    }
+
+// ---------------------------------------------------------
+// CImagicViewBrowser::~CImagicViewBrowser()
+// Default destructor
+// ---------------------------------------------------------
+//
+CImagicViewBrowser::~CImagicViewBrowser()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::~ConstructL++"));
+    
+#ifdef USE_SETTINGS_FILE
+    // Save user settings
+    if (iSettings.IsChanged())
+        TRAP_IGNORE(WriteSettingsFileL(KSettingFileName));  
+#endif    
+    
+    if ( iContainer )
+        {
+        AppUi()->RemoveFromViewStack( *this, iContainer );
+        }
+    iBitmap->Reset();
+    delete iBitmap;
+    delete iContainer;
+    iFsSession.Close();
+    
+    iTempCordArray.Close();
+    iCoordinates.Close();
+    
+    DP0_IMAGIC(_L("CImagicViewBrowser::~ConstructL--"));
+    }
+
+// ---------------------------------------------------------
+// TUid CImagicViewBrowser::Id()
+// This returns the view ID
+// ---------------------------------------------------------
+//
+TUid CImagicViewBrowser::Id() const
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::id"));
+    return BrowserView;
+    }
+
+// ---------------------------------------------------------
+// CImagicViewBrowser::HandleCommandL(TInt aCommand)
+// Here we handle commands for this view.
+// Each view has their own HandleCommandL()
+// ---------------------------------------------------------
+//
+void CImagicViewBrowser::HandleCommandL(TInt aCommand)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::HandleCommandL++"));
+    
+    CIEEngine* engine = iImagicAppUi->GetEngine();
+    
+    switch ( aCommand )
+        {
+        iContainer->DrawNow();
+        //case EAknSoftkeyOk:
+        case EAknSoftkeyBack:
+            {
+            if(iContainer->GetDrawMode() == CImagicContainerBrowser::EOneByOne){
+                iContainer->SetDrawMode(CImagicContainerBrowser::EGrid);
+                }
+            else if(iContainer->GetDrawMode() == CImagicContainerBrowser::EFaceBrowser){
+                iContainer->SetDrawMode(CImagicContainerBrowser::EOneByOne);
+                iFaceBrowsingMode = EFaceBrowserNone;
+                }
+            else if(iContainer->GetDrawMode() == CImagicContainerBrowser::EGrid){
+                AppUi()->HandleCommandL(EEikCmdExit);
+                }
+            //iContainer->DrawNow();
+            break;
+            }
+            
+        case EAknSoftkeyExit:
+            {
+            AppUi()->HandleCommandL(EEikCmdExit);
+            break;
+            }
+            
+        case EAknCmdExit:
+            {
+            AppUi()->HandleCommandL(EEikCmdExit);
+            break;
+            }    
+            
+        case EImagicCmdViewBrowserRotateRight:
+            {
+            CImageData* imageData = engine->GetImageData(iImagicAppUi->GetImageIndex());
+            TInt rotAngle = imageData->GetOrientation();
+            imageData->SetOrientation((rotAngle + 270)%360);
+            engine->SetImageRotation(iImagicAppUi->GetImageIndex());
+            engine->SetDBChanged(imageData);
+            break;
+            }
+     
+        case EImagicCmdViewBrowserRotateLeft:
+            {
+            CImageData* imageData = engine->GetImageData(iImagicAppUi->GetImageIndex());
+            TInt rotAngle = imageData->GetOrientation();
+            imageData->SetOrientation((rotAngle + 90)%360);
+            engine->SetImageRotation(iImagicAppUi->GetImageIndex());
+            engine->SetDBChanged(imageData);
+            break;
+            }
+     
+        //Deleting the Image...
+        case EImagicCmdViewBrowserDelete:
+            {
+            iContainer->DisplayDeleteQueryDialogL(R_DELETE_QUERY);
+            break;
+            }
+
+        //Switch grid mode 
+        case EImagicCmdViewBrowserGridModeFolder:
+            SetGridMode(EGridModeFolder);
+            break;
+            
+        case EImagicCmdViewBrowserGridModeTime:
+            SetGridMode(EGridModeTime);
+            break;
+
+        case EImagicCmdViewBrowserGridModePeople:
+            SetGridMode(EGridModePeople);
+            break;          
+            
+        //Show Image info
+        case EImagicCmdViewBrowserShowImageInfo:
+            {
+            //Get image Info ----------------->
+            
+            const TInt KMaxInfoFileNameLength = 50;
+            
+            TBuf<1024> buf;
+            //TPtr ptr(buf.Des());
+            TFileName fileName;
+            CImageData* imageData = engine->GetImageData(iImagicAppUi->GetImageIndex());
+            imageData->GetFileName(fileName, EFullSize);
+            
+            // Make file name shorter if doesn't fit to info box well
+            if (fileName.Length() > KMaxInfoFileNameLength)
+                {
+                for(TInt i = fileName.Length() - KMaxInfoFileNameLength;i < fileName.Length();i++)
+                    {
+                    if (i > 3 && fileName[i] == '\\')
+                        {
+                        fileName.Replace(3, i - 3, _L("..."));
+                        break;
+                        }
+                    }
+                }
+            
+            buf.Append(fileName);
+            buf.Append(_L("\n"));     
+            
+            TDateTime dateTime = imageData->GetCreatedTime().DateTime();
+            TInt year, month, day, hour, minute, second;
+            day = dateTime.Day() + 1;
+            month = dateTime.Month() + 1;
+            year = dateTime.Year();
+            hour = dateTime.Hour();
+            minute = dateTime.Minute();
+            second = dateTime.Second();
+            
+            TLocale locale;
+            TDateFormat dateFormat = locale.DateFormat();
+
+            TBuf<20> num1, num2, num3;
+            switch (dateFormat)
+                {
+                case EDateEuropean:
+                    num1.Num(day);
+                    buf.Append(num1); 
+                    buf.Append(locale.DateSeparator(1));
+                    num1.Num(month);
+                    buf.Append(num1); 
+                    buf.Append(locale.DateSeparator(2));
+                    num1.Num(year);
+                    buf.Append(num1);
+                    break;
+
+                case EDateAmerican:
+                    num1.Num(month);
+                    buf.Append(num1); 
+                    buf.Append(locale.DateSeparator(1));
+                    num1.Num(day);
+                    buf.Append(num1); 
+                    buf.Append(locale.DateSeparator(2));
+                    num1.Num(year);
+                    buf.Append(num1); 
+                    break;
+                
+                case EDateJapanese:
+                    num1.Num(year); 
+                    buf.Append(num1); 
+                    buf.Append(locale.DateSeparator(1));
+                    num1.Num(day); 
+                    buf.Append(num1); 
+                    buf.Append(locale.DateSeparator(2));
+                    num1.Num(month); 
+                    buf.Append(num1); 
+                    break;
+                }
+            buf.Append(KSpace);
+            
+            TTimeFormat timeFormat = locale.TimeFormat();
+            num2.Num(minute); if(minute < 10) num2.Insert(0, _L("0"));
+            num3.Num(second); if(second < 10) num3.Insert(0, _L("0"));
+            if (timeFormat == ETime12)
+                {
+                num1.Num(hour > 12 ? hour - 12 : hour);
+                if (locale.AmPmSymbolPosition() == ELocaleBefore)
+                    {
+                    buf.Append(hour < 12 ? _L("AM") : _L("PM"));
+                    if (locale.AmPmSpaceBetween()) 
+                        buf.Append(KSpace);
+                    buf.Append(num1);
+                    buf.Append(locale.TimeSeparator(1));
+                    buf.Append(num2);
+                    buf.Append(locale.TimeSeparator(2));
+                    buf.Append(num3);                    
+                    }
+                else
+                    {
+                    buf.Append(num1);
+                    buf.Append(locale.TimeSeparator(1));
+                    buf.Append(num2);
+                    buf.Append(locale.TimeSeparator(2));
+                    buf.Append(num3);
+                    if (locale.AmPmSpaceBetween()) 
+                        buf.Append(KSpace);
+                    buf.Append(hour < 12 ? _L("AM") : _L("PM"));                    
+                    }
+                }
+            else
+                {
+                num1.Num(hour);                
+                buf.Append(num1);
+                buf.Append(locale.TimeSeparator(1));            
+                buf.Append(num2);
+                buf.Append(locale.TimeSeparator(2));            
+                buf.Append(num3);                
+                }
+            buf.Append(KNewLine);            
+
+            num1.Num(imageData->GetSize().iWidth); 
+            num2.Num(imageData->GetSize().iHeight);
+            buf.Append(num1);
+            buf.Append(_L(" x "));
+            buf.Append(num2);            
+            
+            //buf.Append(_L("\n"));
+            //dateTime.TDateTime(aYear, aMonth, aDay, aHour, aMinute, aSecond, aMicroSecond);
+                    
+            iImagicAppUi->GetImagicUtils()->ExecutePopUpNote(buf, 10000, iContainer->GetScreenOrientation());
+            break;
+            }
+
+        //FaceBrowsing          
+        case EImagicCmdViewFaceBrowsing:
+            {
+            //Set Face Browsing Mode
+            //iFaceBrowsingMode = EFaceBrowsing;
+            iFaceBrowsingMode = EFaceBrowsingShowRect;
+            iContainer->InitFaceBrowsing();
+            
+            //Clear if face browser had old data
+            iContainer->ClearFaceArray();
+            ResetFaceCoords();
+            
+            //Get the file for FB processing
+            TFileName fileName;
+            engine->GetFileNameL(iImagicAppUi->GetImageIndex(), ESize512x512, fileName);
+
+            //Check if background face browsing is still going on 
+            //if(iFaceBrowsingComplete)
+                {
+                //If face browsing is complete just get face coordinates
+                engine->GetFaceCoordinates(fileName, iCoordinates);
+                
+                if(iCoordinates.Count() >= 1)
+                    {
+                    if(iContainer)
+                        iContainer->SetFaceCoords(iCoordinates);
+                    
+                    iContainer->SetDrawMode(CImagicContainerBrowser::EFaceBrowser);
+                    }
+                else
+                    {
+                    iImagicAppUi->GetImagicUtils()->ShowInfoNote(R_IMAGE_EDITOR_NO_FACES_FOUND_TEXT);
+                    }
+                }
+            break;
+            }
+
+// unno begin
+//#ifdef DOUBLETAP_FACEBROWSING
+        //FaceBrowsing with coordinates          
+        case EImagicCmdViewFaceBrowsingWithCoordinates:
+            {
+            CImageData* imageData = engine->GetImageData(iImagicAppUi->GetImageIndex());
+            if(imageData->IsImageReady(ESize512x512))
+                {
+                //Get the original file, and reset local coord storage
+                TFileName fileName;
+                engine->GetFileNameL(iImagicAppUi->GetImageIndex(), ESize512x512, fileName);
+                
+                ResetFaceCoords();
+                
+                //Check if background face browsing is still going on 
+                if(/*iFaceBrowsingComplete &&*/ iContainer) // also make sure container exists
+                    {
+                    //ResetFaceCoords();
+                    
+                    //If face browsing is complete just get face coordinates
+                    engine->GetFaceCoordinates(fileName, iCoordinates);
+                    
+                    if(iCoordinates.Count() >= 1)
+                        {
+                        iContainer->SetFaceCoords(iCoordinates);
+
+                        TInt faceid;
+                        if (iContainer->FindNearestFace(iContainer->GetLastTouchPoint(), faceid))
+                            {
+                            // start face browsing view if there are faces
+                            iContainer->SetDrawMode(CImagicContainerBrowser::EFaceBrowser);
+                            iContainer->SetCurrentFaceNro(faceid);
+                            //iFaceBrowsingMode = EFaceBrowsing;
+                            iFaceBrowsingMode = EFaceBrowsingShowRect;
+                            iContainer->InitFaceBrowsing();
+
+                            //unno
+                            DP0_IMAGIC(_L(" ------------------ Face browsing"));
+                            }
+                        else
+                            {
+                            DP1_IMAGIC(_L(" ------------------ No near faces (%d)"), faceid);
+                            }
+                        }
+                    else
+                        {
+                        DP0_IMAGIC(_L(" ------------------ No faces in picture"));
+                        }
+                    }
+                else
+                    {
+                    //Prioritise face browsing of selected picture if background process not completed 
+                    iContainer->ClearFaceArray();
+                    
+                    DP0_IMAGIC(_L(" ------------------ Background process ongoing"));
+                    }
+                }
+            break;
+            }
+//#endif
+
+        //Remove false face detection Coords from exif data
+        case EImagicCmdViewBrowserRemoveFace:
+            {
+            break;
+            }
+            
+        //Add new face detection to exif data
+        case EImagicCmdViewBrowserAddNewFace:
+            {
+            //Set Face Browsing Mode
+            iFaceBrowsingMode = EFaceBrowsingAddNewFace;
+            iImagicAppUi->GetImagicUtils()->ExecutePopUpNote(R_IMAGE_ADD_NEW_FACE_HELP_TEXT, 15000);
+                        
+            //Just set draw mode as oneByOne here
+            iContainer->SetDrawMode(CImagicContainerBrowser::EOneByOne);
+            break;
+            }
+
+        //Add as new face to exif data
+        case EImagicCmdViewBrowserAddAsThisNewFace:
+            {
+            break;
+            }
+        
+        //Face cropping
+        case EImagicCmdViewBrowserFaceCropping:
+            {
+            iContainer->SetBGPSStatus(EFalse);
+            
+            iFaceCroppingComplete = EFalse;
+            //iImagicAppUi->GetEngine()->StartFaceCropping(iImagicAppUi->GetImageIndex());
+            break;
+            }
+            
+        case EImagicCmdViewBrowserHelp:
+            {
+            CArrayFix<TCoeHelpContext>* buf = iImagicAppUi->AppHelpContextL();
+            //TBuf<10> buf;
+            HlpLauncher::LaunchHelpApplicationL(iEikonEnv->WsSession(), buf);
+            break;
+            }
+            
+        case EImagicCmdViewBrowserSend:
+            {
+            TFileName imageFileName;
+            
+            iImagicAppUi->GetEngine()->GetFileNameL(iContainer->GetCurrentIndex(), EFullSize, imageFileName);
+            
+            CSendImageFile *sender;
+            sender = CSendImageFile::NewL();
+            sender->SendFileViaSendUiL(imageFileName);
+            delete sender;
+            break;
+            }
+
+        default:
+            {
+            AppUi()->HandleCommandL( aCommand );
+            break;
+            }
+        }
+    DP0_IMAGIC(_L("CImagicViewBrowser::HandleCommandL--"));
+    }
+
+void CImagicViewBrowser::SetGridMode(TGridMode aGridMode)
+    {
+    CIEEngine* engine = iImagicAppUi->GetEngine();
+    CIEImageList& imageList = engine->GetImageList();
+    //if (imageList.IsGroupingFolders() != aEnable)
+        {
+        iSettings.SetValue(CSettings::ESettingGridMode, aGridMode);
+        
+        CImageData* imageData = NULL;
+        TInt index = 0;
+        
+        if (iContainer)
+            {
+            // Get index of currently selected image
+            index = iContainer->GetCurrentIndex();
+            if (iContainer->IsUserInputGiven())
+                imageData = engine->GetImageData(iContainer->GetCurrentIndex());
+            }
+        
+        imageList.SetGridMode(aGridMode); 
+        
+        if (iContainer)
+            {
+            // Update grid order
+            iContainer->ImageListChanged(0, EFalse);
+            
+            // Set index of same image in new grid
+            if (imageData)
+                {
+                index = imageList.GetImageIndex(imageData);
+                iContainer->SetCurrentIndex(index);
+                }
+            }
+        }
+    }
+
+/*
+void CImagicViewBrowser::SingleFaceBrowsingComplete()
+    {
+    //iImagicAppUi->GetEngineL()->GetFaceCoordinates(tmpFileName, iCoordinates);
+    
+    if(iCoordinates.Count() >= 1)
+        {
+        if(iContainer)
+            iContainer->SetFaceCoords(iCoordinates);
+        
+        iContainer->SetDrawMode(CImagicContainerBrowser::EFaceBrowser);
+        }
+    else
+        {
+        iImagicAppUi->GetImagicUtils()->ShowInfoNote(R_IMAGE_EDITOR_NO_FACES_FOUND_TEXT);
+        //DisplayAddFacesQueryDialogL(R_ADD_FACE_MANUALLY_QUERY);
+        }
+    }
+*/
+
+
+void CImagicViewBrowser::DisplayAddFacesQueryDialogL(TInt aResourceId)
+    {
+    CAknQueryDialog* dlg;
+    dlg = new ( ELeave ) CAknQueryDialog();
+    TInt result = dlg->ExecuteLD( aResourceId );
+    
+    if(result != KErrNone)
+        {
+        iFaceBrowsingMode = EFaceBrowsingAddNewFace;
+        //iImagicAppUi->GetImagicUtils()->ShowInfoNote(R_IMAGE_ADD_NEW_FACE_HELP_TEXT);
+        iImagicAppUi->GetImagicUtils()->ExecutePopUpNote(R_IMAGE_ADD_NEW_FACE_HELP_TEXT, 15000);
+        }
+    else
+        {
+        iFaceBrowsingMode = EFaceBrowserNone;                    
+        }
+    }
+
+void CImagicViewBrowser::SetFaceBrowsingMode(TFaceBrowsingModes aMode)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::SetFaceBrowsingMode"));
+    iFaceBrowsingMode = aMode;
+    }
+
+TFaceBrowsingModes CImagicViewBrowser::GetFaceBrowsingMode()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::GetFaceBrowsingMode"));
+    return iFaceBrowsingMode;
+    }
+
+
+// ---------------------------------------------------------
+// CImagicViewBrowser::HandleClientRectChange()
+// ---------------------------------------------------------
+//
+void CImagicViewBrowser::HandleClientRectChange()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::HandleClientRectChange++"));
+    if ( iContainer )
+        {
+        iContainer->SetRect( ClientRect() );
+        iContainer->SetFullScreen();
+        }
+    DP0_IMAGIC(_L("CImagicViewBrowser::HandleClientRectChange--"));
+    }
+
+// ---------------------------------------------------------
+// CImagicViewBrowser::DoActivateL(...)
+// This is called when a view needs to be activated.
+// This creates container with its controls.
+// ---------------------------------------------------------
+//
+void CImagicViewBrowser::DoActivateL(
+   const TVwsViewId& /*aPrevViewId*/,TUid /*aCustomMessageId*/,
+   const TDesC8& /*aCustomMessage*/)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::DoActivateL++"));
+    
+    // Create Container
+    if (!iContainer)
+        {
+        DP0_IMAGIC(_L("CImagicViewBrowser::DoActivateL - create container"));
+        iContainer = new (ELeave) CImagicContainerBrowser;
+        iContainer->SetMopParent(this);
+        iContainer->ConstructL( iImagicAppUi, this, ClientRect() );
+        AppUi()->AddToStackL( *this, iContainer );
+        
+        if(iTNCreationComplete)
+            iContainer->SetBGPSStatus(ETrue);
+        else
+            iContainer->SetBGPSStatus(EFalse);
+        }
+    
+    iImagicAppUi->CImagicAppUiReady();
+    iImagicAppUi->BrowserContainerInitialized();
+    
+    DP0_IMAGIC(_L("CImagicViewBrowser::DoActivateL--"));
+   }
+
+// ---------------------------------------------------------
+// CImagicViewBrowser::HandleCommandL(TInt aCommand)
+// This is called when a view needs to be deactivated.
+// This destroys container with its controls.
+// ---------------------------------------------------------
+//
+void CImagicViewBrowser::DoDeactivate()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::DoDeactivate++"));
+    if ( iContainer )
+        {
+        AppUi()->RemoveFromViewStack( *this, iContainer );
+        delete iContainer;
+        iContainer = NULL;
+        }
+    DP0_IMAGIC(_L("CImagicViewBrowser::DoDeactivate--"));
+    }
+
+
+// Set bitmap to draw
+void CImagicViewBrowser::SetActiveViewL(TUid /*aViewNro*/)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::SetActiveView"));
+    AppUi()->ActivateLocalViewL(BrowserView);
+    }
+
+//void CImagicViewBrowser::LoadBitmapsToBrowserL(TInt aIndex, TBool aHighRes)
+void CImagicViewBrowser::LoadBitmapsToBrowserL(CImageData* aImageData, TThumbSize aImageResolution)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::LoadBitmapsToBrowserL++"));
+    
+    ASSERT(iContainer);
+    
+    if (iContainer)
+        {
+        iImagicAppUi->GetEngine()->GetBitmapL(aImageData, iBitmap, aImageResolution);
+        iImageResolution = aImageResolution;
+        }
+    DP0_IMAGIC(_L("CImagicViewBrowser::LoadBitmapsToBrowserL--"));
+    }
+
+
+//Callback from engine that bitmap has been loaded
+void CImagicViewBrowser::BitmapLoadedByEngineL(TInt aError)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::BitmapLoadedByEngine++"));
+    
+    iContainer->ImageLoadedL(aError, iBitmap, iImageResolution);
+	
+    iContainer->SetLoadingOn(ETrue);
+    
+	// Request to load next thumbnail
+    if (aError == KErrNone)
+        iContainer->DynamicLoadingL(); 
+    
+    DP0_IMAGIC(_L("CImagicViewBrowser::BitmapLoadedByEngine--"));
+    }
+
+CImagicContainerBrowser* CImagicViewBrowser::GetContainer()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::GetContainer"));
+    //We return null on purpose if container does not exits
+    return iContainer;
+    }
+
+void CImagicViewBrowser::TNCreationComplete()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::TNCreationComplete++"));
+    iTNCreationComplete = ETrue;
+    
+    if(iContainer)
+        iContainer->SetBGPSStatus(ETrue);
+    
+    DP0_IMAGIC(_L("CImagicViewBrowser::TNCreationComplete--"));
+    }
+
+void CImagicViewBrowser::FaceDetectionComplete()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::FaceBrowsingComplete++"));
+    iFaceBrowsingComplete = ETrue;
+    
+    /*if(iContainer)
+        iContainer->SetTNCreationComplete(ETrue);*/
+    
+    DP0_IMAGIC(_L("CImagicViewBrowser::FaceBrowsingComplete--"));
+    }
+
+void CImagicViewBrowser::TNCreationBegin()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::TNCreationBegin++"));
+    iTNCreationComplete = EFalse;
+    
+    if(iContainer)
+        iContainer->SetBGPSStatus(EFalse);
+    DP0_IMAGIC(_L("CImagicViewBrowser::TNCreationBegin--"));
+    }
+
+TApplicationFeature CImagicViewBrowser::GetAppFeature()
+    {
+    return iApplicationFeature;
+    }
+
+// ----------------------------------------------------------------------------
+// CImagicViewBrowser::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)
+// This function is called by the EIKON framework just before it displays
+// a menu pane. Sets the state of menu items dynamically according
+// to the state of application data.
+// ----------------------------------------------------------------------------
+//
+void CImagicViewBrowser::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::DynInitMenuPaneL++"));
+    
+    CTextureLoader* textLoader = iContainer->GetTextureLoader();
+    CImagicContainerBrowser::TDrawFunction drawMode = iContainer->GetDrawMode();
+    
+    if(aResourceId == R_IMAGIC_VIEWBROWSER_MENU)
+        {
+        //Initialaly hide Edit, Crop and Delete
+        aMenuPane->SetItemDimmed(EImagicCmdViewEdit, ETrue); //Edit
+        aMenuPane->SetItemDimmed(EImagicCmdViewFaceBrowsing, ETrue); //FaceBrowsing
+        aMenuPane->SetItemDimmed(EImagicCmdViewBrowserCropping, ETrue); //Crop
+        //aMenuPane->SetItemDimmed(EImagicCmdViewBrowserDelete, EFalse); //Delete
+                
+        aMenuPane->SetItemDimmed(EImagicCmdViewBrowserRemoveFace, ETrue);//Remove false detection Coords from exif data
+        aMenuPane->SetItemDimmed(EImagicCmdViewBrowserAddNewFace, ETrue);//Add new face detection to exif data
+        aMenuPane->SetItemDimmed(EImagicCmdViewBrowserAddAsThisNewFace, ETrue);//Add as new face to exif data
+        aMenuPane->SetItemDimmed(EImagicCmdViewBrowserFaceCropping, ETrue);//Face cropping
+        
+        aMenuPane->SetItemDimmed(ECmdRotateImage, EFalse); //Layouts
+        aMenuPane->SetItemDimmed(EImagicCmdViewBrowserShowImageInfo, EFalse); //Image Info
+        aMenuPane->SetItemDimmed(EImagicCmdViewBrowserHelp, ETrue); //Image Info
+        
+        if((drawMode == CImagicContainerBrowser::EOneByOne || drawMode == CImagicContainerBrowser::EFaceBrowser))
+            {
+            aMenuPane->SetItemDimmed(EImagicCmdViewBrowserGridModeFolder, ETrue);            
+            aMenuPane->SetItemDimmed(EImagicCmdViewBrowserGridModeTime, ETrue); 
+            
+            //if(iTNCreationComplete && iFaceCroppingComplete)
+            CImageData* imageData = iImagicAppUi->GetEngine()->GetImageData(iImagicAppUi->GetImageIndex());
+            if(imageData->IsImageReady(ESize512x512))
+                {
+                aMenuPane->SetItemDimmed(EImagicCmdViewEdit, ETrue); //Edit
+                if(imageData->GetNumberOfFaces() > 0)
+                    aMenuPane->SetItemDimmed(EImagicCmdViewFaceBrowsing, EFalse); //FaceBrowsing
+                
+                aMenuPane->SetItemDimmed(EImagicCmdViewBrowserCropping, ETrue); //Crop
+                aMenuPane->SetItemDimmed(EImagicCmdViewBrowserFaceCropping, ETrue);//Face cropping
+                
+                if(iFaceBrowsingMode == EFaceBrowsing)
+                    {
+                    aMenuPane->SetItemDimmed(EImagicCmdViewFaceBrowsing, ETrue); //FaceBrowsing
+                    aMenuPane->SetItemDimmed(EImagicCmdViewBrowserAddAsThisNewFace, ETrue);//Add as new face to exif data
+                    aMenuPane->SetItemDimmed(EImagicCmdViewBrowserCropping, ETrue); //Crop
+                    aMenuPane->SetItemDimmed(EImagicCmdViewBrowserDelete, ETrue); //Delete
+                    aMenuPane->SetItemDimmed(EImagicCmdViewBrowserFaceCropping, ETrue);//Face cropping
+                    aMenuPane->SetItemDimmed(EImagicCmdViewBrowserShowImageInfo, EFalse); //Image Info
+                    }
+                }
+            }
+        else
+            {
+            TGridMode gridMode = (TGridMode)iSettings.GetValue(CSettings::ESettingGridMode);
+            aMenuPane->SetItemDimmed(EImagicCmdViewBrowserGridModeFolder, gridMode != EGridModeFolder);            
+            aMenuPane->SetItemDimmed(EImagicCmdViewBrowserGridModeTime, gridMode != EGridModeTime); 
+            aMenuPane->SetItemDimmed(EImagicCmdViewBrowserGridModePeople, 
+#ifdef PEOPLE_VIEW			
+				ETrue);
+#else
+				gridMode != EGridModePeople);
+#endif				
+            }
+        }
+    
+    DP0_IMAGIC(_L("CImagicViewBrowser::DynInitMenuPaneL--"));
+    }
+
+void CImagicViewBrowser::WriteSettingsFileL(const TDesC& aName)
+{
+    DP0_IMAGIC(_L("CImagicViewBrowser::WriteSettingsFileL++"));
+    
+    TParse filestorename;
+    iFsSession.Parse(aName,filestorename);
+    
+    RFileWriteStream writer;
+    writer.PushL();
+    User::LeaveIfError(writer.Replace(iFsSession, filestorename.FullName(), EFileWrite));
+    
+    writer << iSettings; 
+    writer.CommitL();
+    
+    CleanupStack::PopAndDestroy();
+
+    DP0_IMAGIC(_L("CImagicViewBrowser::WriteSettingsFileL--"));
+}
+
+
+void CImagicViewBrowser::ReadSettingsFileL(const TDesC& aName)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::ReadSettingsFileL++"));
+    TParse filestorename;
+    iFsSession.Parse(aName,filestorename);
+
+    RFileReadStream reader;
+    reader.PushL();
+    
+    User::LeaveIfError(reader.Open(iFsSession, filestorename.FullName(),EFileRead));
+    reader >> iSettings;
+
+    // Cleanup the stream object
+    CleanupStack::PopAndDestroy();
+    DP0_IMAGIC(_L("CImagicViewBrowser::ReadSettingsFileL--"));
+    }
+
+//Returns true if file exists
+/*TBool CImagicViewBrowser::FindFileName(const TDesC& aName)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::FindFileName++"));
+    TBool result = BaflUtils::FileExists(iFsSession, aName); 
+    DP0_IMAGIC(_L("CImagicViewBrowser::FindFileName--"));
+    return result;
+    }*/    
+
+CSettings::CSettings()
+    {
+    iChanged = EFalse;
+    Mem::FillZ(iValues, sizeof(iValues));
+    }
+
+//Functions from TModeSettings class
+void CSettings::ExternalizeL(RWriteStream& aStream) const
+    {
+    aStream.WriteL((TUint8*)iValues, sizeof(iValues));
+    }  
+ 
+void CSettings::InternalizeL(RReadStream& aStream)
+    {
+    aStream.ReadL((TUint8*)iValues, sizeof(iValues));
+    }
+
+void CSettings::SetValue(TSettingsValue aIndex, TInt aValue)
+    {
+    if (iValues[aIndex] != aValue)
+        {
+        iValues[aIndex] = aValue;
+        iChanged = ETrue;
+        }
+    }
+
+TInt CSettings::GetValue(TSettingsValue aIndex) const
+    {
+    return iValues[aIndex];
+    }
+
+TBool CSettings::IsChanged() const
+    {
+    return iChanged;
+    }
+
+/*
+void CImagicViewBrowser::SetFaceCoords(RArray<TRect>& aCoordinates)
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::SetFaceCoords++"));
+    
+    iCoordinates = aCoordinates;
+    
+    if(iContainer)
+        iContainer->SetFaceCoords(aCoordinates);
+    
+    TInt tmp = iCoordinates.Count();
+    for(TInt i = 0; i < tmp; i++)
+        {
+        iCoordinates.Remove(0);
+        }
+        
+    DP0_IMAGIC(_L("CImagicViewBrowser::SetFaceCoords--"));
+    }
+*/
+void CImagicViewBrowser::ResetFaceCoords()
+    {
+    DP0_IMAGIC(_L("CImagicViewBrowser::ResetFaceCoords++"));
+    
+    //iCoordinates.Reset();
+    TInt tmp = iCoordinates.Count();
+    for(TInt i = 0; i < tmp; i++)
+        {
+        iCoordinates.Remove(0);
+        }
+    }
+
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/SendImageFile.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,126 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "SendImageFile.h"
+
+#include <sendui.h>
+#include <eikenv.h>
+
+#ifdef SEND_FILE_DIALOGUE
+#include <BTObjectExchange.rsg>
+#endif
+
+#include <caknfileselectiondialog.h>
+#include <caknmemoryselectiondialog.h> 
+
+#include <cmessagedata.h> 
+
+
+CSendImageFile::CSendImageFile() {
+
+}
+
+CSendImageFile* CSendImageFile::NewL() {
+    CSendImageFile* self = new ( ELeave ) CSendImageFile();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+}
+
+void CSendImageFile::ConstructL() {
+
+    iSendUi = CSendUi::NewL();
+
+}
+
+CSendImageFile::~CSendImageFile() {
+    if(iSendUi) {
+        delete iSendUi;
+    }
+}
+
+#ifdef SEND_FILE_DIALOGUE
+TBool CSendImageFile::AskFileL(TFileName& aFileName)
+    {
+
+    // Select memory
+    CAknMemorySelectionDialog* memSelectionDialog = 
+        CAknMemorySelectionDialog::NewL(ECFDDialogTypeNormal, EFalse);
+    CleanupStack::PushL(memSelectionDialog);
+    CAknMemorySelectionDialog::TMemory mem(CAknMemorySelectionDialog::EPhoneMemory);
+
+    TInt ret = memSelectionDialog->ExecuteL(mem);
+    CleanupStack::PopAndDestroy(memSelectionDialog);
+    if (!ret) 
+        {        
+        return EFalse;
+        }
+    //Select file from the chosen memory
+    CAknFileSelectionDialog* fileSelectionDialog = NULL; 
+    if (mem == CAknMemorySelectionDialog::EMemoryCard)
+        {  
+        fileSelectionDialog = CAknFileSelectionDialog::NewL(ECFDDialogTypeNormal,R_FILE_SELECTION_DIALOG_E );
+        }
+    else
+        {  
+        fileSelectionDialog= CAknFileSelectionDialog::NewL(ECFDDialogTypeNormal,R_FILE_SELECTION_DIALOG_C );
+        } 
+
+    TBool result = fileSelectionDialog->ExecuteL(aFileName);
+    delete fileSelectionDialog;
+    return result;
+
+    }
+
+void CSendImageFile::SendFileViaSendUiL()
+    {
+
+    TFileName path;
+
+    AskFileL(path);
+    SendFileViaSendUiL(path);
+
+    }
+#endif
+
+void CSendImageFile::SendFileViaSendUiL(TFileName path)
+    {
+
+        TSendingCapabilities capabs( 0, 1024, TSendingCapabilities::ESupportsAttachments ); 
+
+        RFs fs;
+        CleanupClosePushL(fs);
+        User::LeaveIfError( fs.Connect() );
+        fs.ShareProtected();
+        
+        RFile temp;
+        User::LeaveIfError( temp.Open( fs, path, EFileShareReadersOnly | EFileRead ) );
+        CleanupClosePushL(temp);
+                
+        CMessageData* messageData = CMessageData::NewL();
+        CleanupStack::PushL(messageData);
+        messageData->AppendAttachmentHandleL(temp);
+        
+        TRAPD(err, iSendUi->ShowQueryAndSendL(messageData, capabs) );
+
+        CleanupStack::PopAndDestroy(messageData);
+        
+        CleanupStack::PopAndDestroy(&temp);
+        CleanupStack::PopAndDestroy(&fs);        
+   
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/TextureLoader.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,789 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// INCLUDE FILES
+#include "TextureLoader.h"
+#include <GLES\egl.h>
+#include "ImagicContainerBrowser.h"
+#include "ImagicViewBrowser.h"
+#include <hal.h>
+
+// INCLUDES
+#include <coecntrl.h>
+#include <aknnotewrappers.h>
+#include "ImagicAppUi.h"
+
+/*----------------------------------------------------------------------*/
+// Constructor and destructor
+//
+CTextureLoader::CTextureLoader(CImagicAppUi* aImagicAppUi, CImagicContainerBrowser* aContainer, CImagicViewBrowser* aView, 
+                               RCriticalSection* aDrawLock) :
+        //CActive(CActive::EPriorityStandard),
+        CActive(CActive::EPriorityLow),
+        //CActive(CActive::EPriorityStandard),
+        //CActive(CActive::EPriorityUserInput),
+        //CActive(CActive::EPriorityHigh),
+        iImagicAppUi(aImagicAppUi),
+        iContainer(aContainer),
+        iView(aView),
+        iDrawLock(aDrawLock),
+        iData(NULL)
+        
+    {
+    DP0_IMAGIC(_L("CTextureLoader::CTextureLoader++"));
+    
+    // Add loader to active scheduler
+    CActiveScheduler::Add(this);
+    
+    DP0_IMAGIC(_L("CTextureLoader::CTextureLoader--"));
+    }
+
+void CTextureLoader::ConstructL()
+    {
+    DP0_IMAGIC(_L("CTextureLoader::ConstructL++"));
+    
+    // Create small default bitmap
+    iBitmap = new (ELeave) CFbsBitmap();
+    iSmileBitmap = new (ELeave) CFbsBitmap();
+    iZoomBitmap = new (ELeave) CFbsBitmap();
+#ifdef USE_RGBA
+    iBitmap->Create(TSize(10, 10), EColor16MU);
+#else
+    iBitmap->Create(TSize(10, 10), EColor16M);
+#endif
+    
+    // Create bitmap scaler
+    iBitmapScaler = CBitmapScaler::NewL();
+    iBitmapScaler->UseLowMemoryAlgorithm(ETrue);
+    
+    iRGB2BGRDone = EFalse;
+
+#ifdef ICONS_ENABLAD
+    LoadIcons();
+#endif
+    
+    DP0_IMAGIC(_L("CTextureLoader::ConstructL--"));
+    }
+
+CTextureLoader::~CTextureLoader()
+    {
+    DP0_IMAGIC(_L("CTextureLoader::~CTextureLoader++"));
+    
+    // Cancel ongoing process
+    Cancel();
+    
+    // Free memory
+    delete iBitmapScaler;
+    delete iBitmap;
+    delete iSmileBitmap;
+    delete iZoomBitmap;
+    
+    iBitmapArray.Close();
+    
+    DP0_IMAGIC(_L("CTextureLoader::~CTextureLoader--"));
+    }
+
+void CTextureLoader::GetPngL(TFileName& afilepath, CFbsBitmap* aBitmap) 
+    {
+    DP0_IMAGIC(_L("CTextureLoader::GetPngL++"));
+    
+    CImageDecoder* idecoder = CImageDecoder::FileNewL(CEikonEnv::Static()->FsSession(), 
+            afilepath, _L8("image/png")/*, CImageDecoder::EOptionAlwaysThread*/);
+    
+    TFrameInfo iFrameInfo = idecoder->FrameInfo(0);
+    aBitmap->Create(iFrameInfo.iOverallSizeInPixels, EColor16MA );
+    
+    TRequestStatus aStatus = KRequestPending; 
+    
+    TRAPD(err1, idecoder->Convert( &aStatus, *aBitmap, 0 ));
+    if(err1 == KErrNone)
+        User::WaitForRequest( aStatus );   
+
+    delete idecoder;
+    
+    DP0_IMAGIC(_L("CTextureLoader::GetPngL--"));
+    }
+
+
+void CTextureLoader::LoadIcons()
+    {
+    TInt err = KErrNone;
+
+    TFileName filename;
+    filename = KSmileFileName;
+    TRAP(err, GetPngL(filename, iSmileBitmap));
+    if(err == KErrNone)
+        iBitmapArray.Append(iSmileBitmap);
+    
+    err = KErrNone;
+
+    filename = KZoomFileName;
+    TRAP(err, GetPngL(filename, iZoomBitmap));
+    if(err == KErrNone)
+        iBitmapArray.Append(iZoomBitmap);
+    
+
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Returns loader loading status
+//
+TBool CTextureLoader::IsActiveAndRunning()
+    {
+    // Make sure that loader is not active
+    if (IsRunning())
+        return ETrue;
+    else
+        return EFalse;
+    }
+    
+
+/*----------------------------------------------------------------------*/
+// Loads picture and stores the OpenGL index into specified variable
+//
+void CTextureLoader::LoadL(CImageData* aData, TThumbSize aResolution)
+    {
+    DP1_IMAGIC(_L("CTextureLoader::LoadL++ - resolution: %d"), aResolution);
+
+    // Make sure that loader is not active
+    if (IsRunning())
+        {
+        DP0_IMAGIC(_L("CTextureLoader::LoadL - already running, KErrInUse"));
+        User::Leave(KErrInUse);
+        }
+    // Check that image is not already loaded
+    else if (aData->iGridData.iGlSuperHQTextIndex && aResolution == EFullSize)
+        {
+        DP0_IMAGIC(_L("CTextureLoader::LoadL - EFullRes KErrAlreadyExists"));
+        iData = NULL;
+        User::Leave(KErrAlreadyExists);
+        }
+    else if (aData->iGridData.iGlHQ512TextIndex && aResolution == ESize512x512)
+        {
+        DP0_IMAGIC(_L("CTextureLoader::LoadL - ESize512x512 KErrAlreadyExists"));
+        iData = NULL;
+        User::Leave(KErrAlreadyExists);
+        }
+    else if (aData->iGridData.iGlLQ128TextIndex && aResolution == ESize128x128)
+        {
+        DP0_IMAGIC(_L("CTextureLoader::LoadL -  ESize128x128 KErrAlreadyExists"));
+        iData = NULL;
+        User::Leave(KErrAlreadyExists);
+        }
+    else if (aData->iGridData.iGlLQ32TextIndex && aResolution == ESize32x32)
+        {
+        DP0_IMAGIC(_L("CTextureLoader::LoadL - ESize32x32 KErrAlreadyExists"));
+        iData = NULL;
+        User::Leave(KErrAlreadyExists);
+        }
+    
+    iContainer->DynamicUnLoading();
+    
+    // Store image data
+    iData = aData;
+    iResolution = aResolution;
+    iHighQuality = EFalse;
+    if(aResolution == EFullSize || aResolution == ESize512x512)
+        {
+        iHighQuality = ETrue;
+        //iContainer->DynamicUnLoading();
+        }
+    
+    // Call engine to load picture
+    TRAPD(err, iView->LoadBitmapsToBrowserL(iData, aResolution));
+    if (err != KErrNone)
+        {
+        //if (err == KErrNotFound || err == KErrPathNotFound)
+            iData->SetImageReady(aResolution, EFalse);
+        iData = NULL;
+        User::Leave(err);
+        }
+
+    DP0_IMAGIC(_L("CTextureLoader::LoadL--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Releases 512x512 and Max resolution textures
+//
+void CTextureLoader::ReleaseSuperHResTexture(CImageData* aGridData)
+    {
+    DP0_IMAGIC(_L("CTextureLoader::ReleaseHResTextures++"));
+    
+    if(aGridData->iGridData.iGlSuperHQTextIndex != 0)
+        {
+        glDeleteTextures(1, &(aGridData->iGridData.iGlSuperHQTextIndex));
+        aGridData->iGridData.iGlSuperHQTextIndex=0;
+        DP0_IMAGIC(_L("CTextureLoader::ReleaseHResTextures - glSuperHQTextIndex released"));
+        }
+    
+    DP0_IMAGIC(_L("CTextureLoader::ReleaseHResTextures--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Unloads picture from specified index
+//
+void CTextureLoader::ReleaseHQ512Textures()
+    {
+    DP0_IMAGIC(_L("CTextureLoader::ReleaseQ512Textures++"));
+    
+    TInt mem = 0;
+    TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+    DP1_IMAGIC(_L("CTextureLoader::ReleaseQ512Textures - Free RAM: %d"), mem);
+    
+    for(TInt i=0; i<iContainer->iIEngine->GetTotalNumOfImages(); i++)
+        {
+        if(i >= iContainer->GetCurrentIndex() + CImagicContainerBrowser::K512TNImageBuffer || 
+           i <= iContainer->GetCurrentIndex() - CImagicContainerBrowser::K512TNImageBuffer)
+            {
+            CImageData* imageData = iImagicAppUi->GetEngine()->GetImageData(i);
+            
+            if(imageData->iGridData.iGlSuperHQTextIndex!=0)
+                {
+                glDeleteTextures(1, &(imageData->iGridData.iGlSuperHQTextIndex));
+                imageData->iGridData.iGlSuperHQTextIndex=0;
+                }
+            
+            if(i != iContainer->GetCurrentIndex())
+                {
+                if (imageData->iGridData.iGlHQ512TextIndex!=0)
+                    {
+                    glDeleteTextures(1, &(imageData->iGridData.iGlHQ512TextIndex));
+                    imageData->iGridData.iGlHQ512TextIndex=0;
+                    }
+                }
+            }
+        }
+    
+    ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+    DP1_IMAGIC(_L("CTextureLoader::ReleaseQ512Textures - Free RAM: %d"), mem);
+    
+    DP0_IMAGIC(_L("CTextureLoader::ReleaseQ512Textures--"));
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Unloads picture from specified index
+//
+void CTextureLoader::UnloadLQ512Tex(CImageData* aData) const
+    {
+    DP0_IMAGIC(_L("CTextureLoader::UnloadLQ512Tex++"));
+    
+    /*TInt mem = 0;
+    TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+    DP1_IMAGIC(_L("CTextureLoader::UnloadLQ512Tex - Free RAM: %d"), mem);*/
+                
+    // Delete the picture
+    if (aData->iGridData.iGlHQ512TextIndex!=0)
+        {
+        glDeleteTextures(1, &(aData->iGridData.iGlHQ512TextIndex));
+        aData->iGridData.iGlHQ512TextIndex=0;
+        }
+    
+    /*ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+    DP1_IMAGIC(_L("CTextureLoader::UnloadLQ512Tex - Free RAM: %d"), mem);*/
+    
+    DP0_IMAGIC(_L("CTextureLoader::UnloadLQ512Tex--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Unloads picture from specified index
+//
+void CTextureLoader::UnloadLQ128Tex(CImageData* aData) const
+    {
+    DP0_IMAGIC(_L("CTextureLoader::UnloadLQ128Tex++"));
+    
+    // Delete the picture
+    if (aData->iGridData.iGlLQ128TextIndex!=0)
+        {
+        glDeleteTextures(1, &(aData->iGridData.iGlLQ128TextIndex));
+        aData->iGridData.iGlLQ128TextIndex=0;
+        }
+    
+    DP0_IMAGIC(_L("CTextureLoader::UnloadLQ128Tex--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Unloads picture from specified index
+//
+void CTextureLoader::UnloadLQ32Tex(CImageData* aData) const
+    {
+    DP0_IMAGIC(_L("CTextureLoader::UnloadLQ32Tex++"));
+    
+    if (aData->iGridData.iGlLQ32TextIndex!=0)
+        {
+        glDeleteTextures(1, &(aData->iGridData.iGlLQ32TextIndex));
+        aData->iGridData.iGlLQ32TextIndex=0;
+        }
+    
+    DP0_IMAGIC(_L("CTextureLoader::UnloadLQ32Tex--"));
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Image is loaded by engine, iScale it for OpenGL if needed
+//
+void CTextureLoader::ImageLoadedL(TInt aError, CFbsBitmap* aBitmap, TInt aGLMaxRes)
+    {
+    DP0_IMAGIC(_L("CTextureLoader::ImageLoadedL++"));
+    
+    if(aError == KErrNotFound || aError == KErrPathNotFound)
+        {
+        DP0_IMAGIC(_L("CTextureLoader::ImageLoadedL - Error: KErrNotFound/KErrPathNotFound"));
+        iData->SetImageReady(iResolution, EFalse);
+        iData = NULL;
+        return;
+        }
+    else if(aError == KErrCorrupt)
+        {
+        DP0_IMAGIC(_L("CTextureLoader::ImageLoadedL - Error: KErrCorrupt"));
+        iData->SetImageReady(iResolution, EFalse);
+        iData->iGridData.iCorrupted = ETrue;
+        iData = NULL;
+        return;
+        }
+    else if(aError == KErrCancel)
+        {
+        //Image loading is cancelled only for superzoom iage loading
+        DP1_IMAGIC(_L("CTextureLoader::ImageLoadedL - Error: %d"), aError);
+        //iData->SetImageReady(iResolution, EFalse);
+        iData = NULL;
+        return;
+        }
+    else if(aError != KErrNone)
+        {
+        DP1_IMAGIC(_L("CTextureLoader::ImageLoadedL - Error: %d"), aError);
+        iData->SetImageReady(iResolution, EFalse);
+        iData = NULL;
+        return;
+        }
+    
+    // Set image ready to database
+    //iData->SetImageReady(iResolution, ETrue);
+    
+    iGLMaxRes = aGLMaxRes;
+    iImageSize = aBitmap->SizeInPixels();
+    
+    //Check loaded image real size and check if scaling is needed
+    iScalingNeeded = IsScalingNeeded(iImageSize);
+        
+    TSize size;
+    // Check does image need to be scaled
+    if(!iScalingNeeded)
+        { //Image is already proper size, just create texture
+        CreateThumbnailTexture(aBitmap);
+        }
+    //Calculate new image size if scaling is needed(in case size is not pow^2)
+    else
+        {
+        size.iWidth = ScaleDown( iImageSize.iWidth );
+        size.iHeight = ScaleDown( iImageSize.iHeight );
+
+        // Setup target bitmap to be large enough
+        iBitmap->Reset();
+#ifdef USE_RGBA
+        iBitmap->Create(size, EColor16MU);
+#else
+        iBitmap->Create(size, EColor16M);
+#endif
+    
+        // Setup image quality
+        CBitmapScaler::TQualityAlgorithm quality = CBitmapScaler::EMinimumQuality;
+        /*if(iHighQuality)*/
+            quality=CBitmapScaler::EMaximumQuality;
+    
+        iBitmapScaler->SetQualityAlgorithm(quality);
+    
+        // Start scaling the bitmap, RunL will be called when complete
+        iBitmapScaler->Scale(&iStatus, *aBitmap, *iBitmap, EFalse);
+        if(!IsActive())
+            SetActive();
+        }
+    
+    DP0_IMAGIC(_L("CTextureLoader::ImageLoadedL--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Creates OpenGL texture of given bitmap
+//
+TInt CTextureLoader::CreateTexture(CFbsBitmap* aBitmap, TBool aHighQuality)
+    {
+    DP0_IMAGIC(_L("CTextureLoader::CreateTexture++"));
+    
+    // Get image data size
+    TInt width = aBitmap->SizeInPixels().iWidth;
+    TInt height = aBitmap->SizeInPixels().iHeight;
+    TInt dataSize = width * height;
+    
+    // Lock bitmap before modifying its data
+    aBitmap->LockHeap( EFalse );
+    
+    // The data in the texture are in RGBA order but is read in BGRA order.
+    // So we have to swap the 1st and 3rd bytes.
+    TUint8* data = (TUint8 *)aBitmap->DataAddress();
+
+#ifdef USE_RGBA
+    dataSize*=4;
+    for (TInt i=0; i<dataSize; i+=4)
+        {
+        TUint8 temp = data[i];
+        data[i] = data[i+2];
+        data[i+2] = temp;
+        }
+#else
+    dataSize*=3;
+    //RDebug::Print(_L("CTextureLoader::CreateTexture - Bitmap Data seize: %d"), dataSize);
+    for(TInt i=0; i<dataSize; i+=3)
+        {
+        TUint8 temp = data[i];
+        data[i] = data[i+2];
+        data[i+2] = temp;
+        }
+#endif
+    
+    // Generate OpenGL texture index
+    GLuint index;
+    glGenTextures(1, &index);
+    glBindTexture(GL_TEXTURE_2D, index);
+    
+//#define MIPMAPPING
+#ifdef MIPMAPPING
+       //Set mipmapping on
+       //glHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST );
+       glHint( GL_GENERATE_MIPMAP_HINT, GL_FASTEST );
+       glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
+       //Select mipmapping filtering mode
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+       //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);//linear gives better image quality but slover rendering
+#endif
+       
+    // Set texture parameters
+    //GL_NEAREST is faster than GL_LINEAR but quality is better in linear
+    if(!aHighQuality)
+        {
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        }
+    else
+        {
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        }
+    
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    
+#ifdef USE_RGBA
+    // Load texture into OpenGL memory
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height,
+                  0, GL_RGBA, GL_UNSIGNED_BYTE, data );
+#else
+       glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data );
+#endif
+    
+    // Unlock bitmap
+    aBitmap->UnlockHeap( EFalse );
+    
+    return index;
+    }
+    
+void CTextureLoader::CreateThumbnailTexture(CFbsBitmap* aBitmap)
+    {
+    DP0_IMAGIC(_L("CTextureLoader::CreateThumbnailTexture++"));
+    
+    TInt index = CreateTexture(aBitmap, iHighQuality);
+    iContainer->SetTextIndex(index);
+    
+    //Image has been loaded, store index
+    if(iResolution == ESize512x512)
+        {
+        //Check that we really have high resolution image
+        if((aBitmap->SizeInPixels().iHeight == 512 && aBitmap->SizeInPixels().iWidth == 1024) || 
+           (aBitmap->SizeInPixels().iHeight == 1024 && aBitmap->SizeInPixels().iWidth == 512) ||
+           (aBitmap->SizeInPixels().iHeight == 512 && aBitmap->SizeInPixels().iWidth == 512))
+            {
+            iData->iGridData.iGlHQ512TextIndex = index;
+            }
+        else
+            {//if no high resolution image, delete existing texture from 128x128 slot and bind newly created texture there
+            if(aBitmap->SizeInPixels().iHeight == 128)
+                {
+                if(iData->iGridData.iGlLQ128TextIndex != 0)
+                    glDeleteTextures(1, &(iData->iGridData.iGlLQ128TextIndex));
+                iData->iGridData.iGlLQ128TextIndex = index;
+                }
+            if(aBitmap->SizeInPixels().iHeight == 32)
+                {
+                if(iData->iGridData.iGlLQ32TextIndex != 0)
+                    glDeleteTextures(1, &(iData->iGridData.iGlLQ32TextIndex));
+                iData->iGridData.iGlLQ32TextIndex = index;
+                }
+            }
+        iPreviousData = iData;
+        }
+    else if(iResolution == ESize128x128)
+        {
+        //Check if we had exif tn already binded and delete it
+        if(iData->iGridData.iGlLQ128TextIndex != 0)
+            {
+            glDeleteTextures(1, &(iData->iGridData.iGlLQ128TextIndex));
+            }
+        iData->iGridData.iGlLQ128TextIndex = index;
+        }
+    else if(iResolution == ESize32x32)
+        {
+        //Check if we had exif tn already binded and delete it
+        if(iData->iGridData.iGlLQ32TextIndex != 0)
+            {
+            glDeleteTextures(1, &(iData->iGridData.iGlLQ32TextIndex));
+            }
+        iData->iGridData.iGlLQ32TextIndex = index;
+        }
+#ifdef SUPERZOOM
+    else if(iResolution == EFullSize)
+        {
+        iData->iGridData.iGlSuperHQTextIndex = index;
+        }
+#endif
+
+    //Order container to draw scaled image
+    /*if(iContainer->GetDrawMode() == EOneByOne)
+        {
+        //Check if loaded image is current one and draw it
+        CImageData* imageData = iImagicAppUi->GetEngineL()->GetImageData(iContainer->GetCurrentIndex(), iImagicAppUi->GetUIDrawMode());
+        if(imageData->iGridData.iGlSuperHQTextIndex != 0)
+            iContainer->DrawNow();
+        else if(imageData->iGridData.iGlHQ512TextIndex == iData->iGridData.iGlHQ512TextIndex )
+            iContainer->DrawNow();
+        else if(imageData->iGridData.iGlLQ128TextIndex == iData->iGridData.iGlLQ128TextIndex )
+            iContainer->DrawNow();
+        }
+    else*/
+        {
+        iContainer->DrawNow();
+        DP0_IMAGIC(_L("<----------- CTextureLoader DrawNow ----------->"));
+        }
+    
+    //Loader is finished
+    iData = NULL;
+    aBitmap->Reset();
+    
+    //Set loader back on
+    //iContainer->SetLoadingOn(ETrue);
+        
+    DP0_IMAGIC(_L("CTextureLoader::CreateThumbnailTexture--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Active object's RunL
+//
+void CTextureLoader::RunL()
+    {
+    ASSERT(iBitmap);
+    CreateThumbnailTexture(iBitmap);
+    }
+
+/*----------------------------------------------------------------------*/
+// Active object's DoCancel
+//
+void CTextureLoader::DoCancel()
+    {
+    DP0_IMAGIC(_L("CTextureLoader::DoCancel++"));
+    
+    // Reset bitmap and cancel scaler
+    if (IsActive())
+        {
+        iBitmap->Reset();
+        iBitmapScaler->Cancel();
+        }
+    
+    DP0_IMAGIC(_L("CTextureLoader::DoCancel--"));
+    }
+
+/*----------------------------------------------------------------------*/
+// Active object's RunError
+//
+void CTextureLoader::RunError()
+    {
+    // Nothing here
+    }
+
+/*----------------------------------------------------------------------*/
+// Scales given value to power of two
+//
+TInt CTextureLoader::ScaleDown(TInt aSize)
+    {
+    DP0_IMAGIC(_L("CTextureLoader::ScaleDown++"));
+    
+    if(iResolution == ESize32x32)
+        {
+        return 32;
+        }
+    else if(iResolution == ESize128x128 || iResolution == ESize512x512)
+        {
+        return 128;
+        }
+        
+    // Find new size for picture
+    TInt newSize;
+    for (newSize=1; newSize<aSize; newSize*=2)
+        ;   // Just do nothing
+    
+    // Do not iScale up
+    if(newSize > aSize)
+        newSize/=2;
+    
+    // Limit size to some maximum value
+    TInt maxSize=256;
+    TInt minSize = 32;
+    
+    
+    if(iHighQuality)    // High quality pictures are lot bigger
+        {
+/*#ifdef __WINS__
+        maxSize=512;
+#endif*/
+
+#ifdef SUPERZOOM
+        //maxSize=iGLMaxRes;
+        if(iGLMaxRes >= 1024)
+            maxSize=1024;
+        else
+            maxSize=iGLMaxRes;
+        
+#else
+        maxSize=512;
+#endif
+    
+        }
+    // Check that size is below maximum and min size
+    if(newSize > maxSize)
+        newSize=maxSize;
+    if(newSize < minSize)
+        newSize=minSize;
+
+    DP0_IMAGIC(_L("CTextureLoader::ScaleDown--"));
+    return newSize;
+    }
+
+/*----------------------------------------------------------------------*/
+// Creates OpenGL texture of given bitmap
+//
+void CTextureLoader::CreateIconTextures()
+    {
+    DP0_IMAGIC(_L("CTextureLoader::CreateIconTextures++"));
+    
+    for(TInt i=0; i<iBitmapArray.Count(); i++)
+        {
+        // Get image data size
+        TInt width = iBitmapArray[i]->SizeInPixels().iWidth;
+        TInt height = iBitmapArray[i]->SizeInPixels().iHeight;
+        TInt dataSize = width * height;
+        
+        // Lock bitmap before modifying its data
+        iBitmapArray[i]->LockHeap( EFalse );
+        
+        // The data in the texture are in RGBA order but is read in BGRA order.
+        // So we have to swap the 1st and 3rd bytes.
+        TUint8* data = (TUint8 *)iBitmapArray[i]->DataAddress();
+    
+        if(!iRGB2BGRDone)
+            {
+//#ifdef USE_RGBA
+            dataSize*=4;
+            for (TInt i=0; i<dataSize; i+=4)
+                {
+                TUint8 temp = data[i];
+                data[i] = data[i+2];
+                data[i+2] = temp;
+                }
+/*#else
+            dataSize*=3;
+            for(TInt i=0; i<dataSize; i+=3)
+                {
+                TUint8 temp = data[i];
+                data[i] = data[i+2];
+                data[i+2] = temp;
+                }
+#endif*/
+            }
+        
+        // Generate OpenGL texture index
+        //GLuint index;
+        glGenTextures(1, &iSmileTexIndex);
+        glBindTexture(GL_TEXTURE_2D, iSmileTexIndex);
+        iIconTextureIndexes.Append(iSmileTexIndex);
+        //iContainer->SetTextIndex(index);
+        
+        // Set texture parameters
+        //GL_NEAREST is faster than GL_LINEAR but quality is better in linear
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    
+        
+    //#ifdef USE_RGBA
+        // Load texture into OpenGL memory
+        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
+    /*#else
+           glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data );
+    #endif*/
+        
+        // Unlock bitmap
+       iBitmapArray[i]->UnlockHeap( EFalse );
+       }
+    
+    iRGB2BGRDone = ETrue;
+    
+    iContainer->IconTexturesLoaded(iIconTextureIndexes);
+    
+    DP0_IMAGIC(_L("CTextureLoader::CreateIconTextures--"));
+    }
+
+
+/*----------------------------------------------------------------------*/
+// Check if scaling is needed
+//
+TBool CTextureLoader::IsScalingNeeded(TSize aImageSize)
+    {
+//Check loaded image real size and over write high quality flag
+    if((aImageSize.iHeight == 1024 && aImageSize.iWidth == 1024) ||
+       (aImageSize.iHeight == 512 && aImageSize.iWidth == 1024) || 
+       (aImageSize.iHeight == 1024 && aImageSize.iWidth == 512) ||
+       (aImageSize.iHeight == 512 && aImageSize.iWidth == 512))
+        {
+        // Set image ready to database, only if resolution was maching with Imagic TN size
+        iData->SetImageReady(ESize512x512, ETrue);
+        return EFalse;
+        }
+    if((aImageSize.iHeight == 128 && aImageSize.iWidth == 128))
+        {
+        // Set image ready to database, only if resolution was maching with Imagic TN size
+        iData->SetImageReady(ESize128x128, ETrue);
+        return EFalse;
+        }
+    if((aImageSize.iHeight == 32 && aImageSize.iWidth == 32))
+        {
+        // Set image ready to database, only if resolution was maching with Imagic TN size
+        iData->SetImageReady(ESize32x32, ETrue);
+        return EFalse;
+        }
+    
+    return ETrue;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/glfont2.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,381 @@
+//*******************************************************************
+// glfont2.cpp -- glFont Version 2.0 implementation
+// Copyright (c) 1998-2002 Brad Fish
+// See glfont.html for terms of use
+// May 14, 2002
+//
+// Symbian OS port - June 2007
+// Luis Valente - lpvalente@gmail.com
+//
+//*******************************************************************
+ 
+/*
+This font class is intended to render 2D text. So, it is important to set up the 
+required orthographic projection before rendering. The following code is an 
+example of how to do this: 
+
+// Rect() is a method that returns the current drawing rectangle.
+// The (0,0) point will be the on bottom-left corner.
+ 
+glViewport (0, 0, Rect().Width(), Rect().Height());
+    
+glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  glOrthox (0, IntToFixed (Rect().Width()), 0, IntToFixed (Rect().Height()), -1, 1);
+    
+ glMatrixMode (GL_MODELVIEW);
+   glLoadIdentity ();Also, the BeginDraw() and EndDraw() methods (or equivalent code) should be called 
+   to set up required states for rendering. For example, if alpha blending is not enabled, the quad 
+   corresponding to the character becomes noticeable. 
+
+Currently, this class supports 8 bit descriptors only. The class should be extended to support 16 bits 
+descriptors and resource strings. 
+
+*/
+
+// Symbian OS headers
+#include <s32file.h>
+#include <eikenv.h>
+#include <eikappui.h>
+#include <eikapp.h>
+#include "glfont2.h"
+#include "FixedMath.h"
+ 
+ 
+// GLFontChar structure as stored in file
+struct GLFontCharFile
+{
+   TReal32 dx, dy;
+   TReal32 tx1, ty1;
+   TReal32 tx2, ty2;
+};
+ 
+// GLFontHeaderFile structure as stored in file
+struct GLFontHeaderFile
+{
+   TInt32  tex;
+   TInt32  texWidth, texHeight;
+   TInt32  startChar, endChar;
+   TUint32 chars;
+};
+ 
+ 
+ 
+//_____________________________________________________________________________
+//
+// Default constructor.
+//
+ 
+GLFont::GLFont ()
+{
+   // Initialize iHeader to safe state
+   iHeader.tex = 0;
+   iHeader.texWidth = 0;
+   iHeader.texHeight = 0;
+   iHeader.startChar = 0;
+   iHeader.endChar = 0;
+   iHeader.chars = NULL;
+ 
+   // OpenGL texture
+   glGenTextures (1, &iHeader.tex);
+}
+ 
+//_____________________________________________________________________________
+//
+// Destructor.
+//
+ 
+GLFont::~GLFont ()
+{
+   // Destroy the font
+   Destroy();
+ 
+   // delete texture
+   glDeleteTextures (1, &iHeader.tex);
+}
+ 
+//_____________________________________________________________________________
+//
+// Factory-method.
+//
+ 
+GLFont * GLFont::NewL (const TDesC & aFilename)
+{
+   GLFont* f = new (ELeave) GLFont();
+   CleanupStack::PushL (f);
+ 
+   f->ConstructL (aFilename);
+ 
+   CleanupStack::Pop ();
+   return f;
+}
+ 
+//_____________________________________________________________________________
+//
+// Second part of the two-phase construction.
+//
+ 
+void GLFont::ConstructL (const TDesC & aFilename)
+{
+   // Destroy the old font if there was one, just to be safe
+   Destroy();
+ 
+   // Open file session with server	
+   RFs session;
+   User::LeaveIfError (session.Connect());
+   CleanupClosePushL (session);	
+ 
+   // retrieve private application folder
+   TFileName path;
+   session.PrivatePath (path);
+ 
+   // retrieve full application path on device
+   #ifndef __WINS__
+      TFileName appFullName =          
+      CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
+ 
+      TParse parse;
+      parse.Set (appFullName, NULL, NULL);
+      path.Insert (0, parse.Drive());
+   #endif
+ 
+   // update filename with full path
+   TFileName fullFilename (path);
+   fullFilename.Append (aFilename);
+ 
+   // load file
+   LoadFileL (session, fullFilename);
+ 
+   // close server session
+   CleanupStack::PopAndDestroy();
+ 
+}
+ 
+//_____________________________________________________________________________
+//
+// Loads the font file.
+//
+ 
+void GLFont::LoadFileL (RFs & aFs, const TDesC & aFilename)
+{
+   // Open input file
+   RFileReadStream readStream;
+ 
+   User::LeaveIfError (readStream.Open (aFs, aFilename, EFileRead));	
+   readStream.PushL();
+ 
+   // Read the iHeader from file
+   GLFontHeaderFile headerFile;
+ 
+   headerFile.tex       = readStream.ReadInt32L ();
+   headerFile.texWidth  = readStream.ReadInt32L();
+   headerFile.texHeight = readStream.ReadInt32L();
+   headerFile.startChar = readStream.ReadInt32L();
+   headerFile.endChar   = readStream.ReadInt32L();
+   headerFile.chars     = readStream.ReadUint32L();
+ 
+   // copy iHeader file to actual iHeader		
+   iHeader.texWidth  = headerFile.texWidth;
+   iHeader.texHeight = headerFile.texHeight;
+   iHeader.startChar = headerFile.startChar;
+   iHeader.endChar   = headerFile.endChar;
+ 
+   // Allocate space for character array
+   TInt numChars = iHeader.endChar - iHeader.startChar + 1;	
+   iHeader.chars = new (ELeave) GLFontChar [numChars];
+ 
+   // Read character array
+   for (TInt i = 0; i < numChars; ++i)
+   {
+      iHeader.chars [i].dx  =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].dy  =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].tx1 =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].ty1 =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].tx2 =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].ty2 =  FloatToFixed (readStream.ReadReal32L () );
+   }
+ 
+ 
+   // Read texture pixel data
+   TInt numTexBytes = iHeader.texWidth * iHeader.texHeight * 2;	
+   TUint8 * texBytes = new (ELeave) TUint8 [numTexBytes]; CleanupStack::PushL (texBytes);
+ 
+   readStream.ReadL (texBytes, numTexBytes);	
+ 
+   // Create OpenGL texture
+   glBindTexture   (GL_TEXTURE_2D, iHeader.tex);  
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ 
+   glTexImage2D (GL_TEXTURE_2D,
+                 0,
+                 GL_LUMINANCE_ALPHA,
+                 iHeader.texWidth,
+                 iHeader.texHeight,
+                 0,
+                 GL_LUMINANCE_ALPHA,
+                 GL_UNSIGNED_BYTE,
+                 (GLvoid *)texBytes);
+ 
+   // Free texture pixels memory
+   CleanupStack::Pop ();
+   delete [] texBytes;	
+ 
+   // Close input file
+   readStream.Close();
+   readStream.Pop();
+}
+ 
+//_____________________________________________________________________________
+//
+// Font destruction.
+//
+ 
+void GLFont::Destroy ()
+{
+   //Delete the character array if necessary
+   if (iHeader.chars)
+   {
+      delete [] iHeader.chars;
+      iHeader.chars = 0;
+   }
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the texture dimensions.
+//
+ 
+void GLFont::GetTexSize (TInt & aWidth, TInt & aHeight)
+{	
+   aWidth  = iHeader.texWidth;
+   aHeight = iHeader.texHeight;
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the character interval.
+//
+ 
+void GLFont::GetCharInterval (TInt & aStart, TInt & aEnd)
+{	
+   aStart = iHeader.startChar;
+   aEnd   = iHeader.endChar;
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the dimensions of a character.
+//
+ 
+void GLFont::GetCharSize (TText8 aChar, TInt & aWidth, TInt aHeight)
+{
+   // Make sure character is in range
+   if (aChar < iHeader.startChar || aChar > iHeader.endChar)
+   {
+      // Not a valid character, so it obviously has no size
+      aWidth  = 0;
+      aHeight = 0;
+   }
+   else
+   {
+      GLFontChar* fontChar;
+ 
+      // Retrieve character size
+      fontChar = & iHeader.chars [aChar - iHeader.startChar];		
+      aWidth  = FixedToInt (MultiplyFixed (fontChar->dx, IntToFixed (iHeader.texWidth) ) );
+      aHeight = FixedToInt (MultiplyFixed (fontChar->dy, IntToFixed (iHeader.texHeight) ) );		
+   }
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the dimensions of a string.
+//
+ 
+void GLFont::GetStringSize (const TDesC8 & aText, TInt & aWidth, TInt & aHeight)
+{	
+   // Height is the same for now...might change in future
+   aHeight = FixedToInt (MultiplyFixed (iHeader.chars [iHeader.startChar].dy, IntToFixed (iHeader.texHeight) ) ); 
+ 
+   // texWidth as fixed
+   const GLfixed texWidthx = IntToFixed (iHeader.texWidth);
+ 
+   // Calculate width of string	
+   GLfixed widthx = 0;
+   for (TInt i = 0; i < aText.Length(); i++)
+   {
+      // Make sure character is in range
+      const TText8 c = aText [i];
+      if (c < iHeader.startChar || c > iHeader.endChar)
+         continue;
+ 
+      // Get pointer to glFont character
+      const GLFontChar* fontChar = & iHeader.chars [c - iHeader.startChar];
+ 
+      // Get width and height
+      widthx += MultiplyFixed (fontChar->dx, texWidthx);		
+   }
+ 
+   // Save width
+   aWidth = FixedToInt (widthx);
+}
+ 
+//_____________________________________________________________________________
+//
+// Renders a string. Reference point is top-left.
+//
+ 
+void GLFont::DrawString (const TDesC8 & aText, GLfixed aX, GLfixed aY)
+{
+   // vertex arrays to render the string
+   GLfixed  vertices [4*2];
+   GLfixed texCoords [4*2];	
+   const GLubyte indices [] = {1, 2, 0, 3};
+ 
+   glVertexPointer  (2, GL_FIXED, 0, vertices);
+   glTexCoordPointer (2, GL_FIXED, 0, texCoords); 	
+ 
+   // Bind texture
+   glBindTexture (GL_TEXTURE_2D, iHeader.tex);
+ 
+   // Loop through characters
+   for (TInt i = 0; i < aText.Length(); i++)
+   {
+      // Make sure character is in range
+      TText8 c = aText [i];
+      if (c < iHeader.startChar || c > iHeader.endChar)
+         continue;
+ 
+      // Get pointer to glFont character
+      GLFontChar* fontChar = &iHeader.chars [c - iHeader.startChar];
+ 
+      // Get width and height
+      GLfixed width =  MultiplyFixed (fontChar->dx, IntToFixed (iHeader.texWidth) );
+      GLfixed height = MultiplyFixed (fontChar->dy, IntToFixed (iHeader.texHeight) );
+ 
+      // Specify texture coordinates
+      texCoords [0] = fontChar->tx1; texCoords [1] = fontChar->ty1;
+      texCoords [2] = fontChar->tx1; texCoords [3] = fontChar->ty2;
+ 
+      texCoords [4] = fontChar->tx2; texCoords [5] = fontChar->ty2;
+      texCoords [6] = fontChar->tx2; texCoords [7] = fontChar->ty1;
+ 
+      // and vertices
+      vertices [0] = aX;         vertices [1] = aY;
+      vertices [2] = aX;         vertices [3] = aY - height;
+   
+      vertices [4] = aX + width; vertices [5] = aY - height;
+      vertices [6] = aX + width; vertices [7] = aY;
+ 
+      // draw
+      glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
+ 
+      // Move to next character
+      aX += width;
+   }
+ 
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/project.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,309 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "project.h"
+#define fabs(x) ((x) < 0 ? -(x) : (x))
+#define MEMCPY(x,y,z) Mem::Copy((x),(y),(z))
+
+/*
+ * Transform a point (column vector) by a 4x4 matrix.  I.e.  out = m * in
+ * Input:  aMatrix - the 4x4 matrix
+ *         aIn - the 4x1 vector
+ * Output: aOut - the resulting 4x1 vector.
+ */
+static void TransformPoint(GLdouble aOut[4], const GLdouble aMatrix[16], const GLdouble aIn[4])
+    {
+#define M(row,col)  aMatrix[col*4+row]
+    aOut[0] = M(0, 0) * aIn[0] + M(0, 1) * aIn[1] + M(0, 2) * aIn[2] + M(0, 3) * aIn[3];
+    aOut[1] = M(1, 0) * aIn[0] + M(1, 1) * aIn[1] + M(1, 2) * aIn[2] + M(1, 3) * aIn[3];
+    aOut[2] = M(2, 0) * aIn[0] + M(2, 1) * aIn[1] + M(2, 2) * aIn[2] + M(2, 3) * aIn[3];
+    aOut[3] = M(3, 0) * aIn[0] + M(3, 1) * aIn[1] + M(3, 2) * aIn[2] + M(3, 3) * aIn[3];
+#undef M
+    }
+
+/*
+ * Perform a 4x4 matrix multiplication  (product = a x b).
+ * Input:  a, b - matrices to multiply
+ * Output: aProduct - product of a and b
+ */
+static void MultiplyMatrix(GLdouble* aProduct, const GLdouble* a, const GLdouble* b)
+    {
+    GLdouble temp[16];
+    GLint i;
+
+#define A(row,col)  a[(col<<2)+row]
+#define B(row,col)  b[(col<<2)+row]
+#define T(row,col)  temp[(col<<2)+row]
+
+    for (i = 0; i < 4; i++)
+        {
+        T(i, 0) = A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i, 3) * B(3, 0);
+        T(i, 1) = A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i, 3) * B(3, 1);
+        T(i, 2) = A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i, 3) * B(3, 2);
+        T(i, 3) = A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i, 3) * B(3, 3);
+        }
+
+#undef A
+#undef B
+#undef T
+   MEMCPY(aProduct, temp, 16 * sizeof(GLdouble));
+    }
+
+/*
+ * Compute inverse of 4x4 transformation matrix.
+ * Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
+ */
+static GLboolean InvertMatrix(const GLdouble * aMatrix, GLdouble * aOut)
+    {
+    // OpenGL Matrices are COLUMN major
+#define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; }
+#define MAT(m,r,c) (m)[(c)*4+(r)]
+
+    GLdouble wtmp[4][8];
+    GLdouble m0, m1, m2, m3, s;
+    GLdouble *r0, *r1, *r2, *r3;
+
+    r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
+
+    r0[0] = MAT(aMatrix, 0, 0), r0[1] = MAT(aMatrix, 0, 1),
+    r0[2] = MAT(aMatrix, 0, 2), r0[3] = MAT(aMatrix, 0, 3),
+    r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
+    r1[0] = MAT(aMatrix, 1, 0), r1[1] = MAT(aMatrix, 1, 1),
+    r1[2] = MAT(aMatrix, 1, 2), r1[3] = MAT(aMatrix, 1, 3),
+    r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
+    r2[0] = MAT(aMatrix, 2, 0), r2[1] = MAT(aMatrix, 2, 1),
+    r2[2] = MAT(aMatrix, 2, 2), r2[3] = MAT(aMatrix, 2, 3),
+    r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
+    r3[0] = MAT(aMatrix, 3, 0), r3[1] = MAT(aMatrix, 3, 1),
+    r3[2] = MAT(aMatrix, 3, 2), r3[3] = MAT(aMatrix, 3, 3),
+    r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
+
+    // choose pivot - or die
+    if (fabs(r3[0]) > fabs(r2[0]))
+        SWAP_ROWS(r3, r2);
+    if (fabs(r2[0]) > fabs(r1[0]))
+        SWAP_ROWS(r2, r1);
+    if (fabs(r1[0]) > fabs(r0[0]))
+        SWAP_ROWS(r1, r0);
+    if (0.0 == r0[0])
+        return GL_FALSE;
+
+    // eliminate first variable
+    m1 = r1[0] / r0[0];
+    m2 = r2[0] / r0[0];
+    m3 = r3[0] / r0[0];
+    s = r0[1];
+    r1[1] -= m1 * s;
+    r2[1] -= m2 * s;
+    r3[1] -= m3 * s;
+    s = r0[2];
+    r1[2] -= m1 * s;
+    r2[2] -= m2 * s;
+    r3[2] -= m3 * s;
+    s = r0[3];
+    r1[3] -= m1 * s;
+    r2[3] -= m2 * s;
+    r3[3] -= m3 * s;
+    s = r0[4];
+
+    if (s != 0.0)
+        {
+        r1[4] -= m1 * s;
+        r2[4] -= m2 * s;
+        r3[4] -= m3 * s;
+        }
+    s = r0[5];
+
+    if (s != 0.0)
+        {
+        r1[5] -= m1 * s;
+        r2[5] -= m2 * s;
+        r3[5] -= m3 * s;
+        }
+    s = r0[6];
+
+    if (s != 0.0)
+        {
+        r1[6] -= m1 * s;
+        r2[6] -= m2 * s;
+        r3[6] -= m3 * s;
+        }
+    s = r0[7];
+
+    if (s != 0.0)
+        {
+        r1[7] -= m1 * s;
+        r2[7] -= m2 * s;
+        r3[7] -= m3 * s;
+        }
+
+    // choose pivot - or die
+    if (fabs(r3[1]) > fabs(r2[1]))
+        SWAP_ROWS(r3, r2);
+    if (fabs(r2[1]) > fabs(r1[1]))
+        SWAP_ROWS(r2, r1);
+    if (0.0 == r1[1])
+        return GL_FALSE;
+
+    // eliminate second variable
+    m2 = r2[1] / r1[1];
+    m3 = r3[1] / r1[1];
+    r2[2] -= m2 * r1[2];
+    r3[2] -= m3 * r1[2];
+    r2[3] -= m2 * r1[3];
+    r3[3] -= m3 * r1[3];
+    s = r1[4];
+
+    if (0.0 != s)
+        {
+        r2[4] -= m2 * s;
+        r3[4] -= m3 * s;
+        }
+    s = r1[5];
+
+    if (0.0 != s)
+        {
+        r2[5] -= m2 * s;
+        r3[5] -= m3 * s;
+        }
+    s = r1[6];
+
+    if (0.0 != s)
+        {
+        r2[6] -= m2 * s;
+        r3[6] -= m3 * s;
+        }
+    s = r1[7];
+
+    if (0.0 != s)
+        {
+        r2[7] -= m2 * s;
+        r3[7] -= m3 * s;
+        }
+
+    // choose pivot - or die
+    if (fabs(r3[2]) > fabs(r2[2]))
+        SWAP_ROWS(r3, r2);
+    if (0.0 == r2[2])
+        return GL_FALSE;
+
+    // eliminate third variable
+    m3 = r3[2] / r2[2];
+    r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
+    r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7];
+
+    // last check
+    if (0.0 == r3[3])
+        return GL_FALSE;
+
+    s = 1.0 / r3[3];     /* now back substitute row 3 */
+    r3[4] *= s;
+    r3[5] *= s;
+    r3[6] *= s;
+    r3[7] *= s;
+
+    m2 = r2[3];          /* now back substitute row 2 */
+    s = 1.0 / r2[2];
+    r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
+    r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
+    m1 = r1[3];
+    r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
+    r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
+    m0 = r0[3];
+    r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
+    r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
+
+    m1 = r1[2];          /* now back substitute row 1 */
+    s = 1.0 / r1[1];
+    r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
+    r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
+    m0 = r0[2];
+    r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
+    r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
+
+    m0 = r0[1];          /* now back substitute row 0 */
+    s = 1.0 / r0[0];
+    r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
+    r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
+
+    MAT(aOut, 0, 0) = r0[4];
+    MAT(aOut, 0, 1) = r0[5], MAT(aOut, 0, 2) = r0[6];
+    MAT(aOut, 0, 3) = r0[7], MAT(aOut, 1, 0) = r1[4];
+    MAT(aOut, 1, 1) = r1[5], MAT(aOut, 1, 2) = r1[6];
+    MAT(aOut, 1, 3) = r1[7], MAT(aOut, 2, 0) = r2[4];
+    MAT(aOut, 2, 1) = r2[5], MAT(aOut, 2, 2) = r2[6];
+    MAT(aOut, 2, 3) = r2[7], MAT(aOut, 3, 0) = r3[4];
+    MAT(aOut, 3, 1) = r3[5], MAT(aOut, 3, 2) = r3[6];
+    MAT(aOut, 3, 3) = r3[7];
+    
+    return GL_TRUE;
+
+#undef MAT
+#undef SWAP_ROWS
+    }
+
+GLint gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
+       const GLdouble model[16], const GLdouble proj[16],
+       const GLint viewport[4],
+       GLdouble* winx, GLdouble* winy, GLdouble* winz)
+    {
+    GLdouble in[4], out[4];
+
+    in[0] = objx;
+    in[1] = objy;
+    in[2] = objz;
+    in[3] = 1.0;
+    TransformPoint(out, model, in);
+    TransformPoint(in, proj, out);
+
+    if (in[3] == 0.0)
+        return GL_FALSE;
+
+    in[0] /= in[3];
+    in[1] /= in[3];
+    in[2] /= in[3];
+
+    *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
+    *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
+    *winz = (1 + in[2]) / 2;
+    return GL_TRUE;
+}
+
+GLint gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
+         const GLdouble model[16], const GLdouble proj[16],
+         const GLint viewport[4],
+         GLdouble * objx, GLdouble * objy, GLdouble * objz)
+    {
+    GLdouble m[16], A[16];
+    GLdouble in[4], out[4];
+
+    in[0] = (winx - viewport[0]) * 2 / viewport[2] - 1.0;
+    in[1] = (winy - viewport[1]) * 2 / viewport[3] - 1.0;
+    in[2] = 2 * winz - 1.0;
+    in[3] = 1.0;
+
+    MultiplyMatrix(A, proj, model);
+    InvertMatrix(A, m);
+
+    TransformPoint(out, m, in);
+    if (out[3] == 0.0)
+        return GL_FALSE;
+    *objx = out[0] / out[3];
+    *objy = out[1] / out[3];
+    *objz = out[2] / out[3];
+    return GL_TRUE;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Inc/IEEngineUtils.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef  __IEENGINEUTILS__
+#define __IEENGINEUTILS__
+
+#include <f32file.h>
+#include <f32file.h>
+#include <e32base.h>
+//#include "IEImageData.h"
+#include "IEImage.h"
+
+class CIEEngineUtils: public CBase
+{
+public:
+	/*
+	* Symbian First phase constructor
+	* 
+	* @aParam aFs - FileServer
+	*/
+	IMPORT_C CIEEngineUtils(RFs &aFs);
+	
+	/*
+	* Destructor.
+	* 
+	*/
+	IMPORT_C ~CIEEngineUtils();
+public:
+	/*
+	 * GenerateIEThumbNailPath depending on the resolution
+	 * 
+	 * @aParam  aTNResolution - Thumbnail resolution
+	 * @aParam  aIETNFileName - IEFilename
+	 */ 
+    IMPORT_C static void GenerateThumbnailFileName(TThumbSize aResolution, const TDesC& aFileName, TDes& aThumbnailFileName);
+    IMPORT_C static void DeleteThumbnails(TDesC& aFileName, RFs& aFs);
+    
+    /*
+     * Create TN folder
+     * 
+     * @aParam  aTNPath -  Thumbnail path
+     * @return - systemwide error code.
+     */ 
+     IMPORT_C static TInt CreateTNFolder(RFs aFs, const TDesC& aTNPath);
+     IMPORT_C static void PrivatePath(TFileName& aFileName);
+     
+     IMPORT_C TInt AddFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+     IMPORT_C TInt RemoveFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+     IMPORT_C HBufC8* ReadExifMakerNoteL(const TDes &aFileName);
+     IMPORT_C void ReadFaceCoordinatesL(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+     IMPORT_C void WriteFaceCoordinatesL(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+     IMPORT_C void GetModifiedTimeL(const TDes &aFileName, TTime& aTime);
+     IMPORT_C void GetImageSizeL(const TDes &aFileName, TSize& aSize);
+     IMPORT_C static HBufC8* ReadExifThumbnailL(RFs& aFs, const TDesC& aFileName);     
+     //void ReadFile2BuffL(const TDes &aFileName, HBufC8** buffer);
+     //TPtr8 LoadImageIntoMemoryLC(const TDesC& aFileName);
+     IMPORT_C void GetExifDateTimeAndOrientationL(const TDesC& aFilename, TTime& aExifDateTime, TUint16& aOrientation);
+     IMPORT_C static TUid GetImageDecoderUid();
+     
+private:
+      IMPORT_C static HBufC8* ReadExifHeaderL(RFs& aFs, const TDesC& aFileName);
+      
+      RFs& iFs;
+};
+#endif /*__IEENGINEUTILS__*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Inc/IEImageData.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEDATA_H__
+#define __IEIMAGEDATA_H__
+
+// Include files
+#include <e32base.h> 
+#include <IEImage.h>
+
+class HGridData
+    {
+public:
+    TBool       iCorrupted;
+    float       iRotationAngle; // rotation angle of one image
+    float       iTargetRotationAngle; // target rotation angle of one image
+    float       iX, iY, iZ; // OpenGL coordinates
+    float       iScale; // OpenGL iScale
+    TUint       iGlLQ32TextIndex; // OpenGL 128x128 texture index
+    TUint       iGlLQ128TextIndex; // OpenGL 128x128 texture index
+    TUint       iGlHQ512TextIndex; // OpenGL 512x512 texture index
+    TUint       iGlSuperHQTextIndex; // OpenGL 2048x2048 texture index
+    
+    // Returns opengl index for best quality image that has been loaded
+    inline TUint BestImage(void)
+        {
+        if (iGlSuperHQTextIndex!=0)
+            return iGlSuperHQTextIndex;
+        if (iGlHQ512TextIndex!=0)
+            return iGlHQ512TextIndex;
+        if (iGlLQ128TextIndex!=0)
+            return iGlLQ128TextIndex;
+        if (iGlLQ32TextIndex!=0)
+            return iGlLQ32TextIndex;
+        return 0;
+        }
+    };
+
+
+class CImageData
+    {
+public:
+    IMPORT_C static CImageData* NewL(TUint32 aImagesReady = 0);
+    IMPORT_C ~CImageData();
+    
+protected:    
+    TReal       iAspectRatio; 
+    TSize       iSize;
+    TTime       iFileTime, iCreatedTime;
+    HBufC*      iPath;
+    HBufC*      iFileName;
+    TUint16     iImagesReady;
+    TUint16     iOrientation;
+    TInt        iNumberOfFaces;
+
+    void ConstructL(TUint32 aImagesReady);
+    TBool IsCreatedTimeSet() const;
+    CImageData();
+    
+public:    
+    HGridData   iGridData;
+    TInt        iPersonId;  // TODO temp solution, -1 = no person
+    
+    IMPORT_C void GetFileName(TFileName & aFullFileName, TThumbSize aSize) const;
+    IMPORT_C void GetPath(TFileName & aPath) const;
+    IMPORT_C void GetFileName(TFileName & aFileName) const;
+    IMPORT_C void SetFileNameL(const TFileName & aFullFileName);
+    IMPORT_C TBool IsImageReady(TThumbSize aSize) const;
+    IMPORT_C void SetImageReady(TThumbSize aSize, TBool bReady);
+    IMPORT_C const TReal GetAspectRatio() const;
+    IMPORT_C void SetSize(const TSize aSize);
+    IMPORT_C TSize GetSize() const;
+    IMPORT_C const TTime & GetFileTime() const;
+    IMPORT_C void SetFileTime(const TTime & aTime);
+    IMPORT_C const TTime & GetCreatedTime() const;
+    IMPORT_C void SetCreatedTime(const TTime & aTime);
+    IMPORT_C TUint16 GetOrientation() const;
+    IMPORT_C void SetOrientation(TUint16 aOrientation);
+    IMPORT_C TInt GetNumberOfFaces() const;
+    IMPORT_C void SetNumberOfFaces(TInt aValue);
+    IMPORT_C TBool IsSamePath(CImageData& aImageData) const;
+    };  
+
+#endif // __IEIMAGEDATA_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Inc/ImagicConsts.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,131 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IMAGICCONSTS_H__
+#define __IMAGICCONSTS_H__
+
+//Feature definition flags
+#define USE_BITMAPS_TNS //Set on if want to use Symbian Bitmap TNs 
+//#define USE_RGBA //Set on if want to use RBGA(RGB+Alpha) bitmaps
+
+#ifdef __WINS__
+    #undef _S60_5x_ACCELEROMETER_
+    #define _S60_3x_ACCELEROMETER_
+    #define _ACCELEROMETER_SUPPORTED_
+#else
+    #define _ACCELEROMETER_SUPPORTED_
+#ifdef __S60_50__
+    #define _S60_5x_ACCELEROMETER_
+#else
+    #define _S60_3x_ACCELEROMETER_
+#endif
+#endif
+
+
+struct FloatCoords
+    {
+    float iX;
+    float iY;
+    };
+
+//App UI Feature definition flags
+//#define BUBLE_EFFECT
+#define DRAW_FRAME
+//#define MIPMAPPING
+#define SUPERZOOM
+#define IMAGIC_DATABASE
+#define FACE_DETECTION
+//#define SHADOW_PHOTOS
+//#define EMPTY_IMAGE_AS_BMP       
+#define EMPTY_IMAGE_AS_WIREFRAME
+#define GAP_BETWEEN_FOLDERS
+//#define PEOPLE_VIEW
+
+/**
+* EXIF data DateTimeOriginal length
+*/
+const TInt KPMMExifDateTimeOriginalLength = 20;
+
+
+_LIT(KEmptyString, "");
+_LIT(KSpace, " ");
+_LIT(KHash, "#");
+_LIT(KZero, "0");
+_LIT(KUnderScr, "_");
+_LIT(KDot, ".");
+_LIT(KSlash, "/");
+//_LIT(KNewLine, "\n\r");
+_LIT(KNewLine, "\r");
+
+_LIT(KPAlbTNFilePath, "_PAlbTN");
+
+_LIT(K32x32TNFilePath, "_PAlbTN\\IEImagicTN_32x32\\");
+_LIT(K128x96TNFilePath, "_PAlbTN\\");
+_LIT(K128x128TNFilePath, "_PAlbTN\\IEImagicTN_128x128\\");
+_LIT(K512x512TNFilePath, "_PAlbTN\\IEImagicTN_512x512\\");
+
+_LIT( K32x32Ext, "_32x32" );
+_LIT( K128x96Ext, "_128x96" );
+_LIT( K128x128Ext, "_128x128" );
+_LIT( K512x512Ext, "_512x512" );
+
+_LIT(KFaces, "ImagicFaces\\");
+_LIT8(KFaceCoordsHeader, "Face Coordinates");
+_LIT8(KFaceCoordsImagicVersion, "Imagic v2.1:");
+
+_LIT(KRootPathFDrive, "F:\\");
+_LIT(KRootPathCDrive, "C:\\");
+
+#ifdef __WINS__
+    _LIT(KFacesPath, "ImagicFaces");
+    _LIT(KRootImagePath, "C:\\Images\\");
+    _LIT(ImagePath, "Images\\");
+    _LIT(KRootFacesImagePath, "C:\\Images\\ImagicFaces");
+#else
+    _LIT(KFacesPath, "ImagicFaces");
+    //_LIT(KRootImagePath, "E:\\Images\\");
+    _LIT(ImagePath, "Images\\");
+    _LIT(KRootFacesImagePath, "E:\\Images\\ImagicFaces");
+#endif
+
+_LIT(KCRootBgroundImages, "C:\\Images\\Data\\Backgrounds");
+_LIT(KFileString, "*.JPG");
+
+#ifdef __WINS__
+_LIT(KSmileFileName, "c:\\data\\smile.mbm");
+_LIT(KZoomFileName, "c:\\data\\zoom.mbm");
+_LIT(KLoadingFileName, "c:\\data\\loading.mbm");
+_LIT(KExitFileName, "c:\\data\\exit.mbm");
+_LIT(KMenuFileName, "c:\\data\\menu.mbm");
+_LIT(KShadowFileName, "c:\\data\\shadow.mbm");
+#else
+_LIT(KSmileFileName, "c:\\resource\\apps\\smile.mbm");
+_LIT(KZoomFileName, "c:\\resource\\apps\\zoom.mbm");
+_LIT(KLoadingFileName, "c:\\resource\\apps\\loading.mbm");
+_LIT(KExitFileName, "c:\\resource\\apps\\exit.mbm");
+_LIT(KMenuFileName, "c:\\resource\\apps\\menu.mbm");
+_LIT(KShadowFileName, "c:\\resource\\apps\\shadow.mbm");
+#endif
+
+#define USE_SETTINGS_FILE
+#ifdef __WINS__
+_LIT(KSettingFileName,"C:\\data\\photobrowser.cfg");
+#else
+_LIT(KSettingFileName,"C:\\data\\photobrowser.cfg");
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Inc/ImagicUtils.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,170 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IMAGICUTILS_
+#define IMAGICUTILS_
+
+#include <e32base.h>
+#include <W32STD.H> 
+#include <aknwaitdialog.h> 
+#include "Imagic.hrh"
+#include <AknInfoPopupNoteController.h>
+
+class CAknInfoPopupNoteController;
+
+class CImagicUtils: public CBase
+{
+public:
+	/*
+	* Symbian First phase constructor
+	* 
+	* @aParam aFs - FileServer
+	*/
+	static CImagicUtils* NewL(RFs &aFs);
+	
+	/*
+	* Destructor.
+	* 
+	*/
+ 	~CImagicUtils();
+public:
+    void DisplayYearAndMonth(TInt aIndex, TDateTime dateTime);
+    void ExecutePopUpNote(TDes& aFilename, TInt aTime, TBool aAligment);
+    void ExecutePopUpNote(TInt aResourceId, TDes& aFilename, TInt aTime);
+    void ExecutePopUpNote(TInt aResourceId, TInt aTime);
+    void ExecuteFileScanPopUpNote(TInt aResourceId, TInt aTime);
+    
+	/*
+	* Show Text on Display
+	*
+	* @aParam aText - Text to Display on screen
+	* @aParam  gc - Windows GC
+	* @aParam aRect - Window rectangle.
+	* @aParam aFont - DisplayFont 
+	* @aParam  aTransparentBlack - Black Transparent value 
+	* @aParam  aTransparentWhite - White Transparent value 
+	*/
+    void ShowText(const TDesC16& aText, CWindowGc& gc, TRect aRect,const CFont*aFont,
+    			 TRgb aTransparentBlack, TRgb aTransparentWhite) const;
+    			 
+    /*
+    * Executing Error Dialog
+    * 
+    * @aParam aError - Error code
+    * @aParam aResourceId - dialog Resource ID
+    */
+   	void ExecuteQueryDialog(TInt aError,TInt aResourceId);
+   	
+   	/*
+    * Executing Query Dialog
+    * 
+    * @aParam aResourceId - dialog Resource ID
+    * @returns - Returns Dialog error ID
+    */
+   	TInt ExecuteQueryDialog(TInt aResourceId);
+   	
+   	
+   /*
+    * Display Wait Dialog
+    * 
+    * @aParam aResourceId - dialog Resource ID
+    * @aParam aSingular - Text to execute 
+    */
+    void DisplayWaitDialog(TInt aResourceId, TBool aSingular);
+   
+    /*
+    * Cancels Wait Dialog
+    * 
+    */
+    void CancelWaitDialog();
+    
+    /*
+    * Display Wait Dialog
+    * 
+    * @aParam aResourceId - dialog Resource ID
+    */
+    void ShowWaitDialog(TInt aResouceId);
+    
+    /*
+    * Cancels Wait Dialog
+    * 
+    */
+    void ProcessFinishedL();
+     
+     
+    /*
+    * Display Infonote 
+    */
+    void DisplayTNInfoNoteStarted();
+    
+    /*
+    * Display End Info note.
+    */
+    void DisplayTNInfoNoteCompleted();
+    
+    /*
+    * Show Info note.
+    *
+    * @aParam aResourceId - Resource Id.
+    */
+    void ShowInfoNote(TInt aResourceId);
+    
+    /*
+    * Display Saving Dailog
+    *
+    * @aParam aResourceId - Resource Id.
+    */  
+    void DisplaySavingDialog(TInt aResourceId);
+     
+    /*
+    * Show Info note.
+    *
+    * @aParam aResourceId - Resource Id.
+    * @aParam FileName - File Name.
+    */
+    void ShowInfoNote(TInt aResourceId, TDes& aFilename);
+    
+     /*
+    * Get New File Name
+    *
+    * @aParam aFileName - Filename
+    */
+    
+    void GetNewFileName( TDes&  aFileName );
+    
+    /*
+    * Get Original file name
+    *
+    * @aParam aFileName - Original file name.
+    */
+    void GetOriginalFileName( TDes&  aFileName );
+private:
+	void ConstructL();
+	CImagicUtils(RFs &aFs);
+	
+	void ExecuteInternalWaitNote(TInt aResourceId,TBool aTextPlurality);
+ 
+private:
+
+
+	RFs iFs;
+	CAknWaitDialog*                iWaitDialog;
+	CAknInfoPopupNoteController*   iPopUpNote;
+	CAknInfoPopupNoteController*   iFileScanPopUpNote;
+	HBufC*                         iTextResource;
+};
+#endif /*IMAGICUTILS_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Inc/debug.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IMAGIC_TRACE_H__
+#define __IMAGIC_TRACE_H__
+
+//#define _IMAGIC_DEBUG
+#ifdef _IMAGIC_DEBUG
+
+#include <e32debug.h>
+
+#define DP0_IMAGIC(string)                            RDebug::Print(string)
+#define DP1_IMAGIC(string,arg1)                       RDebug::Print(string,arg1)
+#define DP2_IMAGIC(string,arg1,arg2)                  RDebug::Print(string,arg1,arg2)
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             RDebug::Print(string,arg1,arg2,arg3)
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        RDebug::Print(string,arg1,arg2,arg3,arg4)
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)   RDebug::Print(string,arg1,arg2,arg3,arg4,arg5)
+
+#else
+
+#define DP0_IMAGIC(string)                            
+#define DP1_IMAGIC(string,arg1)                       
+#define DP2_IMAGIC(string,arg1,arg2)                  
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)
+#endif // _DEBUG
+
+
+#endif //__IMAGIC_TRACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Src/IEEngineUtils.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,688 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include <exifmodify.h>
+#include <BAUTILS.H>
+#include "IEEngineUtils.h" 
+#include "ImagicConsts.h"
+#include "debug.h"
+#include <exifread.h>
+#include <ExifUtility.h> 
+#include <ICLExif.h> 
+//#include <iclextjpegapi.h>  // For CExtJpegDecoder
+
+#define KJpegDecIVAUidValue 0x10272C10
+#define KJpegOptUidValue 0x101FF555
+
+EXPORT_C CIEEngineUtils::CIEEngineUtils(RFs& aFs)
+    : iFs(aFs)
+    {
+    } 
+
+EXPORT_C CIEEngineUtils::~CIEEngineUtils()
+    {
+    }
+
+/* Generating IETNFileName with complete path */
+EXPORT_C void CIEEngineUtils::GenerateThumbnailFileName(
+        TThumbSize aTNResolution,
+        const TDesC& aSavedFileName, 
+        TDes &aIETNFileName)
+    {
+    TFileName tmpName;
+    TParse parser;
+    switch(aTNResolution)
+        {
+        case ESize512x512:
+            {
+            parser.Set(aSavedFileName, NULL, NULL);
+            tmpName = parser.DriveAndPath();//only path name
+            tmpName.Append(K512x512TNFilePath);
+            tmpName.Append(parser.NameAndExt());
+            tmpName.Append(K512x512Ext);
+            aIETNFileName.Copy(tmpName);
+            break;
+            }
+        case ESize128x128:
+           {
+           parser.Set(aSavedFileName, NULL, NULL);
+           tmpName = parser.DriveAndPath();//only path name
+           tmpName.Append(K128x128TNFilePath);
+           tmpName.Append(parser.NameAndExt());
+           tmpName.Append(K128x128Ext);
+           aIETNFileName.Copy(tmpName);
+           break;
+           }
+        case ESize32x32:
+           {
+           parser.Set(aSavedFileName, NULL, NULL);
+           tmpName = parser.DriveAndPath();//only path name
+           tmpName.Append(K32x32TNFilePath);
+           tmpName.Append(parser.NameAndExt());
+           tmpName.Append(K32x32Ext);
+           aIETNFileName.Copy(tmpName);
+           break;
+           }
+        default:
+           ASSERT(0);
+           break;
+        };
+    }
+
+EXPORT_C void CIEEngineUtils::DeleteThumbnails(TDesC& aFileName, RFs& aFs)
+    {
+    TThumbSize res[] = { ESize512x512, ESize128x128, ESize32x32 };
+    for (TInt i = 0;i < sizeof(res)/ sizeof(TThumbSize);i++)
+        {
+        TFileName thumbFileName;
+        GenerateThumbnailFileName(res[i], aFileName, thumbFileName);
+        BaflUtils::DeleteFile(aFs, thumbFileName);
+        }    
+    }
+
+/*Creating TN Folder */
+EXPORT_C TInt CIEEngineUtils::CreateTNFolder(RFs aFs, const TDesC& aTNPath)
+    {
+    TInt error = KErrNone;
+    if( !BaflUtils::PathExists( aFs, aTNPath ) )
+        {
+        error = aFs.MkDirAll( aTNPath );
+        error = aFs.SetAtt( aTNPath, KEntryAttHidden, NULL );
+        }
+   
+    return error;
+    }
+
+// Writes face coordinates to Exif data if faces was found
+EXPORT_C TInt CIEEngineUtils::AddFaceCoordinate(const TFileName aFilename, RArray<TRect>& aCordArray)
+    {
+    DP0_IMAGIC(_L("CIEEngineUtils::AddFaceCoordinate++"));
+    // Read first current maker note to new array from given file
+    RArray<TRect> newCordArray;
+    ReadFaceCoordinatesL(aFilename, newCordArray);
+     
+    // Append existing coords to new coords array
+    for(TInt i=0; i<newCordArray.Count(); i++)
+        {
+        aCordArray.Append(newCordArray[i]);
+        }
+              
+     // Write all coords to file exif data manufactorer note
+    WriteFaceCoordinatesL(aFilename, aCordArray);
+     
+    newCordArray.Close();
+    
+    DP0_IMAGIC(_L("CIEEngineUtils::AddFaceCoordinate--"));
+    return KErrNone;
+    }
+
+EXPORT_C HBufC8* CIEEngineUtils::ReadExifMakerNoteL(const TDes &aFileName)
+    {
+    DP0_IMAGIC(_L("CIEEngineUtils::ReadExifMakerNoteL++"));
+    
+    HBufC8* exif = ReadExifHeaderL(iFs, aFileName);
+    CleanupStack::PushL( exif );
+    
+    CExifRead* exifRead = CExifRead::NewL(exif->Des(), CExifRead::ENoJpeg);
+    CleanupStack::PushL( exifRead );
+        
+    // Get required data from the Exif image...
+    /*TUint32  xRes;
+    TUint32  yRes;
+    exifRead->GetPixelXDimension(xRes);
+    exifRead->GetPixelYDimension(yRes);*/  
+    HBufC8* makerNote = exifRead->GetMakerNoteL();
+    CleanupStack::PushL( makerNote );
+            
+    CleanupStack::Pop( makerNote );
+    CleanupStack::PopAndDestroy( exifRead );
+    CleanupStack::PopAndDestroy( exif );
+
+    DP0_IMAGIC(_L("CIEEngineUtils::ReadExifMakerNoteL--"));
+    return makerNote;
+    }
+
+EXPORT_C TInt CIEEngineUtils::RemoveFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray)
+    {
+    DP0_IMAGIC(_L("CIEEngineUtils::RemoveFaceCoordinate++"));
+    
+    //Read first current make note
+    HBufC8* makerNote = ReadExifMakerNoteL(a128x128TNFileName);
+     
+    // Allocate buffer for coords to be removed
+    HBufC8* heapComment = HBufC8::NewL(100);
+    TPtr8 ptrCoords = heapComment->Des();
+    //Copy coords to be removed to descriptor
+    for(TInt i=0; i < aCordArray.Count(); i++)
+        {
+        ptrCoords.AppendNum(aCordArray[i].iTl.iX);
+        ptrCoords.Append(' ');
+        ptrCoords.AppendNum(aCordArray[i].iTl.iY);
+        ptrCoords.Append(' ');
+        ptrCoords.AppendNum(aCordArray[i].iBr.iX );
+        ptrCoords.Append(' ');
+        ptrCoords.AppendNum(aCordArray[i].iBr.iY);
+        ptrCoords.Trim();
+        }
+     
+    //Find coordinates from maker note
+    TPtr8 tmpPtr = makerNote->Des();
+    TInt res = tmpPtr.Find(ptrCoords);
+     
+    if(res == KErrNotFound)
+        return res;
+         
+    //Remove coordinates from maker note
+    TInt l = ptrCoords.Length();
+    tmpPtr.Delete(res, ptrCoords.Length()+1);
+     
+    //Find number of faces from maker note and update it
+    _LIT8(KNumberOfFace, "#");
+    res = tmpPtr.Find(KNumberOfFace);
+     
+    TLex8 lex(makerNote->Ptr());
+    lex.SkipAndMark(res+1);
+    TInt faceCount = 0;
+    lex.Val(faceCount);
+     
+    //Check lenght of number of faces string
+    TInt length = 0;
+    //TInt aFaceNumber = 1;
+    if(faceCount < 10)
+        length = 1;
+    else
+        length = 2;
+          
+    HBufC8* numberOfFaces = HBufC8::NewL(length);
+    TPtr8 FaceNroPtr = numberOfFaces->Des();
+    FaceNroPtr.AppendNum(faceCount-1);
+              
+    tmpPtr.Replace(res+1, length, FaceNroPtr);
+    //TPtr8 numberOfFaces;
+     
+    delete numberOfFaces;
+    //numberOfFaces.Copy();
+    
+    // 1. Read JPEG image from the file to a buffer...
+    RFile file;
+    User::LeaveIfError( file.Open( iFs, a128x128TNFileName, EFileWrite ) );
+    CleanupClosePushL( file );
+    TInt size = 0;
+    file.Size(size);
+    HBufC8* jpegImage = HBufC8::NewL( size );
+    CleanupStack::PushL( jpegImage );
+    TPtr8 bufferDes( jpegImage->Des() );
+    User::LeaveIfError( file.Read( bufferDes ) );
+    CleanupStack::Pop( jpegImage );
+    CleanupStack::PopAndDestroy();
+    CleanupStack::PushL( jpegImage );
+     
+    file.Close();
+     
+    // 2. Instantiate Exif modifier in ECreate mode...
+    CExifModify* modify = CExifModify::NewL( jpegImage->Des(), CExifModify::EModify );
+    CleanupStack::PushL( modify );
+     
+    //3. Insert (Set) at least the mandatory Exif data.
+    //TInt descSize = 300;
+    //HBufC8* heapComment = HBufC8::NewL(descSize);
+    TPtr8 ptr = makerNote->Des();
+     
+    modify->SetMakerNoteL(ptr);
+    //modify->SetMakerNoteL(makerNote->Des());
+     
+    // 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( jpegImage->Des() );
+    HBufC8* newExif;
+    TRAPD(err, newExif = modify->WriteDataL( jpegImage->Des() ));
+     
+    if(err != KErrNone)
+        {
+        TInt i=0;
+        }
+     
+    //TPtr8 tmp = newExif->Des();
+     
+    User::LeaveIfError( file.Replace( iFs, a128x128TNFileName, EFileWrite ) );
+    //Write Exif and jpeg image back to jpeg file
+    User::LeaveIfError(file.Write(*newExif));
+     
+    // Process the new Exif data
+    delete newExif;
+    newExif = NULL;
+     
+    // 5. Delete the modifier instance...
+    CleanupStack::PopAndDestroy( modify );
+    CleanupStack::PopAndDestroy( jpegImage );
+     
+    file.Close();
+    
+    DP0_IMAGIC(_L("CIEEngineUtils::RemoveFaceCoordinate--"));
+    return KErrNone;
+    }
+
+
+
+EXPORT_C void CIEEngineUtils::WriteFaceCoordinatesL(const TFileName a512x512TNFileName, RArray<TRect>& aCordArray)
+    {
+    DP1_IMAGIC(_L("CIEEngineUtils::WriteFaceCoordinatesL a512x512TNFileName = %S ++"), &a512x512TNFileName);
+    
+    TInt error = KErrNone;
+    RFile tnFile;
+    TInt size = 0;
+    
+    //Check that coords got from IDL makes sense. Eg. not out of image area etc.
+    /*TSize tnSize;
+    iImageDecoder->GetImageSizeL(iCurrentImageData->iMGTN_320x320_Filename, tnSize);
+    TInt brx;
+    
+    TInt count = aCordArray.Count();
+    TBool removed = EFalse;
+    for(TInt i=0; i<count; i++)
+        {
+        brx = aCordArray[i].iBr.iX;
+        brx = aCordArray[i].iBr.iY;
+        brx = aCordArray[i].iTl.iX;
+        brx = aCordArray[i].iTl.iY;
+        if(aCordArray[i].iTl.iX >= aCordArray[i].iBr.iX || aCordArray[i].iTl.iY >= aCordArray[i].iBr.iY)
+            {
+            aCordArray.Remove(i);
+            removed = ETrue;
+            }
+        if(removed)
+            count = aCordArray.Count();
+        }
+    */
+   
+    User::LeaveIfError(tnFile.Open(iFs, a512x512TNFileName, EFileRead));
+    
+    tnFile.Size(size);
+    
+    if(size <= 0) User::Leave(KErrUnderflow); // May be more meaningful error code shud be returned
+    
+    HBufC8* imageData = HBufC8::NewL(size);
+    
+    CleanupStack::PushL(imageData);
+    
+    TPtr8 imageDataPtr = imageData->Des();
+    
+    User::LeaveIfError(tnFile.Read(imageDataPtr));
+    
+    tnFile.Close();
+    
+    // Create the exifmodifier instance
+    CExifModify* exifModifier = CExifModify::NewL(imageDataPtr, CExifModify::ECreate);
+    
+    CleanupStack::PushL(exifModifier);
+    
+    //3. Insert (Set) at least the mandatory Exif data...
+    exifModifier->SetXResolutionL( 123, 1 ); 
+    exifModifier->SetYResolutionL( 512, 1 ); 
+    exifModifier->SetResolutionUnitL( 2 );
+    exifModifier->SetYCbCrPositioningL( 1 );
+    exifModifier->SetComponentsConfigurationL( 1, 2, 3, 0 );
+    exifModifier->SetColorSpaceL( 1 );
+    exifModifier->SetPixelXDimensionL( 512 );
+    exifModifier->SetPixelYDimensionL( 512 );
+    
+    TInt descSize = aCordArray.Count()*4*4 + 32+10; // Be careful calculating like this!!!
+    
+    HBufC8* heapComment = HBufC8::NewL(descSize);
+    
+    CleanupStack::PushL(heapComment);
+    
+    TPtr8 ptr = heapComment->Des();
+     
+    ptr.Append(KFaceCoordsHeader);
+    ptr.Append(KSpace);
+    ptr.Append(KFaceCoordsImagicVersion);
+    ptr.Append(KSpace);
+    ptr.Append(KHash);
+     
+    //Set number of faces detected to Exif data
+    if(aCordArray.Count() == 0)
+        ptr.Append(KZero);
+    else
+        {
+        ptr.AppendNum(aCordArray.Count());
+        ptr.Append(KSpace);
+        for(TInt i=0; i<aCordArray.Count(); i++)
+            {
+            //TInt size = ptr.Size();
+            ptr.AppendNum(aCordArray[i].iTl.iX);
+            ptr.Append(KSpace);
+            ptr.AppendNum(aCordArray[i].iTl.iY);
+            ptr.Append(KSpace);
+            ptr.AppendNum(aCordArray[i].iBr.iX);
+            ptr.Append(KSpace);
+            ptr.AppendNum(aCordArray[i].iBr.iY);
+            ptr.Append(KSpace);
+            }    
+        }
+    
+    exifModifier->SetMakerNoteL(ptr);
+    
+    HBufC8* newImageData = exifModifier->WriteDataL(imageDataPtr); // newImageData contains the image data with the modified exif data
+    CleanupStack::PushL(newImageData);
+    
+    if(newImageData == NULL)
+        User::Leave(KErrNotFound); // Better error code should be returned
+    
+    TPtr8 newImageDataPtr = newImageData->Des();
+    
+    // Create the new thumbnail image with modified exif data
+    User::LeaveIfError(tnFile.Replace(iFs, a512x512TNFileName, EFileWrite));
+    User::LeaveIfError(tnFile.Write(newImageDataPtr));
+    
+    tnFile.Flush();
+    tnFile.Close();
+    
+    CleanupStack::PopAndDestroy(4);
+    
+    DP0_IMAGIC(_L("CIEEngineUtils::WriteFaceCoordinatesL --"));
+    }
+
+EXPORT_C void CIEEngineUtils::ReadFaceCoordinatesL(const TFileName a512x512TNFileName, RArray<TRect>& aCordArray)
+    {
+    DP1_IMAGIC(_L("CIEEngineUtils::ReadFaceCoordinatesL, a512x512TNFileName = %S ++"), &a512x512TNFileName);
+    
+    TInt count = aCordArray.Count();
+    for(TInt i=0; i<count; i++)
+        aCordArray.Remove(0);
+    
+    HBufC8* imageData = ReadExifHeaderL(iFs, a512x512TNFileName);
+    CleanupStack::PushL(imageData);
+
+    CExifRead* exifReader;
+    exifReader = CExifRead::NewL(imageData->Des(), CExifRead::ENoJpeg);
+    CleanupStack::PushL(exifReader);
+    
+    HBufC8* makerNoteData = exifReader->GetMakerNoteL();
+    TPtr8 makerNoteDataPtr = makerNoteData->Des();
+
+    // No valid face information
+    if (makerNoteDataPtr.Find(KFaceCoordsHeader) != 0)
+        User::Leave(KErrNotFound);
+    
+    // 31 is the length of the string KFaceCoordsHeader+KSpace+KFaceCoordsImagicVersion+KSpace+KHash
+    makerNoteDataPtr.Delete(0, 31);
+
+    TRect rect(0,0,0,0);
+    TLex8 lex(makerNoteDataPtr.Ptr());
+    TInt faceCount = 0;
+    
+    lex.Val(faceCount);
+    
+    if(faceCount > 0)
+        {
+        for(TInt i=0; i<faceCount; i++)
+            {
+            lex.SkipSpaceAndMark(); 
+            lex.Val(rect.iTl.iX);
+            lex.SkipSpaceAndMark(); 
+            lex.Val(rect.iTl.iY);
+            
+            lex.SkipSpaceAndMark(); 
+            lex.Val(rect.iBr.iX);
+            lex.SkipSpaceAndMark(); 
+            lex.Val(rect.iBr.iY);
+            
+            aCordArray.Append(rect);
+            
+            DP4_IMAGIC(_L("Rect(%d, %d, %d, %d)"), rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);
+            
+            rect = TRect(0,0,0,0);
+            }
+        aCordArray.SortSigned();
+        }
+    
+    CleanupStack::PopAndDestroy(2);
+        
+    DP0_IMAGIC(_L("CIEEngineUtils::ReadFaceCoordinatesL --"));
+    }
+
+EXPORT_C void CIEEngineUtils::GetModifiedTimeL(const TDes &aFileName, TTime& aTime)
+    {
+    DP0_IMAGIC(_L("CIEEngineUtils::GetFileModifiedTimeL++"));
+   
+    // Read file modified date
+    RFile file;
+    TInt error = file.Open(iFs, aFileName , EFileRead);
+    DP1_IMAGIC(_L("CIEEngineUtils::GetFileModifiedTimeL - file open error = %d"), error);
+    User::LeaveIfError(error);
+    file.Modified(aTime);
+    file.Close();
+    DP0_IMAGIC(_L("CIEEngineUtils::GetFileModifiedTimeL--"));
+    }
+
+EXPORT_C void CIEEngineUtils::GetImageSizeL(const TDes &aFileName, TSize& aSize)
+    {
+    DP0_IMAGIC(_L("CIEEngineUtils::GetImageSizeL++"));
+    
+    CImageDecoder* imageDecoder = CImageDecoder::FileNewL(iFs, aFileName);
+    TFrameInfo frameInfo = imageDecoder->FrameInfo();
+    aSize = frameInfo.iFrameCoordsInPixels.Size();
+
+    delete imageDecoder;
+    imageDecoder = NULL;   
+    
+    DP2_IMAGIC(_L("CIEEngineUtils::GetImageSizeL-- [%d x %d]"), aSize.iWidth, aSize.iHeight);
+    }
+
+EXPORT_C HBufC8* CIEEngineUtils::ReadExifHeaderL(RFs& aFs, const TDesC &aFileName) 
+    {
+    DP0_IMAGIC(_L("CIEEngineUtils::ReadExifHeaderL++"));
+    RFile file;
+    User::LeaveIfError(file.Open(aFs, aFileName, EFileRead|EFileShareReadersOnly));
+    CleanupClosePushL(file);
+    
+    TInt size;
+    file.Size(size);
+    size = Min(size, 64 * 1024);    // TODO use exact exif size
+        
+    HBufC8* exif = HBufC8::NewL(size);
+    CleanupStack::PushL(exif);
+    TPtr8 bufferPtr(exif->Des()); 
+    User::LeaveIfError(file.Read(bufferPtr));
+
+    CleanupStack::Pop(exif); // exif
+    CleanupStack::PopAndDestroy(); // file
+    
+    DP0_IMAGIC(_L("CIEEngineUtils::ReadExifHeaderL--"));
+    return exif;
+    }
+
+EXPORT_C HBufC8* CIEEngineUtils::ReadExifThumbnailL(RFs& aFs, const TDesC& aFileName)
+    {
+    DP1_IMAGIC(_L("CIEEngineUtils::ReadExifThumbnailL++ %S"), &aFileName);
+    
+    HBufC8* exif = ReadExifHeaderL(aFs, aFileName);
+    CleanupStack::PushL(exif);
+    
+    // Instantiate Exif reader
+    CExifRead* exifRead = CExifRead::NewL(*exif, CExifRead::ENoJpeg);
+    CleanupStack::PushL(exifRead);
+    
+    // Get required data from the Exif image
+    HBufC8* exifThumb = exifRead->GetThumbnailL();
+    CleanupStack::PushL(exifThumb);
+
+    /*TUint32 w, w2, h, h2;
+    exifRead->GetThumbnailXResolution(w, w2);
+    exifRead->GetThumbnailYResolution(h, h2);*/
+    
+    CleanupStack::Pop(exifThumb);
+    CleanupStack::PopAndDestroy(exifRead);
+    CleanupStack::PopAndDestroy(exif);
+    DP0_IMAGIC(_L("CIEEngineUtils::ReadExifThumbnailL--"));
+    return exifThumb;
+    }
+
+//------------------------------------------------------------------------------
+// Read the JPEG EXIF creation timestamp and orientation
+//------------------------------------------------------------------------------
+EXPORT_C void CIEEngineUtils::GetExifDateTimeAndOrientationL(
+        const TDesC& aFilename, 
+        TTime& aExifDateTime,
+        TUint16& aOrientation)
+    {
+    HBufC8* exifDateTime = NULL;
+    
+//#define USE_EXIF_DECODER
+#ifdef USE_EXIF_DECODER
+    // First create the decoder and attach it to the JPEG file. The
+    // decoder implementation UID has to be specified or calling
+    // ExifMetadata() will crash.
+    CImageDecoder* imageDecoder = NULL;
+    imageDecoder = CImageDecoder::FileNewL(
+            iFs, 
+            aFilename, 
+            CImageDecoder::EOptionNone, 
+            KImageTypeJPGUid, 
+            KNullUid,
+            TUid::Uid(KJPGDecoderImplementationUidValue));
+
+    // The specific implementation UID makes the downcasting safe.
+    // Besides, there is no other way to use the decoder.
+    CJPEGExifDecoder* jpegDecoder = static_cast<CJPEGExifDecoder*>(imageDecoder);
+    CleanupStack::PushL(jpegDecoder);
+    // Read the EXIF timestamp, format "YYYY:MM:DD HH:MM:SS".
+    MExifMetadata* exifData = jpegDecoder->ExifMetadata();
+    if(!exifData)
+        User::Leave(KErrNotSupported);
+    
+    TExifReaderUtility reader(exifData);
+    exifDateTime = HBufC8::NewLC(KPMMExifDateTimeOriginalLength);
+    TInt error = reader.GetDateTimeOriginal(exifDateTime);
+    User::LeaveIfError(error);
+#else
+    HBufC8* exifData = ReadExifHeaderL(iFs, aFilename);
+    CleanupStack::PushL(exifData);
+    CExifRead* exifReader = CExifRead::NewL(*exifData, CExifRead::ENoJpeg);
+    CleanupStack::PushL(exifReader);
+    
+    exifDateTime = exifReader->GetDateTimeOriginalL();
+#endif    
+    // Convert the descriptor to a TDateTime as it cannot be converted
+    // directly to a TTime.
+    TLex8 lexer(*exifDateTime);
+    TInt timeValue;
+    TDateTime intermediateDateTime;
+    // Year
+    User::LeaveIfError(lexer.Val(timeValue));
+    intermediateDateTime.SetYear(timeValue);
+    lexer.Inc(); // Skip the colon.
+    // Month
+    User::LeaveIfError(lexer.Val(timeValue));
+    intermediateDateTime.SetMonth(TMonth(timeValue-1));
+    lexer.Inc();
+    // Day
+    User::LeaveIfError(lexer.Val(timeValue));
+    intermediateDateTime.SetDay(timeValue-1);
+    lexer.Inc();
+    // Hours
+    User::LeaveIfError(lexer.Val(timeValue));
+    intermediateDateTime.SetHour(timeValue);
+    lexer.Inc();
+    // Minutes
+    User::LeaveIfError(lexer.Val(timeValue));
+    intermediateDateTime.SetMinute(timeValue);
+    lexer.Inc();
+    // Seconds
+    User::LeaveIfError(lexer.Val(timeValue));
+    intermediateDateTime.SetSecond(timeValue);
+
+    // Finally, convert the TDateTime to a TTime.
+    aExifDateTime = intermediateDateTime;
+
+    // Read orientation
+    TUint16 exifOrientation;
+#ifdef USE_EXIF_DECODER    
+    if (reader.GetOrientation(exifOrientation) == KErrNone)
+#else
+    if (exifReader->GetOrientation(exifOrientation) == KErrNone)
+#endif        
+        {
+        switch (exifOrientation)
+            {
+            case 1: case 2:
+                aOrientation = 0;
+                break;
+
+            case 3: case 4:
+                aOrientation = 180;
+                break;
+                
+            case 5: case 8:
+                aOrientation = 90;
+                break;
+                
+            case 6: case 7:
+                aOrientation = 270;
+                break;
+                
+            default:
+                DP0_IMAGIC(_L("CIEEngineUtils::GetExifDateTimeAndOrientationL: invalid orientation"));
+            }
+        
+        DP1_IMAGIC(_L("CIEEngineUtils::GetExifDateTimeAndOrientationL: %d"), aOrientation);        
+        }
+    
+#ifdef USE_EXIF_DECODER
+    CleanupStack::PopAndDestroy(exifDateTime);    
+    CleanupStack::PopAndDestroy(jpegDecoder);
+#else
+    CleanupStack::PopAndDestroy(exifReader);
+    CleanupStack::PopAndDestroy(exifData);    
+#endif    
+    }
+
+EXPORT_C TUid CIEEngineUtils::GetImageDecoderUid()
+    {
+    CImplementationInformationType* type;
+    TInt error;
+
+    TUid uid = TUid::Uid(KJpegDecIVAUidValue);
+    TRAP(error, type = CImageDecoder::GetImplementationInformationL(uid));
+    if (error == KErrNone)
+        {
+        DP0_IMAGIC(_L("CIEEngineUtils::GetImageDecoderUid: IVA decoder found"));
+        return uid;
+        }
+
+    uid = TUid::Uid(KJpegOptUidValue);
+    TRAP(error, type = CImageDecoder::GetImplementationInformationL(uid));
+    if (error == KErrNone)
+        {
+        DP0_IMAGIC(_L("CIEEngineUtils::GetImageDecoderUid: Emuzed decoder found"));
+        return uid;
+        }
+   
+    /*CExtJpegDecoder* extDecoder;
+    TRAP(error, extDecoder = CImageDecoder::DataNewL(CExtJpegDecoder::EHwImplementation));
+    if (error == KErrNone)
+        return extDecoder->ImplementationUid();*/
+    
+    /*TRAP(error, type = CImageDecoder::GetImplementationInformationL(CExtJpegDecoder::ESwImplementation));
+    if (error == KErrNone)
+        return type->ImplementationUid();*/ 
+  
+    DP0_IMAGIC(_L("CIEEngineUtils::GetImageDecoderUid: no specified decoder found"));    
+    return KNullUid;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Src/IEImageData.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,203 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include <eikenv.h>
+#include "IEImageData.h"
+#include "ImagicConsts.h"
+
+EXPORT_C CImageData* CImageData::NewL(TUint32 aImagesReady)
+    {
+    CImageData* self = new (ELeave) CImageData();
+    CleanupStack::PushL(self);
+    self->ConstructL(aImagesReady);
+    CleanupStack::Pop();
+    return self;
+    }
+
+EXPORT_C CImageData::~CImageData()
+    {
+    delete iFileName;
+    delete iPath;
+    }
+
+CImageData::CImageData() : 
+    iFileTime(0),
+    iCreatedTime(0)
+    {
+    }
+
+void CImageData::ConstructL(TUint32 aImagesReady)
+    {
+    iFileName = NULL;
+    iPath = NULL;
+    iGridData.iCorrupted = 0;
+    iGridData.iRotationAngle = 0;
+    iGridData.iTargetRotationAngle = 0;
+    iGridData.iX = iGridData.iY = iGridData.iZ = 0;
+    iGridData.iScale = 0;
+    iGridData.iGlLQ32TextIndex = 0;
+    iGridData.iGlLQ128TextIndex = 0;
+    iGridData.iGlHQ512TextIndex = 0;
+    iGridData.iGlSuperHQTextIndex = 0;
+    iImagesReady = aImagesReady|EExifThumb;
+    iOrientation = 0;
+    iNumberOfFaces = -1;
+    iAspectRatio = 1;
+    iSize = TSize(0,0);
+    iPersonId = -1;
+    }
+
+EXPORT_C void CImageData::SetFileNameL(const TFileName & aFileName) 
+    {
+    TParse parser;
+    parser.Set(aFileName, NULL, NULL);
+    delete iFileName; iFileName = NULL;
+    delete iPath; iPath = NULL;
+    iFileName = parser.NameAndExt().AllocL();
+    iPath = parser.DriveAndPath().AllocL();
+    }
+
+EXPORT_C void CImageData::GetFileName(TFileName & aFullFileName, TThumbSize aSize) const 
+    {
+    if (iPath == NULL || iFileName == NULL)
+        User::Leave(KErrNotReady);
+        
+    aFullFileName = *iPath;
+
+    switch (aSize) 
+        { 
+        case EFullSize:
+            aFullFileName.Append(*iFileName);
+            break;
+
+        case ESize32x32:
+            aFullFileName.Append(K32x32TNFilePath);
+            aFullFileName.Append(*iFileName);
+            aFullFileName.Append(K32x32Ext);
+            break;            
+            
+        case ESize128x128:
+            aFullFileName.Append(K128x128TNFilePath);
+            aFullFileName.Append(*iFileName);
+            aFullFileName.Append(K128x128Ext);            
+            break;  
+            
+        case ESize512x512:
+            aFullFileName.Append(K512x512TNFilePath);
+            aFullFileName.Append(*iFileName);
+            aFullFileName.Append(K512x512Ext);            
+            break;  
+
+        default:
+            User::Leave(KErrArgument);
+        }
+    }
+
+EXPORT_C void CImageData::GetPath(TFileName & aPath) const 
+    {
+    aPath.Copy(iPath ? iPath->Des() : _L(""));
+    }
+
+EXPORT_C void CImageData::GetFileName(TFileName & aFileName) const
+    {
+    aFileName.Copy(iFileName ? iFileName->Des() : _L(""));
+    }
+
+EXPORT_C TBool CImageData::IsImageReady(TThumbSize aSize) const 
+    {
+    return ((iImagesReady & aSize) == aSize);
+    }
+
+EXPORT_C void CImageData::SetImageReady(TThumbSize aSize, TBool aReady)  
+    {
+    if (aReady) 
+        iImagesReady |= aSize;
+    else
+        iImagesReady &= ~aSize;
+    }
+
+EXPORT_C const TReal CImageData::GetAspectRatio() const 
+    { 
+    return iAspectRatio;
+    }
+
+TBool CImageData::IsCreatedTimeSet() const 
+    {
+    // Time is defined if not zero
+    return (iCreatedTime.Int64() != 0);
+    }
+
+EXPORT_C const TTime & CImageData::GetFileTime() const 
+    { 
+    return iFileTime; 
+    }
+
+EXPORT_C void CImageData::SetFileTime(const TTime & aTime) 
+    { 
+    iFileTime = aTime;
+    }
+
+EXPORT_C const TTime & CImageData::GetCreatedTime() const 
+    { 
+    // if no created time (usually from EXIF), use file time
+    return IsCreatedTimeSet() ? iCreatedTime : iFileTime; 
+    }
+
+EXPORT_C void CImageData::SetCreatedTime(const TTime & aTime) 
+    { 
+    iCreatedTime = aTime; 
+    }
+
+EXPORT_C TUint16 CImageData::GetOrientation() const 
+    {
+    return iOrientation;
+    }
+
+EXPORT_C void CImageData::SetOrientation(TUint16 aOrientation) 
+    {
+    iOrientation = aOrientation;
+    }
+
+EXPORT_C void CImageData::SetSize(const TSize aSize)
+    {
+    iSize = aSize;
+    iAspectRatio = iSize.iHeight ? (TReal(iSize.iWidth) / iSize.iHeight) : 0;
+    }
+
+EXPORT_C TSize CImageData::GetSize() const
+    {
+    return iSize;
+    }
+
+EXPORT_C TInt CImageData::GetNumberOfFaces() const 
+    {
+    return iNumberOfFaces;
+    }
+
+EXPORT_C void CImageData::SetNumberOfFaces(TInt aValue) 
+    {
+    iNumberOfFaces = aValue;
+    }
+
+EXPORT_C TBool CImageData::IsSamePath(CImageData& aImageData) const
+    {
+    TFileName path, path2;
+    GetPath(path);
+    aImageData.GetPath(path2);
+    return (path == path2);
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/Src/ImagicUtils.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,421 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include <aknquerydialog.h> 
+#include <avkon.hrh>
+#include <BAUTILS.H>
+#include <stringloader.h> 
+#include <aknnotewrappers.h>
+ 
+/*Imagic RSG file for rss file */
+#include <PhotoBrowser.rsg>
+#include "ImagicUtils.h"
+#include  "Imagic.hrh"
+
+CImagicUtils* CImagicUtils::NewL(RFs & aFs)
+{
+    
+	CImagicUtils* self=new (ELeave) CImagicUtils(aFs);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CImagicUtils::CImagicUtils(RFs& aFs)
+    : iFs(aFs)
+    {
+        
+    } 
+
+void CImagicUtils::ConstructL()
+    {
+    //no implementation required.
+    }
+
+CImagicUtils::~CImagicUtils()
+    {
+    }
+
+void CImagicUtils::DisplayYearAndMonth(TInt aIndex, TDateTime dateTime)
+    {
+    if(iPopUpNote)
+        {
+        delete iPopUpNote;
+        }
+  /*  if(iTextResource)
+        {
+        //CleanupStack::PopAndDestroy(iTextResource);
+        delete iTextResource;
+        }*/
+
+    iPopUpNote = CAknInfoPopupNoteController::NewL();
+    TMonth month = dateTime.Month();
+    TInt year = dateTime.Year();
+    //Convert int to buf
+    TBuf<10> valToNumBuf;
+    valToNumBuf.Num(year);
+    
+    _LIT(KMonth1, "January ");
+    _LIT(KMonth2, "February ");
+    _LIT(KMonth3, "March ");
+    _LIT(KMonth4, "April ");
+    _LIT(KMonth5, "May ");
+    _LIT(KMonth6, "June ");
+    _LIT(KMonth7, "July ");
+    _LIT(KMonth8, "August ");
+    _LIT(KMonth9, "September ");
+    _LIT(KMonth10, "October ");
+    _LIT(KMonth11, "November ");
+    _LIT(KMonth12, "December ");
+    
+    TBuf<512> text;
+    
+    if(month == EJanuary)  {text.Format(KMonth1);text.Append(valToNumBuf);}
+    if(month == EFebruary) {text.Format(KMonth2);text.Append(valToNumBuf);}
+    if(month == EMarch)    {text.Format(KMonth3);text.Append(valToNumBuf);}
+    if(month == EApril)    {text.Format(KMonth4);text.Append(valToNumBuf);}
+    if(month == EMay)      {text.Format(KMonth5);text.Append(valToNumBuf);}
+    if(month == EJune)     {text.Format(KMonth6);text.Append(valToNumBuf);}
+    if(month == EJuly)     {text.Format(KMonth7);text.Append(valToNumBuf);}
+    if(month == EAugust)   {text.Format(KMonth8);text.Append(valToNumBuf);}
+    if(month == ESeptember){text.Format(KMonth9);text.Append(valToNumBuf);}
+    if(month == EOctober)  {text.Format(KMonth10);text.Append(valToNumBuf);}
+    if(month == ENovember) {text.Format(KMonth11);text.Append(valToNumBuf);}
+    if(month == EDecember) {text.Format(KMonth12);text.Append(valToNumBuf);}
+                        
+    iPopUpNote->SetTextL(text);
+    iPopUpNote->SetTimeDelayBeforeShow(0);
+    iPopUpNote->SetTimePopupInView( 4000 );
+    iPopUpNote->SetPositionAndAlignment(TPoint(0,0), /*TGulAlignmentValue*/EHLeftVTop);
+    iPopUpNote->ShowInfoPopupNote();
+    }
+
+void CImagicUtils::ExecutePopUpNote(TInt aResourceId, TDes& aFilename, TInt aTime)
+    {
+    if(iPopUpNote)
+        {
+        delete iPopUpNote;
+        }
+    if(iTextResource)
+        {
+        //CleanupStack::PopAndDestroy(iTextResource);
+        delete iTextResource;
+        }
+    
+    iPopUpNote = CAknInfoPopupNoteController::NewL();
+    //iTextResource = StringLoader::LoadLC( aResourceId );
+    iTextResource = StringLoader::LoadL( aResourceId );
+    TBuf<512> text;
+    
+    //text.Format(*textResource);
+    TParse parser;
+    parser.Set(aFilename, NULL, NULL);
+    aFilename = parser.NameAndExt();
+    text.Format(*iTextResource, &aFilename);
+    
+    iPopUpNote->SetTextL(text);
+    iPopUpNote->SetTimeDelayBeforeShow(0);
+    iPopUpNote->SetTimePopupInView( aTime );
+    iPopUpNote->SetPositionAndAlignment(TPoint(0,0), /*TGulAlignmentValue*/EHLeftVTop);
+    iPopUpNote->ShowInfoPopupNote();
+    }  
+
+void CImagicUtils::ExecutePopUpNote(TInt aResourceId, TInt aTime)
+    {
+    if(iPopUpNote)
+        {
+        delete iPopUpNote;
+        }
+    if(iTextResource)
+        {
+        //CleanupStack::PopAndDestroy(iTextResource);
+        delete iTextResource;
+        }
+    
+    iPopUpNote = CAknInfoPopupNoteController::NewL();
+    //iTextResource = StringLoader::LoadLC( aResourceId );
+    iTextResource = StringLoader::LoadL( aResourceId );
+    TBuf<512> text;
+    
+    //text.Format(*textResource);
+/*    TParse parser;
+    parser.Set(aFilename, NULL, NULL);
+    aFilename = parser.NameAndExt();*/
+    text.Format(*iTextResource);
+    
+    iPopUpNote->SetTextL(text);
+    iPopUpNote->SetTimeDelayBeforeShow(0);
+    iPopUpNote->SetTimePopupInView( aTime );
+    iPopUpNote->SetPositionAndAlignment(TPoint(0,0), /*TGulAlignmentValue*/EHLeftVTop);
+    iPopUpNote->ShowInfoPopupNote();
+    }
+
+void CImagicUtils::ExecuteFileScanPopUpNote(TInt aResourceId, TInt aTime)
+    {
+    if(iFileScanPopUpNote)
+        {
+        delete iFileScanPopUpNote;
+        }
+    if(iTextResource)
+        {
+        //CleanupStack::PopAndDestroy(iTextResource);
+        delete iTextResource;
+        }
+    
+    iFileScanPopUpNote = CAknInfoPopupNoteController::NewL();
+    //iTextResource = StringLoader::LoadLC( aResourceId );
+    iTextResource = StringLoader::LoadL( aResourceId );
+    TBuf<512> text;
+    
+    //text.Format(*textResource);
+/*    TParse parser;
+    parser.Set(aFilename, NULL, NULL);
+    aFilename = parser.NameAndExt();*/
+    text.Format(*iTextResource);
+    
+    iFileScanPopUpNote->SetTextL(text);
+    iFileScanPopUpNote->SetTimeDelayBeforeShow(0);
+    iFileScanPopUpNote->SetTimePopupInView( aTime );
+    iFileScanPopUpNote->SetPositionAndAlignment(TPoint(0,0), /*TGulAlignmentValue*/EHLeftVTop);
+    iFileScanPopUpNote->ShowInfoPopupNote();
+    }
+
+
+void CImagicUtils::ExecutePopUpNote(TDes& aFilename, TInt aTime, TBool aAligment)
+    {
+    if(iPopUpNote)
+        {
+        delete iPopUpNote;
+        }
+    
+    iPopUpNote = CAknInfoPopupNoteController::NewL();
+    
+    /*TBuf<512> text;
+    
+    TParse parser;
+    parser.Set(aFilename, NULL, NULL);
+    aFilename = parser.NameAndExt();*/
+    
+    iPopUpNote->SetTextL(aFilename);
+    iPopUpNote->SetTimeDelayBeforeShow(0);
+    iPopUpNote->SetTimePopupInView(aTime);
+    iPopUpNote->SetPriority(EPriorityHigh);
+    
+    //if(aAligment)
+        iPopUpNote->SetPositionAndAlignment(TPoint(0,0), EHLeftVTop);
+    /*else
+        iPopUpNote->SetPositionAndAlignment(TPoint(0,0), EHRightVCenter);*/
+    
+    iPopUpNote->ShowInfoPopupNote();
+    }  
+
+/* Show text on Display */
+void CImagicUtils::ShowText(const TDesC16& aText, CWindowGc& gc, TRect aRect,const CFont*aFont,TRgb aTransparentBlack, TRgb aTransparentWhite) const
+    {
+    //RDebug::Print(_L("CImagicAppUi::ShowText"));
+        
+    gc.SetPenStyle(CGraphicsContext::ESolidPen);//ESolidPen, ENullPen
+    gc.UseFont(aFont);
+    gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+        
+    gc.SetBrushColor(aTransparentWhite);
+    gc.SetPenColor(aTransparentBlack);
+    
+    TRect rectText(TPoint(0, 0), TPoint(aRect.Width(),aFont->HeightInPixels()+3));
+    gc.DrawText(aText, rectText, rectText.Height() - aFont->DescentInPixels(), CGraphicsContext::ECenter );
+    
+    }
+
+/* Executing Error Dialog */
+void CImagicUtils::ExecuteQueryDialog(TInt /*aError*/,TInt aResourceId)
+    {
+    //if (aError != KErrNone)
+       {
+         CAknQueryDialog* dlg;
+         dlg = new ( ELeave ) CAknQueryDialog();
+         TInt result = dlg->ExecuteLD( aResourceId );
+         if(result == KErrNone || result != KErrNone)
+             User::Exit(-1);
+       }
+    }  
+    
+TInt CImagicUtils::ExecuteQueryDialog(TInt aResourceId)
+	{
+	 CAknQueryDialog* dlg;
+	 dlg = new ( ELeave ) CAknQueryDialog();
+	 TInt result = dlg->ExecuteLD( aResourceId );
+	 return result;
+	}
+	
+ void CImagicUtils::DisplayWaitDialog(TInt aResourceId, TBool aSingular)
+    {
+    //show wait dialog untill engine callback cancells it
+    if(iWaitDialog)
+        {
+        delete iWaitDialog;
+        }
+    iWaitDialog = NULL;
+    iWaitDialog = new(ELeave) CAknWaitDialog(NULL, ETrue);
+    
+    iWaitDialog->SetTextPluralityL(aSingular);
+    iWaitDialog->ExecuteLD( aResourceId );
+ 
+    }
+ 
+void CImagicUtils::ProcessFinishedL()
+    {
+	//iWaitDialog->ProcessFinishedL();
+	//iWaitDialog = NULL;
+	CancelWaitDialog();
+    }
+
+void CImagicUtils::CancelWaitDialog()
+    {
+    if(iWaitDialog != NULL)
+        {
+        iWaitDialog->ProcessFinishedL();
+        iWaitDialog = NULL;
+        }
+    }
+  
+void CImagicUtils::ShowWaitDialog( TInt  aResourceId )
+    {
+    TInt result = 0;
+    //show wait dialog untill engine callback cancells it
+    if(iWaitDialog)
+        {
+        delete iWaitDialog;
+        }
+    iWaitDialog = NULL;
+    iWaitDialog = new(ELeave) CAknWaitDialog(NULL, ETrue);
+    iWaitDialog->ExecuteLD( aResourceId );
+    
+    
+    }
+void CImagicUtils::DisplayTNInfoNoteStarted()
+   {
+   ExecuteInternalWaitNote(R_WAIT_NOTE, EFalse);
+   }
+
+void CImagicUtils::DisplayTNInfoNoteCompleted()
+   {
+   ExecuteInternalWaitNote(R_WAIT_NOTE_END, EFalse);
+   }
+
+void CImagicUtils::ShowInfoNote(TInt aResourceId)
+    {
+    HBufC* textResource = StringLoader::LoadLC( aResourceId );
+    CAknInformationNote* note = new ( ELeave ) CAknInformationNote(ETrue);
+    TBuf<512> text;
+    text.Format(*textResource);
+    note->ExecuteLD( text );
+    CleanupStack::PopAndDestroy(textResource);
+    }
+    
+void CImagicUtils::ShowInfoNote(TInt aResourceId, TDes& aFilename)
+    {
+    HBufC* textResource = StringLoader::LoadLC( aResourceId );
+    CAknInformationNote* note = new ( ELeave ) CAknInformationNote(ETrue);
+    TBuf<256+50> text;
+    
+    TParse parser;
+    parser.Set(aFilename, NULL, NULL);
+    aFilename = parser.NameAndExt();
+    
+    text.Format(*textResource, &aFilename);
+    note->ExecuteLD( text );
+    
+    CleanupStack::PopAndDestroy(textResource);
+    }
+
+//Modifies given file name to new with adding counting 
+//number to the end of the file name
+void CImagicUtils::GetNewFileName( TDes&  aFileName )
+    {
+    TBuf<300> valToNumBuf;
+    TInt tempCounter = 0;
+    TParse parser;
+    TFileName tmpName;
+    TBool result = EFalse;
+    
+    while(1)
+        {
+        tempCounter++;
+        
+        /*Converting from Number to Buffer */
+        valToNumBuf.Num(tempCounter);
+        
+        /*Parsing file name. */
+        parser.Set(aFileName, NULL, NULL );
+        tmpName = parser.DriveAndPath();
+        tmpName.Append(parser.Name());
+        
+        /*Appending */
+        tmpName.Append(_L("_"));
+        tmpName.Append(valToNumBuf);
+        tmpName.Append(_L(".jpg"));
+        
+        /*Checking the existing of file */
+        result = BaflUtils::FileExists(iFs, tmpName);
+        if(result)
+            {
+            /* File exists continue */
+            continue;
+            }
+        else
+            {
+            /*File does not found then copy the file and comeout of the loop */
+             aFileName.Copy(tmpName);
+             break;     
+            }
+        
+        }
+    }
+    
+ 
+void CImagicUtils::GetOriginalFileName( TDes&  aFileName )
+    {
+  
+    TParse parser;
+    parser.Set(aFileName, NULL, NULL );
+    TFileName tmpFileName = parser.Name();
+    //tmpName.Append(_L("_01.jpg"));
+    
+    
+    TFileName tmpPathName = parser.FullName();
+    //Delete characters from TN folder after _PAlbTN folder
+    TInt ret = tmpPathName.Find(_L("_PAlbTN\\"));
+    tmpPathName.Delete(ret, tmpPathName.Length()-ret);
+    
+    aFileName = tmpPathName;
+    aFileName.Append(tmpFileName);
+    aFileName.Append(_L(".jpg"));
+    }
+ 
+
+
+    
+ void CImagicUtils::ExecuteInternalWaitNote(TInt aResourceId,TBool aTextPlurality)
+ {
+   CAknNoteDialog* dlg = new ( ELeave ) CAknNoteDialog(CAknNoteDialog::ENoTone,CAknNoteDialog::ELongTimeout);
+   dlg->PrepareLC( aResourceId );
+   dlg->SetTextPluralityL(aTextPlurality);
+   
+   // Show the Dialog
+   dlg->RunLD();
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/FileSystemMonitorAO.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/ 
+
+#ifndef __FILESYSTEMMONITORAO_H__
+#define __FILESYSTEMMONITORAO_H__
+
+#include <e32base.h>
+#include <f32file.h>
+//#include "IEFileLoader.h"
+#include "ImagicConsts.h"
+#include "IEImageFinder.h"
+//#include "IEEngineImp.h"
+
+class CIEImageFinder;
+
+class CFileSystemMonitorAO : public CActive
+    {
+    public:
+        // Constructor and destructor
+        static CFileSystemMonitorAO* NewL(RFs& aFileServer, CIEImageFinder* aImageFinder);
+        static CFileSystemMonitorAO* NewLC(RFs& aFileServer, CIEImageFinder* aImageFinder);
+        void ConstructL();
+        CFileSystemMonitorAO(RFs& aFileServer, CIEImageFinder* aImageFinder);
+        ~CFileSystemMonitorAO();
+        void StartMonitoring();
+        void StopMonitoring();
+       
+    private:
+        // From CActive
+        void RunL();
+        void DoCancel();
+        void RunError();
+        
+    private: // Data
+        
+        CIEImageFinder*        iImageFinder;
+        RFs&                   iFileServer;
+
+        
+    };
+
+#endif //__FILESYSTEMMONITORAO_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEBgpsController.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,154 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBGPSCONTROLLER_H__
+#define __IEBGPSCONTROLLER_H__
+
+// Include files
+#include <e32base.h>
+#include <IEImageProcessing.h>
+#include <IEImage.h>
+
+#include "IEFileloader.h"
+#include "IEEngineUtils.h"
+
+
+// Forward Class Declaration
+class CIEFileLoader;
+class CIEEngineUtils;
+
+// Class Declartion
+class MIEBgpsControllerObserver
+    {
+public:
+    //virtual void Something() = 0;
+    virtual void TNGenerationComplete(TThumbSize aTNRes) = 0;
+    virtual void SingleTNGenerationComplete(TInt aIndex, TThumbSize aTNRes) = 0;
+    virtual void FaceDetectionComplete() = 0;
+    virtual void SingleFaceDetectionComplete() = 0;
+    virtual TInt GetSelectedImageIndex() = 0;
+    virtual CImageData* GetImageData(TInt aIndex) = 0;
+    };
+
+class CIEBgpsController : public CBase, public MIETNObserver
+{
+public: // First phase constructor and destructor
+    static CIEBgpsController* NewL(
+            RFs& aFileServer,
+            MIEBgpsControllerObserver& aIEBgpsControllerObserver, 
+            CIEEngineUtils& aEngineUtils,
+            RCriticalSection* aCritical);
+    ~CIEBgpsController();
+    
+private: // Second phase constructor and C++ default constructor
+    void ConstructL();
+    CIEBgpsController(
+            RFs& aFileServer,
+            MIEBgpsControllerObserver& aIEBgpsControllerObserver, 
+            CIEEngineUtils& aEngineUtils,
+            RCriticalSection* aCritical);
+    
+public: // From MIETNObserver 
+    void ThumbnailGenerationCompleted(TInt aErrorCode);
+    void ThumbnailGenerationCancelled(TInt aErrorCode);
+    void HandleError(TInt aError);
+    
+public: // New functions
+    // TN generation related
+    void SetFileLoader(CIEFileLoader* aFileLoader);
+    void CreateImageProcessing();
+    //void StartTNGeneration(RArray<CImageData*>& aImageArray);
+    //void StopTNGeneration(TInt &aValue);
+    void GenerateThumbNailL(const TDes &aOrgFile, TThumbSize /*aTNResolution*/);
+    void AllFilesAddedToFilenameArrayL();
+    TReal GetAspectRatio(TInt aIndex);
+    TReal GetFacesAspectRatio(TInt aIndex);
+    void GenerateTNForEditedImage(const TFileName aEditedFileName, const TReal aAspectRatio);
+    void FilenameArrayCountChanged(const RArray<CImageData*>& aImageDataArray);
+    CImageData* GetImageData(const TInt aIndex);
+    
+    // Face Detection related
+    void GetFaceCoordinates(const TFileName a128x128TNFileName, RArray<TRect>& aFaceCoordinateArray);  
+    void StartFaceCropping(TInt aIndex, RArray<TFileName>& aFilenames);
+    void RemoveFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+    void AddFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+    void GetSingleFaceCoordinates(TInt aIndex, const TFileName aTNFileName, RArray<TRect>& aFaceCoordinateArray);
+    void CancelTNGeneration();
+    
+private: // Private functions
+    void CreateSingleTNL();    
+    void DeleteCorruptedThumbNailFile(TFileName aFileName);
+    void CheckOptimalFileFor128x128TnCreation(TInt aIndex, TFileName& aFilename);
+    void CheckOptimalFileFor32x32TnCreation(TInt aIndex, TFileName& aFilename);
+    
+    void Generate128x128Thumbnails(TInt aIndex);
+    void Generate32x32Thumbnails(TInt aIndex);
+    void Generate512x512Thumbnails(TInt aIndex);
+    
+    //TReal ReadAspectRatioL(TFileName& aFileName);
+    //void CheckFileNamesExits(TInt aIndex, TDes& aFilename);
+    void StartTNCreatorL();
+    TInt FindMissingTN(TThumbSize& aRes);
+    
+private: // Data members
+    RFs& iFileServer;
+    MIEBgpsControllerObserver& iIEBgpsControllerObserver;
+    CIEImageProcessing* iIEBgpsClient;
+    CIEFileLoader*         iFileLoader;
+    CIEEngineUtils&        iIEEngineUtils;
+    
+    RArray<CImageData*> iImageDataArray;
+    RArray<CImageData*> iFaceCropImageDataArray;
+    
+    TBool i128x128TNCreationOn;
+    TBool i32x32TNCreationOn;
+    TBool i512x512TNCreationOn;
+    
+    
+    TBool iSingleTNGeneration;
+    
+    TBool iSingleFaceDetectionOn;
+    TBool iBackGroundFaceDetectionOn;
+    TBool iBackGroundFaceDetectionComplete;
+    
+    TSize iTNSize;
+    
+    TInt iImageIndex;
+    TInt iStopTN;
+    
+    TReal iAspectRatio;
+    
+    TFileName iTNFilename;
+    TFileName iJpegFilename;
+    TFileName iSavedFileName;    
+        
+    TThumbSize iLatestCreatedTNSize;
+    CImageData* iTmpImageData;
+    CImageData* iImageData;
+    
+    TInt iSingleFBIndex;
+    RArray<TRect>* iSingleFBCoordinateArray;
+    RArray<TRect> iFBCoordinateArray;
+    
+    TInt iTnCreationIndex; 
+    TBool iAllTNsDone;
+    TBool iTnCreationCancelled;
+    RCriticalSection*  iCritical;
+    CFbsBitmap* i512x512TnBitmap;
+};
+
+#endif // __IEBGPSCONTROLLER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEBitmapLoader.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBITMAPLOADER_H__
+#define __IEBITMAPLOADER_H__
+
+// Include files
+#include <f32file.h>
+#include <FBS.H>
+#include <ImageConversion.h>
+
+#include <IEEngine.h>
+#include "IEFileLoader.h"
+//#include "IEEngineImp.h"
+#include <iclexifimageframe.h>
+//#include <oommonitorsession.h>
+
+#define DECODE_FROM_BUFFER
+
+// Forward class declaration
+class CIEFileLoader;
+class CIEEngineUtils;
+
+class MBitmapLoaderObserver
+{
+public:
+	virtual void BitmapsLoadedL(TInt aError) = 0;
+	virtual CIEFileLoader* GetFileLoader() = 0;
+	virtual TInt GetGleMaxRes() = 0;
+};
+
+// Class declaration
+class CIEBitmapLoader : public CActive
+{
+public:
+	static CIEBitmapLoader* NewL(RFs& aFileServer, MBitmapLoaderObserver& aBitmapLoaderObserver, RCriticalSection* aCritical);
+	~CIEBitmapLoader();
+private:
+	void ConstructL();
+	CIEBitmapLoader(RFs& aFileServer, MBitmapLoaderObserver& aBitmapLoaderObserver, RCriticalSection* aCritical);
+	
+public: // From CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+	
+public:
+	void CIEBitmapLoader::LoadBitmapsL(TInt aIndex, TThumbSize aThumbRes);
+	void GetOneBitmapL(CImageData* aImageData, CFbsBitmap* aBitmap, TThumbSize aThumbRes);
+	void CancelFullSizeLoading();
+	void SetImageDataMode(TImageArrayMode aMode);
+		
+private:
+	void TargetDecodingSize(TSize aTgtSize, TSize& aSrcSize);
+	//TPtr8 LoadImageIntoMemoryLC(const TDesC& aFileName);
+	void CropImageL(CFbsBitmap* aOutput, CFbsBitmap* aInput) const;
+
+	
+private: //Data
+	RFs&                   iFileServer;
+	MBitmapLoaderObserver& iBitmapLoaderObserver;
+	CImageDecoder*         iImageDecoder;
+	CJPEGExifDecoder*      iExifDecoder;
+	RCriticalSection*      iCritical;
+	TImageArrayMode        iImageArrayMode;
+	CImageData*            iImageData;
+	TBool                  iUseExifTn;
+	HBufC8*                iExifTn;
+    CFbsBitmap*            iExifBitmap;
+    CFbsBitmap*            iOutputBitmap;
+    TUid                   decoderUid;
+    TThumbSize             iThumbRes;
+#ifdef DECODE_FROM_BUFFER
+    HBufC8*                iSourceData;
+#endif
+};
+
+
+#endif // __IEBITMAPLOADER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEEditor.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,203 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEEDITOR_H__
+#define __IEEDITOR_H__
+
+// Include files
+#include <e32base.h>
+#include <f32file.h>
+#include <FBS.H>
+#include <ImageConversion.h>
+#include <IclExtJpegApi.h>
+#include <IEImage.h>
+
+#include <IDLImageProcessing.h>
+
+#include "IEImageDecoder.h"
+#include "IEImageEncoder.h"
+#include "ImagicConsts.h"
+
+#define _FACEBROWSING
+
+// Forward class declaration
+class CIEImageDecoder;
+class CIEImageEncoder;
+
+class TEditedImage
+{
+public:
+	TIEFeature iEditedFeature;
+	TInt iEditedValue;
+	TIEColorParams iColorValue;
+	HBufC8* iEditedYuvData;
+};
+
+class MIEObserver
+{
+public:
+	virtual void WizardImagesLoadedL(TInt aError) = 0;
+	virtual void FeatureCompleteL(TIEFeature aFeature, TInt aError) = 0;
+	virtual void FeatureErrorL(TIEFeature aFeature, TInt aError) = 0;
+	virtual void ImageSavedL(TInt aError, TReal aAspectRatio) = 0;
+};
+
+// Class declaration
+class CIEEditor : public CBase, 
+					public MDecodingObserver, 
+					public MEncodingObserver, 
+					public MIDLObserver
+{
+public:
+	static CIEEditor* NewL(RFs& aFileServer, MIEObserver& aObserver);
+	~CIEEditor();
+
+private:
+	void ConstructL();
+	CIEEditor(RFs& aFileServer, MIEObserver& aObsaerver);
+
+public: // From MDecodingObserver
+	void YuvImageReadyL(TInt aError);
+	void BitmapReadyL(TInt aError);
+
+public: // From MEncodingObserver
+	void JpegImageReadyL(TInt aError);
+	
+	TSize GetRotateImageSize();
+	TInt GetRotationAngle();
+
+public: // From MIDLObserver
+	inline void ProcessingComplete(TDesC8& /*aData*/){};
+	inline void HandleError(TInt /*aError*/){};	
+
+public:
+	void EditImageL(TIEImage* aImage, const TIEFeature aFeature, const TInt aValue);
+	void EditImageWizardL(const TIEFeature aFeature, RArray<CFbsBitmap*>& aBitmapArray, const TInt aIndex = 0);
+	void EditBrightnessL(CFbsBitmap& aBitmap, const TInt aValue);
+	void EditContrastL(CFbsBitmap& aBitmap, const TInt aValue);
+	void EditColorL(CFbsBitmap& aBitmap,
+				const TInt aRedValue,
+				const TInt aGreenValue,
+				const TInt aBlueValue);
+	void EditGammaL(CFbsBitmap& aBitmap, const TInt aValue);
+	void EditEdgeEnhancementL(CFbsBitmap& aBitmap, const TInt aValue);
+	void RotateImageL(CFbsBitmap& aBitmap, const TRotationAngle aRotationAngle);
+	void CropImageL(CFbsBitmap& aBitmap, const TRect aRect);
+	void EditLocalColorCorrectionL(CFbsBitmap& aBitmap, const TInt aValue);
+	void SetImageAndModeL(const TDesC& aImageName, const TIEEditingMode aEditingMode);
+	void CompleteWizardEditL(const TInt aIndex);
+	void SaveEditedImageL(const TDesC& aSrcFileName, const TDesC& aTargetFileName);
+	void CleanYuvDataArray();
+	void DeleteInputYUVBuffer();
+	void CleanBitmapArray();
+
+ 	
+    	void DetectFaceL(const TDesC &aFileName);
+    	void DetectFaceL();
+    	void FaceDetectSetupL(const TIEFeature aFeature, const TIDLFeatures aIDLFeature);
+    	void NoOfFacesDetected(TInt &aNoOfFaces);
+    	
+    	void NoOfFacesDetected(TInt &aNoOfFaces, RArray<TRect> &aFaceCoordinates);
+    	
+ 
+private:
+	void PrepareOutputBuffersL(TInt aBuffers, TInt aSize);
+	void CreateBitmapsL(TInt aBitmaps, TSize aSize);
+	
+	void SetupL(CFbsBitmap& aBitmap, 
+			const TIEFeature aFeature, 
+			const TIDLFeatures aIDLFeature,
+			const TAny* aValue);
+
+	//void InitializeFeatureL();
+	void InitializeFeatureL(const TSize aInSize, const TSize aOutsize);
+	void ProcessImageL(TDesC8& aInputData, TDesC8& aOutputData);
+	
+	void EditFeatureL(TIEFeature aFeature);
+	void EditBrightnessL();
+	void EditContrastL();
+	void EditColorL();
+	void EditSharpnessL();
+	void EditGammaL();
+	void RotateImageL();	
+	void CropImageL();
+	void EditLocalColorCorrectionL();
+	
+	void SaveImageL();
+	
+	void SaveDataToFileL(const TDesC& aFileName, TDesC8& aData);
+	void GenerateFileName(TDes& aFileName, TDesC& aFeature, TInt aSuffix, TBool aIsYuv);
+	
+	void SetImageParams(const TIEFeature aFeature, const TAny* aFeatureValue);
+
+private: // Data
+	RFs& iFileServer;
+	MIEObserver& iObserver;
+
+	CIEImageDecoder* iImageDecoder;
+	CIEImageEncoder* iImageEncoder;
+
+	RArray<TEditedImage> iYuvDataArray;
+	RArray<CFbsBitmap*>* iBitmapArrayPtr;
+	RArray<CFbsBitmap*> iBitmapArray;
+		
+	HBufC8* iInBufferYuv;
+	HBufC8* iOutBufferYuv;
+	HBufC8* iJpegBuffer;
+	
+	CFbsBitmap* iBitmap;
+	
+	CIDLImageProcessing* iIDLImageProcessor;
+	
+	TSize iSize;
+	TSize iFinalImageSize;
+	TSize iRotatedSize;
+	TSize iCroppedSize;
+		
+	TInt iBitmapArrayIndex;
+	TInt iYuvDataArrayIndex;
+	TInt iOrgImagePos;
+		
+	TUint8* iBufU;
+	
+	TIEImage iCurrentImage;
+	TIEFeature iCurrentFeature;
+	TIDLFeatures iCurrentIDLFeature;
+	TInt iFeatureValue;
+	TIEEditingMode iEditingMode;
+	
+	TRotationAngle iRotationAngle;
+	TInt iAngle;
+	TInt iNumberOfRotation;
+	
+	TRect iCropRect;
+	
+	TBool iImageEdited;
+	TBool iEditComplete;
+	
+	TInt iBufferSize;
+	float  iAspectRatio;
+	
+	TFileName iFileName;
+		
+#ifdef __SAVE_INTERMEDIATE_FILES__
+	TInt       iCount;
+#endif
+	
+};
+
+#endif //__IEEDITOR_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEEngine.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,105 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEENGINE_H__
+#define __IEENGINE_H__
+
+#define _FACEBROWSING
+
+// Include files
+#include <e32base.h>
+#include <fbs.h>
+
+#include "ImagicConsts.h"
+#include "debug.h"
+#include "IEImage.h"
+#include "IEImageProcessing.h" //thumbnail client
+#include "IESensorMonitor.h"
+#include "IEImageList.h"
+
+#ifdef _S60_5x_ACCELEROMETER_
+#include <sensrvorientationsensor.h>
+#endif
+
+//Structures
+
+// Class declaration, AppUI class implements
+class MIEEngineObserver
+{
+public:
+    virtual void ImagesLoadedL(TInt aError) = 0;
+	virtual void TNCreationCompleteL(TThumbSize aTnRes) = 0;
+	virtual void SingleTNCreationCompletedL(TInt index, TThumbSize aTnRes) = 0;
+	virtual void FaceDetectionComplete() = 0;
+	virtual void SingleFaceDetectionComplete() = 0;
+	virtual TInt GetImageIndex() = 0;
+	virtual void AllFilesScanned() = 0;
+	virtual void ImageListChanged(TInt aIndex, TBool bAdded) = 0;
+#ifdef _ACCELEROMETER_SUPPORTED_
+	virtual void ImageRotated(TImagicDeviceOrientation aDeviceOrientation) = 0;
+#endif
+	virtual TInt GetGleMaxRes() = 0;
+	
+};
+
+class CIEEngine : public CBase
+{
+public:
+    
+	IMPORT_C static CIEEngine* NewL(MIEEngineObserver& aObserver);
+	IMPORT_C virtual ~CIEEngine();
+	IMPORT_C virtual TInt GetTotalNumOfImages() = 0;
+	IMPORT_C virtual void GetTotalNumOfImages(TInt& aNumOfImages, TInt& aNumOfFaces) = 0;
+	IMPORT_C virtual TInt DeleteFile(TInt aIndex) = 0;
+	IMPORT_C virtual TInt GetImageName(const TInt aIndex, TFileName& aFileName, TThumbSize aThumbRes) = 0;
+	IMPORT_C virtual void GetBitmapL(CImageData* aImageData, CFbsBitmap* aBitmap, TThumbSize aThumbRes) = 0;
+	IMPORT_C virtual void AppUIReady() = 0;
+	IMPORT_C virtual void CancelFullSizeLoading() = 0;
+#ifdef _ACCELEROMETER_SUPPORTED_
+	IMPORT_C virtual TImagicDeviceOrientation GetDeviceOrientation() = 0;
+	IMPORT_C virtual void SetDeviceOrientation(TImagicDeviceOrientation aOrientation) = 0;
+	IMPORT_C virtual void StartAccSensorMonitoring() = 0;
+    IMPORT_C virtual void StopAccSensorMonitoring() = 0;
+#endif
+	IMPORT_C virtual TBool IsAccelerometerExists() = 0;
+	IMPORT_C virtual void SensorDataAvailable(TImagicDeviceOrientation aOrientation, TBool aValue) = 0;
+	IMPORT_C virtual void SetImageRotation(TInt aIndex) = 0;
+	IMPORT_C virtual void SetDBChanged(CImageData* aImageData) = 0;
+	
+	//New functions for handling UI access to Filename array
+	IMPORT_C virtual CImageData* GetImageData(TInt aIndex/*, TImageArrayMode aMode*/) = 0;
+	IMPORT_C virtual void SetImageData(TInt aIndex, CImageData* aGridData) = 0;
+	IMPORT_C virtual TBool IsScanningFiles() const = 0;
+	IMPORT_C virtual CIEImageList& GetImageList() = 0;	
+
+	// TN related functions
+	IMPORT_C virtual void GetFileNameL(const TInt aIndex, TThumbSize aThumbRes, TFileName& aFilename) = 0;
+	IMPORT_C virtual void StopTNGeneration(TInt &aValue) = 0;
+	IMPORT_C virtual TReal GetAspectRatio(TInt aIndex) = 0;
+	IMPORT_C virtual TReal GetFacesAspectRatio(TInt aIndex) = 0;
+	IMPORT_C virtual void GenerateThumbNailL(const TDes &aOrgFile, TThumbSize aTNResolution) = 0;
+	
+	// Newly added face Detection functions
+	IMPORT_C virtual void GetFaceCoordinates(const TFileName a128x128TNFileName, RArray<TRect>& aFaceCoordinateArray) = 0;
+    IMPORT_C virtual void GetSingleFaceCoordinates(TInt aIndex, const TFileName aTNFileName, RArray<TRect>& aFaceCoordinateArray) = 0;
+    IMPORT_C virtual void SetImageDataMode(TImageArrayMode aMode) = 0;
+    
+    IMPORT_C virtual void Stop() = 0;
+    IMPORT_C virtual TBool IsRunning() = 0;
+};
+
+#endif // __IEENGINE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEEngineImp.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,172 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEENGINEIMP_H__
+#define __IEENGINEIMP_H__
+
+#define _FACEBROWSING
+
+// Include files
+#include <e32cons.h>
+#include <e32base.h>
+#include <F32file.h>
+#include <FBS.h>
+
+#include <IEEngine.h>
+#include <IEImageProcessing.h>//thumbnail client
+#include <exifmodify.h> 
+
+#ifdef IMAGE_EDITOR
+#include "IEEditor.h"
+#endif
+#include "IEBitmapLoader.h"
+#include "IEFileloader.h"
+#include "IEBgpsController.h"
+#include "ImagicConsts.h"
+
+#include "IEEngineUtils.h"
+//#ifdef _S60_5x_ACCELEROMETER_
+#include "IESensorMonitor.h"
+//#endif
+
+// Forward class declarations
+#ifdef IMAGE_EDITOR
+class CIEEditor;
+#endif
+class CIEFileLoader;
+class CIEBitmapLoader;
+class CIETNController;
+class CIEImageProcessing;
+class CImageData;
+class CIEEngineUtils;
+class MBitmapLoaderObserver;
+//#ifdef _S60_5x_ACCELEROMETER_
+//class TSensrvOrientationData;
+//#endif
+
+// Class declaration
+class CIEEngineImp : public CIEEngine, public MBitmapLoaderObserver , public MIEBgpsControllerObserver 
+#ifdef _ACCELEROMETER_SUPPORTED_
+,public MIESensorMonitorObserver
+#endif
+#ifdef IMAGE_EDITOR
+, public MIEObserver
+#endif
+{
+public: // First phase constructor and destructor
+	static CIEEngineImp* NewL(MIEEngineObserver& aObserver);
+	~CIEEngineImp();
+
+private: // Second phase constructot and C++ default constructor
+	void ConstructL();
+	   CIEEngineImp(MIEEngineObserver& aObserver);
+	
+public: // From CIEEngine
+	// General Functions
+    void SetDBChanged(CImageData* aImageData);
+    TInt GetTotalNumOfImages();
+    void GetTotalNumOfImages(TInt& aNumOfImages, TInt& aNumOfFaces);
+	TInt DeleteFile(TInt aIndex);
+	TInt GetImageName(const TInt aIndex, TFileName& aFileName, TThumbSize aThumbRes);
+	void GetBitmapL(CImageData* aImageData, CFbsBitmap* aBitmap, TThumbSize aThumbRes);
+	void SetImageDataMode(TImageArrayMode aMode);
+	void AppUIReady();
+	void CancelFullSizeLoading();
+	//New functions for handling UI access to Filename array
+    CImageData* GetImageData(TInt aIndex);
+    void SetImageData(TInt aIndex, CImageData* aGridData);
+	TBool IsScanningFiles() const;
+	CIEImageList& GetImageList();
+	
+	// TN related functions
+	void GetFileNameL(const TInt aIndex, TThumbSize aThumbRes, TFileName& aFilename);
+	void StopTNGeneration(TInt &aValue);
+	TReal GetAspectRatio(TInt aIndex);
+	TReal GetFacesAspectRatio(TInt aIndex);
+	void GenerateThumbNailL(const TDes &aOrgFile, TThumbSize aTNResolution);
+	
+	// Face Detection related functions
+	void GetFaceCoordinates(const TFileName a128x128TNFileName, RArray<TRect>& aFaceCoordinateArray);  
+    void RemoveFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+    void GetSingleFaceCoordinates(TInt aIndex, const TFileName aTNFileName, RArray<TRect>& aFaceCoordinateArray);
+    
+public: //From MBitmapLoaderObserver
+    CIEFileLoader* GetFileLoader();
+    void BitmapsLoadedL(TInt aError);
+    
+public: // From
+    inline void Something(){};
+    void TNGenerationComplete(TThumbSize aTNRes);
+    void SingleTNGenerationComplete(TInt aIndex, TThumbSize aTNRes);
+    void FaceDetectionComplete();
+    void SingleFaceDetectionComplete();
+    void SetGridRotationAngle(TReal aAngle);
+    TBool IsAccelerometerExists();
+
+#ifdef _ACCELEROMETER_SUPPORTED_
+    void SensorDataAvailable(TImagicDeviceOrientation aOrientation, TBool aValue);
+    void SetImageRotation(TInt aIndex);
+    TImagicDeviceOrientation GetDeviceOrientation();
+    void SetDeviceOrientation(TImagicDeviceOrientation aOrientation);
+    void StartAccSensorMonitoring();
+    void StopAccSensorMonitoring();
+#endif
+
+public: // New public functions
+	CIEEngineUtils *GetEngineUtils();
+	void AllFilesAddedToFilenameArrayL();
+	MIEEngineObserver& GetObserver();
+	
+	TInt GetSelectedImageIndex();
+	void Stop();
+	TBool IsRunning();
+	TInt GetGleMaxRes();
+	
+private:
+    void AddImageToFaceNameArray();
+  
+private:
+	MIEEngineObserver&     iEngineObserver;
+	RFs                    iFileServer;
+#ifdef IMAGE_EDITOR
+	CIEEditor*             iImageEditor;
+#endif
+	CIEFileLoader*         iFileLoader;
+	CIEBitmapLoader*       iBitmapLoader;
+    CIEEngineUtils         iIEEngineUtils;
+    CIEBgpsController*     iIEBgpsController;
+    TBool                  iAllFilesScanned;
+#ifdef _ACCELEROMETER_SUPPORTED_
+    CIESensorMonitor*       iSensorMonitor;
+    TImagicDeviceOrientation      iPrevDeviceOrientation;
+    TImagicDeviceOrientation      iDeviceOrientation;
+#endif
+	
+	TIEEditingMode         iEditingMode;
+	TIEEditingMode         iCurrentEditingMode;
+		
+	TBool                  iImageEdited;
+	CIEImageProcessing*    iIEBgpsClient;
+	RCriticalSection       iCritical;
+	
+	TFileName              iSavedFileName;
+	
+	TImageArrayMode        iImageArrayMode;
+	RArray<TFileName>      iCroppedFilenames;
+};
+
+#endif // __IEENGINEIMP_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEFileLoader.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,126 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEFILELOADER_H__
+#define __IEFILELOADER_H__
+
+// Include files
+#include <e32base.h>
+#include <f32file.h>
+#include <IEEngine.h>
+#include "IEBitmapLoader.h"
+#include "IEThreadEngine.h"
+#include "IEImageList.h"
+//#include "FileSystemMonitorAO.h"
+//#include "IEEngineImp.h"
+
+// Forward class declarations
+class CIEBitmapLoader;
+class IEImageFinderAO;
+class CIEEngineImp;
+class IEImageFinderAO;
+class CFileFinderThreadAO;
+class CImageMonitorAO;
+
+// Class declaration
+class CIEFileLoader : public CBase
+{
+public:
+	static 	CIEFileLoader* NewL(RFs& aFileServer, CIEEngineImp* aEngImp, RCriticalSection* aCritical);
+	~CIEFileLoader();
+	
+	enum TImageFinderState {
+        EImageFinderRunning,
+        EImageFinderStopping,
+        EImageFinderStopped
+	};
+
+private:
+	void ConstructL();
+	CIEFileLoader(RFs& aFileServer, CIEEngineImp* aEngImp, RCriticalSection* aCritical);
+	              
+private:
+	void LoadImageNamesL();
+	void Load320x320ThumbImageNamesL();
+	void FindThumbnailFolderL(TBuf<KMaxFileName> folderName, RFs& session);
+	void FillImageDataArrayL(TBuf<KMaxFileName> folder, RFs& session, TBool IsThumbnail);
+	TInt ScanDirFileCountL(const TDesC& aDir, const TDesC& aWild);
+	void SearchFileCountL(const TDesC& aRootPath, const TDesC& aSearchName, TInt& imageFileCount, TInt& facesFileCount);
+	
+public:
+	void GetFileNameL(const TInt aFileIndex, TFileName& aFileName, TThumbSize aThumbRes);
+	void SaveFileL(const TDesC& aFileName, const TDesC8& aData);
+	TInt GetImageCount(TThumbSize aThumbRes);
+	TInt GetTotalNumOfImages();
+	void GetTotalNumOfImages(TInt& aNumOfImages, TInt& aNumOfFaces);
+	RArray<CImageData*>& GetFileNameArray();
+	RArray<CImageData*>& GetFacesFileNameArray();
+	/*void SetAll640x480TNsDone(TBool aValue);
+	TBool GetAll640x480TNsDone();
+	void SetAll128x128TNsDone(TBool aValue);
+    TBool GetAll128x128TNsDone();*/
+	void AllFilesAddedToFilenameArray();
+	TInt DeleteFile(TInt aIndex);
+	TInt DeleteFaceFile(TInt aIndex);
+	void AddNewImage(CImageData* aTmpImageData, TInt iImageIndex);
+	void AddNewFaceCropImage(CImageData* aTmpImageData, TInt aImageIndex);
+	void ModifyImageData(CImageData* aTmpImageData, TInt aImageIndex);
+	void ImageListChanged(TInt aIndex, TBool aAdded);
+	CIEEngineImp* GetEngineImpPtr();
+	/*void StartFileSystemMonitoring();
+	void StopFileSystemMonitoring();
+	void FileSystemChanged();*/
+	void GetUpdatedNumOfImages(TInt& aNumOfImages, TInt& aNumOfFaces);
+	
+	// Functions for handling UI access to Filename array
+	CImageData* GetImageData(TInt aIndex/*, TImageArrayMode aMode*/);
+	//CImageData* GetImageData(TInt aIndex);
+	void SetImageData(TInt aIndex, CImageData* aGridData);
+	CIEImageList& GetImageList();
+	TInt DeleteFile(const CImageData* aImageData);
+	void StopImageFinder();
+	void ImageFinderStopped(); // callback
+	TImageFinderState ImageFinderState() const;
+#ifdef _ACCELEROMETER_SUPPORTED_
+	TImagicDeviceOrientation CIEFileLoader::DeviceOrientation();
+#endif
+	
+private: // Data
+    TBuf<KMaxFileName>     iTotalRootFolder;
+    
+    //CFileSystemMonitorAO*   iFileSystemMonitor;
+	RFs&                   iFileServer;
+	CIEEngineImp*          iEngImp;
+	TInt                   iCurrentFileIndex;
+	RArray<CImageData*>    iFileNameData;
+	RArray<CImageData*>    iFaceFilenameData;
+	CIEImageList*          iImageList;
+	
+	//For file searching
+	RFile                  iFile;
+	TInt                   iOffSet;
+	TInt                   iNumberOfImages;
+	TInt                   iNumberOfFaces;
+	CFileFinderThread*     iImageFinderThread;
+	RCriticalSection*      iCritical;
+	CImageMonitorAO*       iImageFinderMonitor;
+	TThreadId              iMainThreadId;
+	//TBool                  iJpgFileCountingComplete;
+    TImageFinderState      iImageFinderState;	
+};
+
+#endif // __IEFILELOADER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEImage.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,121 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGE_H__
+#define __IEIMAGE_H__
+
+// Include files
+#include <e32base.h>
+#include "IEBgpsInfo.h"
+#include "ImagicConsts.h"
+
+
+//_LIT8(KFaceCoordsHeader, "Face Coordinates");
+//_LIT8(KFaceCoordsImagicVersion, "Imagic v2.0:");
+
+enum TThumbSize
+{
+    ENotDefined = 0,
+    ESize32x32 = 1,
+    //ESize128x96 = 2,
+    ESize128x128 = 4,
+    ESize512x512 = 8,
+    EFullSize = 16,
+    EExifThumb = 32
+};
+
+enum TIEFeature
+{
+	EFeatureNone = 1,
+	EBrightness,
+	EContrast,
+	EColorAdjustment,
+	EGamma,
+	ECropping,
+	EEdgeEnhancement,
+	ERotation,
+	ELocalColorCorrection,
+	EFaceDetection,
+	EFeatureError
+};
+
+enum TIEEditingMode
+{
+	EEditModeNone = 1,
+	EEditModeWizard,
+	EEditModeAdvanced,
+	EEditModeRotate,
+	EEditModeCrop,
+	EEditModeError,
+	EEditModeBrowsing
+};
+
+enum TImageForamt
+{
+	EYuv420Planar = 1,
+	EYuv422,
+	EYuv444
+};
+
+enum TRotationAngle
+{
+	ERotationClockwise90 = 1,
+	ERotationClockwise180,
+	ERotationClockwise270
+};
+
+class TIEColorParams
+{
+public:
+	TInt iRedValue;
+	TInt iGreenValue;
+	TInt iBlueValue;
+};
+
+class TIEWizardImageParams
+{
+public:
+	TBool iIsWizardEdit;
+	TInt iBrightnessVal;
+	TInt iContrastVal;
+	TIEColorParams iColorVal;
+	TInt iGammmaVal;
+	TInt iSharpnessVal;
+	TInt iLocalColorVal;
+};
+
+class TIEImageParams
+{
+public:
+	TBool iIsNonWizardEdit;
+	TIEFeature iFeature;
+	TInt iValue;
+	TIEColorParams iColorValue;
+	TRect iCropRect;	
+};
+
+class TIEImage
+{
+public:	
+	TFileName iFileName;
+	TFileName iEditedFileName;
+	TInt iFileIndex;
+	TIEWizardImageParams iWizardParams;
+	TIEImageParams iImageParams;
+};
+
+#endif // __IEIMAGE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEImageDecoder.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEDECODER_H__
+#define __IEIMAGEDECODER_H__
+
+// Include files
+#include <e32base.h>
+#include <f32file.h>
+#include <fbs.h>
+#include <ImageConversion.h>
+#include <IclExtJpegApi.h>
+
+#include "IEImage.h"
+
+class MDecodingObserver
+{
+public:
+	//virtual void YuvImageReadyL(TInt aError) = 0;
+	virtual void BitmapReadyL(TInt aError) = 0;
+};
+
+// Forward class declarations
+
+// Class declaration
+class CIEImageDecoder : CActive
+{
+public:
+	static CIEImageDecoder* NewL(RFs& aFileServer, MDecodingObserver& aObserver);
+	~CIEImageDecoder();
+
+private:
+	void ConstructL();
+	CIEImageDecoder(RFs& aFileServer, MDecodingObserver& aObserver);
+	
+public: // From CAtive
+	void RunL()	;
+	void DoCancel();
+	
+public:
+	void GetImageSizeL(const TFileName aFileName, TSize& aSize);
+	void ConvertJpeg2YuvL(const TDesC& aSourceFile, 
+					HBufC8& aBuffer, 
+					const TImageForamt aImageFormat);
+	
+	void ConvertJpeg2BitmapL(CFbsBitmap& aDestBitmap, TDesC8& aSourceData);
+	
+	TPtr8 GetVisualFrame();
+	
+	void CancelDecoding();
+	
+private: // Data
+	RFs& iFileServer;
+	MDecodingObserver& iObserver;
+	CImageDecoder* iImageDecoder;
+	CExtJpegDecoder* iExtImageDecoder;
+	CVisualFrame* iVisualFrame;
+	TBool iDecoderBusy;
+	TBool iDecode2Yuv;
+	TBool iDecode2Bitmap;
+	TPtr8 iSrcPtr;
+	
+	TUint8* iBufU;
+	TInt iNumOfBitmaps;
+};
+
+#endif // __IEIMAGEDECODER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEImageEncoder.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEENCODER_H__
+#define __IEIMAGEENCODER_H__
+
+// Include files
+#include <e32base.h>
+#include <f32file.h>
+#include <fbs.h>
+#include <ImageConversion.h>
+#include <IclExtJpegApi.h>
+
+#include "IEImage.h"
+
+// Forward class declarations
+class MEncodingObserver
+{
+public:
+	virtual void JpegImageReadyL(TInt aError) = 0;
+};
+
+
+// Class declaration
+class CIEImageEncoder : CActive
+{
+public:
+	static CIEImageEncoder* NewL(RFs& aFileServer, MEncodingObserver& aObserver);
+	~CIEImageEncoder();
+
+private:
+	void ConstructL();
+	CIEImageEncoder(RFs& aFileServer, MEncodingObserver& aObserver);
+	
+public:
+	void ConvertYuv2JpegL(HBufC8*& aDestBuffer, 
+					HBufC8& aSourceBuffer, 
+					const TSize aSize, 
+					const TImageForamt aFormat);
+	
+	void ConvertYuv2JpegL(TDesC& aFileName, 
+					HBufC8& aSourceBuffer, 
+					const TSize aSize, 
+					const TImageForamt aFormat);
+
+	void CancelEncoding();
+	
+private:	
+	void SetJpegImageDataL();
+	
+public: // From CAtive
+	void RunL()	;
+	void DoCancel();
+	
+private: // Data
+	RFs& iFileServer;
+	MEncodingObserver& iObserver;
+	
+	CImageEncoder* iImageEncoder;
+	CExtJpegEncoder* iExtImageEncoder;
+	
+	CVisualFrame* iVisualFrame;
+	
+	CFrameImageData* iFrameImageData;
+		
+	TBool iEncoderBusy;
+};
+
+#endif // __IEIMAGEENCODER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEImageFinder.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEFINDER_H_
+#define __IEIMAGEFINDER_H_
+
+// INCLUDES
+#include <e32base.h>
+#include <f32file.h>
+#include <IEEngine.h>
+#include <bautils.h>
+
+#include "IEFileLoader.h"
+#include "IEImageList.h"
+#include <ExifUtility.h> 
+#include <ICLExif.h> 
+#include "ImageMonitorAO.h"
+#include "IEEngineImp.h"
+
+#include <IEImageProcessing.h>
+#include <exifread.h>
+
+#include "IEEngineImp.h"
+#include "IEEngineUtils.h"
+#include "FileSystemMonitorAO.h"
+
+// FORWARD DECLARATIONS
+class CIEFileLoader;
+class CFileSystemMonitorAO;
+
+class CIEImageFinder : public CBase
+    {
+    public:
+        static CIEImageFinder* NewL(
+                CIEFileLoader* aCallback, 
+                RArray<CImageData*>& aFileNameData, 
+                RArray<CImageData*>& aFaceFileNameData, 
+                RCriticalSection* aCritical);
+        
+        static CIEImageFinder* NewLC(
+                CIEFileLoader* aCallback, 
+                RArray<CImageData*>& aFileNameData, 
+                RArray<CImageData*>& aFaceFileNameData, 
+                RCriticalSection* aCritical);
+        
+        CIEImageFinder(CIEFileLoader* callback, 
+                        RArray<CImageData*>& aFileNameData, 
+                        RArray<CImageData*>& aFaceFileNameData, 
+                        RCriticalSection* aCritical);
+        void ConstructL();
+        ~CIEImageFinder();
+        void StartFinderL(const TDesC& aSearchName);
+        void FileSystemChanged();
+        void SetImageDataChanged();
+        
+    private:
+        void ScanDirL(CDir* dir, const TDesC& aDir, const TDesC& aWild);
+        void SearchFilesL(const TDesC& aSearchName);
+        TInt CheckIfFileExist(TFileName& aFileName);
+        float ReadAspectRatioL(TFileName& aFileName);
+        void CheckCreatedThumbnails(CImageData& aImageData) const;
+        void GetDatabaseFileName(TFileName & fileName) const;
+        TBool IsSearching() const;
+       
+    private:
+        //CFileSystemMonitorAO*   iFileSystemMonitor;
+        CIEImageList*           iImageList;
+        RFs                     iFileServer;
+        CIEFileLoader*          iCallback;
+        CIEEngineUtils          iIEEngineUtils;
+        RArray<CImageData*>&    iFileNameData;
+        RArray<CImageData*>&    iFaceFileNameData;
+        RCriticalSection*       iCritical;
+        TExifReaderUtility*     iExifReader;
+    };
+
+#endif //__IEIMAGEFINDER_H_
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEImageFinderAO.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEFINDER_H_
+#define __IEIMAGEFINDER_H_
+
+// INCLUDES
+#include <e32base.h>
+#include <f32file.h>
+#include <IEEngine.h>
+#include <bautils.h>
+
+#include "IEFileLoader.h"
+#include <ExifUtility.h> 
+#include <ICLExif.h> 
+
+
+// FORWARD DECLARATIONS
+
+class CIEImageFinder : public CBase
+    {
+    public:
+        static CIEImageFinder* NewL(CIEFileLoader* aCallback, RArray<TImageData*>& aFileNameData,TBool& aAll128x128TNsDone, 
+                                     TBool& aAll640x480TNsDone, TBool& aAll320x320TNsDone, RCriticalSection* aCritical);
+        
+        static CIEImageFinder* NewLC(CIEFileLoader* aCallback, RArray<TImageData*>& aFileNameData,TBool& aAll128x128TNsDone, 
+                                      TBool& aAll640x480TNsDone, TBool& aAll320x320TNsDone, RCriticalSection* aCritical);
+        
+        CIEImageFinder(CIEFileLoader* callback, RArray<TImageData*>& aFileNameData, TBool& aAll128x128TNsDone,
+                        TBool& aAll640x480TNsDone, TBool& aAll320x320TNsDone, RCriticalSection* aCritical);
+        void ConstructL();
+        ~CIEImageFinder();
+        void ScanDirL(CDir* dir, const TDesC& aDir, const TDesC& aWild);
+        //void ScanDirL(const TDesC& aDir, const TDesC& aWild);
+        void SearchFilesL(const TDesC& aRootPath, const TDesC& aSearchName);
+        void IEImageFinderStartL(const TDesC& aRootPath, const TDesC& aSearchName);
+        TInt CheckIfFileExist(TFileName& aFileName);
+        float ReadAspectRatioL(TFileName& aFileName);
+  
+    private:
+        TBool IsFileExist(const TDesC &aFileName);
+        void CheckForTNFiles(TImageData &aImageData);
+        float ReadExifDataL(const TDes &aFileName);        
+     
+        
+    private:
+        RFs                     iFileServer;
+        CIEFileLoader*          iCallback;
+        RArray<TImageData*>&    iFileNameData;
+        TBool&                  iAll640x480TNsDone; 
+        TBool&                  iAll128x128TNsDone;
+        TBool&                  iAll320x320TNsDone;
+        TBufC<KMaxFileName>     iRootPath;
+        TBufC<KMaxFileName>     iSearchName;
+        RCriticalSection*       iCritical;
+        TExifReaderUtility*     iExifReader;
+//        CImageDecoder*          iImageDecoder;
+        TBool                   iTnFoldersCreated;
+    };
+
+#endif //__IEIMAGEFINDER_H_
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEImageList.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGELIST_H_
+#define __IEIMAGELIST_H_
+
+// INCLUDES
+#include <e32base.h>
+#include <f32file.h>
+#include <bautils.h>
+#include <s32file.h>
+#include <ICLExif.h> 
+#include <exifread.h>
+#include <ExifUtility.h>
+
+#include "IEImageProcessing.h"
+#include "IEEngineUtils.h"
+
+class CIEFileLoader;
+
+enum TGridMode {
+    EGridModeTime,
+    EGridModeFolder,
+    EGridModePeople
+};
+
+class CIEImageList
+    {
+public:
+    IMPORT_C static CIEImageList* NewL(RArray<CImageData*>& aImageData, CIEFileLoader* aCallback);
+    IMPORT_C ~CIEImageList();    
+    IMPORT_C TBool IsImageViewableL(TDesC& aFileName, RFs& aFs) const;
+    IMPORT_C void ReadDatabaseL();
+    IMPORT_C void WriteDatabaseL();
+    IMPORT_C CImageData* CreateImageDataL(
+            const TFileName& aFileName, 
+            const TTime& aCreatedTime, 
+            TReal orientation);
+    IMPORT_C void AddImage(CImageData* aImageData);
+    IMPORT_C void Remove(TInt aIndex, RFs& aFs);
+    IMPORT_C void RemoveNonExistImagesL(TDesC* aPath, RFs& aFs);     
+    IMPORT_C TInt GetImageIndex(CImageData* aImageData);
+    IMPORT_C CImageData* GetImageData(const TFileName& aFileName);
+    IMPORT_C void SetChanged(TDesC& aPath);
+    IMPORT_C void SetGridMode(TGridMode aGridMode);
+    IMPORT_C TGridMode GetGridMode() const;    
+    
+private:        
+    enum TImageListDrive {
+        EImageListDriveC = 0,
+        EImageListDriveE = 1,
+        EImageListDriveF = 2,
+    };
+  
+    CIEImageList(RArray<CImageData*>& aImageData, CIEFileLoader* aCallback);
+    void ConstructL();
+    CImageData* ReadImageDataL(RFileReadStream& readStream, RFs& aFs);
+    void WriteDatabaseL(TImageListDrive aDrive, RFs& aFs);
+    void GetDatabaseFileName(TFileName& aFileName, TImageListDrive aDrive);
+    TBool IsImageBefore(CImageData* aImageData1, TInt aIndex) const;
+    TInt GetNewImageIndex(CImageData* aImageData) const;
+    void Rearrange(TInt aStartIndex);
+    void SetChanged(CImageData* aImageData);
+    static TImageListDrive GetPathDriveL(TDesC& aPath);
+    
+    CIEFileLoader*          iCallback; 
+    TBool                   iDatabaseChanged[3];
+    RArray<CImageData*>&    iImageDataList;    
+    TGridMode               iGridMode;
+    RCriticalSection        iCritical;
+    };
+
+#endif //__IEIMAGELIST_H_
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IESensorDataFilter.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef IESENSORDATAFILTER_H
+#define IESENSORDATAFILTER_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+
+// CLASS DECLARATION
+
+/**
+ *  CIESensorDataFilter
+ * 
+ */
+const TInt KDataBufferSize = 16; 
+
+class CIESensorDataFilter : public CBase
+    {
+public:
+    // Constructors and destructor
+
+    /**
+     * Destructor.
+     */
+    ~CIESensorDataFilter();
+
+    /**
+     * Two-phased constructor.
+     */
+    static CIESensorDataFilter* NewL();
+
+    /**
+     * Two-phased constructor.
+     */
+    static CIESensorDataFilter* NewLC();
+
+private:
+
+    /**
+     * Constructor for performing 1st stage construction
+     */
+    CIESensorDataFilter();
+
+    /**
+     * EPOC default constructor for performing 2nd stage construction
+     */
+    void ConstructL();
+ 
+public:
+
+    TInt FilterSensorData(TInt aNewValue);
+
+private:
+    
+    TInt* iRingBuffer;
+    TInt* iRingBufferPointer;
+    
+    };
+
+#endif // IESENSORDATAFILTER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IESensorMonitor.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,136 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IESensorMonitor_H__
+#define __IESensorMonitor_H__
+
+// INCLUDES
+
+#include <e32base.h>
+#include <e32uid.h>
+#include "ImagicConsts.h"
+
+#ifdef _S60_3x_ACCELEROMETER_
+#define SENSOR_API_LOAD_DYNAMICALLY
+
+#include "RRSensorApi.h"
+#include "IESensorDataFilter.h"
+#endif
+
+#ifdef _S60_5x_ACCELEROMETER_
+    #include <sensrvproperty.h>
+    #include <sensrvtypes.h> 
+    #include <sensrvchannelfinder.h>
+    #include <sensrvchannel.h>
+    #include <sensrvgeneralproperties.h>
+    //#include <sensrvmagnetometersensor.h>
+    #include <sensrvaccelerometersensor.h>
+    #include <sensrvorientationsensor.h>
+    #include <sensrvdatalistener.h> 
+//#include <sensrvtappingsensor.h> 
+#endif 
+
+//#ifdef _S60_3x_ACCELEROMETER_
+#ifdef _ACCELEROMETER_SUPPORTED_
+enum TImagicDeviceOrientation
+	{
+	EOrientationDisplayUp = 1,// Portrait Up
+	EOrientationDisplayDown,// Portrait Down
+	EOrientationDisplayLeftUp,// Landscape Down
+	EOrientationDisplayRigthUp// Landscape Up
+	};
+#endif
+
+#ifdef _ACCELEROMETER_SUPPORTED_
+
+class MIESensorMonitorObserver
+{
+public:
+    virtual void SensorDataAvailable(TImagicDeviceOrientation aOrientation, TBool aValue) = 0;
+    virtual void SetImageRotation(TInt aIndex) = 0;
+};
+
+#ifdef _S60_3x_ACCELEROMETER_
+    class CIESensorMonitor : public MRRSensorDataListener
+#endif
+#ifdef _S60_5x_ACCELEROMETER_
+    class CIESensorMonitor : public MSensrvDataListener
+#endif
+    {
+    public:
+        static CIESensorMonitor* NewL(MIESensorMonitorObserver& aSensorObserver);
+        ~CIESensorMonitor();
+ 
+    private:         
+        void ConstructL();
+        CIESensorMonitor(MIESensorMonitorObserver& aSensorObserver);
+    public:    
+        void StartMonitoring();
+        void StopMonitoring();
+    protected:
+        
+#ifdef _S60_3x_ACCELEROMETER_
+        
+        void HandleDataEventL(TRRSensorInfo aSensor, TRRSensorEvent aEvent);
+#endif  
+#ifdef _S60_5x_ACCELEROMETER_
+        
+   		void DataReceived( CSensrvChannel& aChannel, TInt aCount, TInt aDataLost );
+    	void DataError( CSensrvChannel& aChannel, TSensrvErrorSeverity aError );
+    	void GetDataListenerInterfaceL( TUid /*aInterfaceUid*/, TAny*& /*aInterface*/ ){};
+    	
+#endif
+    	
+    private: 
+        
+        MIESensorMonitorObserver& iSensorObserver;
+        
+#ifdef _S60_3x_ACCELEROMETER_
+        
+		// S60 3x Code
+		RArray <TRRSensorInfo> iSensorList;
+
+#ifdef SENSOR_API_LOAD_DYNAMICALLY
+        RLibrary iSensorApi;
+#endif //SENSOR_API_LOAD_DYNAMICALLY
+    
+        CRRSensorApi* iAccelerometerSensor;
+		TInt	iAccelerometerSensorIndex;
+        
+        TInt iAccSensorDataX;
+        TInt iAccSensorDataY;
+        TInt iAccSensorDataZ;
+        
+        CIESensorDataFilter* iSensorDataFilterX;
+        CIESensorDataFilter* iSensorDataFilterY;
+        CIESensorDataFilter* iSensorDataFilterZ;
+#endif
+
+            
+#ifdef _S60_5x_ACCELEROMETER_
+
+        CSensrvChannelFinder*	iSensrvChannelFinder;
+        RSensrvChannelInfoList  iChannelInfoList;
+        CSensrvChannel*			iSensrvSensorChannel;
+    	TInt					iUpdateInterval;
+    	//TUint32					iDataCount,iDataLostCount;
+#endif
+    };
+#endif//_ACCELEROMETER_SUPPORTED_
+  
+#endif // __IESensorMonitor_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/IEThreadEngine.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/ 
+
+#ifndef __FILEFINDERTHREAD_H__
+#define __FILEFINDERTHREAD_H__
+
+// INCLUDES
+#include <e32base.h> 
+#include <badesca.h> 
+#include <IEBgpsInfo.h>
+#include <PathInfo.h>
+#include <BAUTILS.H>
+
+// FORWARD DECLARATIONS
+class IEImageFinderAO;
+class CImageData;
+class CIEFileLoader;
+
+
+// CLASS DECLARATION
+
+class CMediator: public CBase
+{
+public:
+    RArray<CImageData*>*    iFileNameData;
+    RArray<CImageData*>*    iFaceFileNameData;
+    TBool*                  iAll128x128TNsDone;
+    TBool*                  iAll640x480TNsDone;
+    TBool*                  iAll320x320TNsDone;
+    CIEFileLoader*          iFileLoader;
+    RCriticalSection*       iCritical;
+    TFileName                  iFileName;
+};
+
+
+/**
+*  CFileFinderThread application engine class.
+*/
+class CFileFinderThread: public CBase
+	{
+public: 
+
+	static CFileFinderThread* NewL(CIEFileLoader* aFileLoader, 
+                                    RArray<CImageData*>& aFileNameData, 
+                                    RArray<CImageData*>& aFaceFileNameData, 
+                                    RCriticalSection* aCritical, TDesC& aFileName);
+	
+	static CFileFinderThread* NewLC(CIEFileLoader* aFileLoader, 
+                                    RArray<CImageData*>& aFileNameData, 
+                                    RArray<CImageData*>& aFaceFileNameData,  
+	                                RCriticalSection* aCritical, TDesC& aFileName);
+	
+	CFileFinderThread(CIEFileLoader* aFileLoader, 
+                        RArray<CImageData*>& aFileNameData, 
+                        RArray<CImageData*>& aFaceFileNameData, 
+	                    RCriticalSection* aCritical, TDesC& aFileName);
+	
+	~CFileFinderThread(void);
+
+	void StartL();
+	void Stop();
+	static TInt ExecuteThreadOne(TAny *aPtr);
+	static void CreateFileFinderL(CMediator* aMediator);
+
+private: //functions
+	void CreateThreadsL();
+
+private: // Basic two-phase Symbian OS constructors
+	void ConstructL();
+	CFileFinderThread();
+	
+private: // data members       
+	
+	// a handle for thread1
+	RThread                iThreadOne;
+	TBool                  iCreatedThreads;
+	CMediator*             iSMediator;
+	RArray<CImageData*>&   iFileNameData;
+	RArray<CImageData*>&   iFaceFileNameData;
+	CIEFileLoader*         iFileLoader;
+	RCriticalSection*      iCritical;
+	TBufC<KMaxFileName>    iRootPath;
+    TBufC<KMaxFileName>    iSearchName;
+    TFileName              iFilename;
+    };
+
+#endif // __FILEFINDERTHREAD_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/ImageMonitorAO.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/ 
+
+#ifndef __IMAGEMONITORAO_H__
+#define __IMAGEMONITORAO_H__
+
+class CIEEngineImp;
+
+class CImageMonitorAO : public CActive
+    {
+    public:
+        // Constructor and destructor
+        static CImageMonitorAO* NewL(CIEEngineImp* aEngImp);
+        static CImageMonitorAO* NewLC(CIEEngineImp* aEngImp);
+        void ConstructL();
+        CImageMonitorAO(CIEEngineImp* aEngImp);
+        ~CImageMonitorAO();
+        void ActiveRequest();
+       
+    private:
+        // From CActive
+        void RunL();
+        void DoCancel();
+        void RunError();
+        
+    private: // Data
+        CIEEngineImp*          iEngImp;
+
+        
+    };
+
+#endif //__IMAGEMONITORAO_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/debug.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IMAGIC_TRACE_H__
+#define __IMAGIC_TRACE_H__
+
+//#define _IMAGIC_DEBUG
+#ifdef _IMAGIC_DEBUG
+
+#include <e32debug.h>
+
+#define DP0_IMAGIC(string)                            RDebug::Print(string)
+#define DP1_IMAGIC(string,arg1)                       RDebug::Print(string,arg1)
+#define DP2_IMAGIC(string,arg1,arg2)                  RDebug::Print(string,arg1,arg2)
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             RDebug::Print(string,arg1,arg2,arg3)
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        RDebug::Print(string,arg1,arg2,arg3,arg4)
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)   RDebug::Print(string,arg1,arg2,arg3,arg4,arg5)
+
+#else
+
+#define DP0_IMAGIC(string)                            
+#define DP1_IMAGIC(string,arg1)                       
+#define DP2_IMAGIC(string,arg1,arg2)                  
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)
+#endif // _DEBUG
+
+
+#endif //__IMAGIC_TRACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngInc/rrsensorapi.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,147 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef RRSENSORAPI_H
+#define RRSENSORAPI_H
+
+//  INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+
+const TInt KMaxSensorName = 128;
+
+// CLASS DECLARATION
+
+/**
+*  TRRSensorInfo.
+*  Contains info of sensor
+*
+*  iSensorId identifies individual sensors
+*
+*  iSensorCategory can have following values:
+*  0x10010FFF for sensor server internal sensors and
+*  0x10010321 for external sensors.
+*
+*  iSensorName contains string name of sensor. This
+*  can be used e.g. to show name of sensor to user.
+*
+*  @lib rrsensorapi.lib
+*/
+class TRRSensorInfo
+    {
+    public:
+    TInt iSensorCategory;
+    TInt iSensorId;
+    TBuf<KMaxSensorName> iSensorName;
+    };
+
+/**
+*  TRRSensorEvent
+*  Data obtained from sensor 
+*  --------------------------------------------------------------------------
+*  E.g. to sensor server internal Accelerator sensor id: 0x10273024
+*  these fields contain following information:
+*  iSensorData1 = acceleration in axis X
+*  iSensorData2 = acceleration in axis Y
+*  iSensorData3 = acceleration in axis Z
+*  --------------------------------------------------------------------------
+*  Data from external sensors may vary.
+*
+*  @lib rrsensorapi.lib
+*/
+class TRRSensorEvent
+    {
+    public:
+    TInt iSensorData1;
+    TInt iSensorData2;
+    TInt iSensorData3;
+    };
+
+
+/**
+*  MRRSensorDataListener
+*  Callback function for receiving sensor
+*  data events
+*
+*  TRRSensorInfo identifies sensor that created the event.
+*
+*  TTRRSensorEvent contains data about created event.
+*
+*  @lib rrsensorapi.lib
+*/
+class MRRSensorDataListener
+    {
+    public:
+        virtual void HandleDataEventL( TRRSensorInfo aSensor, 
+                                       TRRSensorEvent aEvent ) = 0;
+    };
+
+/**
+*  CRRSensorApi
+*  User access to sensor server
+*  data events
+*  @lib rrsensorapi.lib
+*/
+class CRRSensorApi : public CBase
+{
+public:
+    /**
+    * Create new sensor access
+    * @param TRRSensorInfo identifing desired sensor.
+    * @return CRRSensorApi*
+    */
+	IMPORT_C static CRRSensorApi* NewL( TRRSensorInfo aSensor );
+	
+    /**
+    * Retrieve list of available sensors
+    * @param RArray<TRRSensorInfo>& upon completion
+    *        contains list of available sensors.
+    * @return void
+    */
+    IMPORT_C static void FindSensorsL( RArray<TRRSensorInfo>& aSensorInfoArray );
+	
+    /**
+    * Register data listener
+    * @param MRRSensorDataListener* register this pointer as sensor
+    *        event listener.
+    * @return void
+    */
+    virtual void AddDataListener( MRRSensorDataListener* aListener ) = 0;
+	
+    /**
+    * Remove data listener
+    * @param void
+    * @return void
+    */
+    virtual void RemoveDataListener() = 0;
+
+    /**
+    * Send sensor specific command.
+    * This feature is intended for future use and
+    * is not currently supported.
+    *
+    * @param TInt& aCommand identify of command.
+    *        TInt& aValue desired value for command.
+    * @return TInt error code
+    */
+	virtual TInt SensorCommand( TInt& aCommand, TInt& aValue ) = 0;
+    
+};
+
+#endif  //RRSENSORAPI_H
+
+//  End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/FileSystemMonitorAO.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "FileSystemMonitorAO.h"
+
+    
+CFileSystemMonitorAO* CFileSystemMonitorAO::NewL(RFs& aFileServer, CIEImageFinder* aImageFinder)
+    {
+    CFileSystemMonitorAO* self = new(ELeave) CFileSystemMonitorAO(aFileServer, aImageFinder);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+CFileSystemMonitorAO* CFileSystemMonitorAO::NewLC(RFs& aFileServer, CIEImageFinder* aImageFinder)
+    {
+    CFileSystemMonitorAO* self = new(ELeave) CFileSystemMonitorAO(aFileServer, aImageFinder);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+ 
+CFileSystemMonitorAO::CFileSystemMonitorAO(RFs& aFileServer, CIEImageFinder* aImageFinder) :
+        CActive(CActive::EPriorityLow),
+        iFileServer(aFileServer),
+        iImageFinder(aImageFinder)
+    {
+    CActiveScheduler::Add(this);
+    }
+
+void CFileSystemMonitorAO::ConstructL()
+    {
+    //StartMonitoring();
+    }
+
+
+CFileSystemMonitorAO::~CFileSystemMonitorAO()
+    {
+    Cancel();
+    }
+ 
+void CFileSystemMonitorAO::RunL()
+    {
+    iImageFinder->FileSystemChanged();
+    }
+
+ 
+void CFileSystemMonitorAO::DoCancel()
+    {
+    if(IsActive())
+        Cancel();
+    
+    iFileServer.NotifyChangeCancel(iStatus);
+    }
+
+ 
+void CFileSystemMonitorAO::RunError()
+    {
+    // Nothing here
+    }
+
+//This name should be changed to IssueActiveRequest()
+//This is more meaningful...
+void CFileSystemMonitorAO::StartMonitoring()
+    {//ENotifyEntry, ENotifyFile
+#ifdef __WINS__
+    iFileServer.NotifyChange(ENotifyEntry, iStatus, KRootImagePath);
+#else
+    TFileName rootPath = PathInfo::MemoryCardRootPath();
+    rootPath.Append(ImagePath);
+    iFileServer.NotifyChange(ENotifyFile, iStatus, rootPath);
+#endif
+    
+    SetActive();
+    }
+
+void CFileSystemMonitorAO::StopMonitoring()
+    {
+    iFileServer.NotifyChangeCancel();    
+    }
+
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEBgpsController.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,793 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include <BAUTILS.H>
+
+#include "IEBgpsController.h"
+#include "debug.h"
+#include "ImagicConsts.h"
+
+// ====================== MEMBER FUNCTION ================================== //
+
+CIEBgpsController* CIEBgpsController::NewL(RFs& aFileServer,
+                                        MIEBgpsControllerObserver& aIEBgpsControllerObserver, 
+                                        CIEEngineUtils& aEngineUtils,
+                                        RCriticalSection* aCritical)
+    {
+    CIEBgpsController* self = new (ELeave) CIEBgpsController(aFileServer,
+                                                            aIEBgpsControllerObserver, 
+                                                            aEngineUtils,
+                                                            aCritical);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+CIEBgpsController::CIEBgpsController(RFs& aFileServer, MIEBgpsControllerObserver& aIEBgpsControllerObserver, 
+                                     CIEEngineUtils& aEngineUtils, RCriticalSection* aCritical)
+    :iFileServer(aFileServer),
+    iIEBgpsControllerObserver(aIEBgpsControllerObserver),
+    iFileLoader(NULL),
+    iIEEngineUtils(aEngineUtils),
+    iCritical(aCritical)
+    {
+    
+    }
+
+CIEBgpsController::~CIEBgpsController()
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::~CIEBgpsController++"));
+    
+    if(iIEBgpsClient)
+        {
+        delete iIEBgpsClient;
+        iIEBgpsClient = NULL;    
+        }
+    
+    iFaceCropImageDataArray.Close();
+    iFBCoordinateArray.Close();
+    
+    DP0_IMAGIC(_L("CIEBgpsController::~CIEBgpsController--"));
+    }
+
+void CIEBgpsController::ConstructL()
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::ConstructL++"));
+    
+    iImageIndex = 0;
+    iSingleTNGeneration = EFalse;
+    iTnCreationCancelled = EFalse;
+    iAllTNsDone = EFalse;
+    
+    //iIEBgpsClient = CIEImageProcessing::NewL(*this);
+    
+    DP0_IMAGIC(_L("CIEBgpsController::ConstructL--"));
+    }
+
+
+void CIEBgpsController::SetFileLoader(CIEFileLoader* aFileLoader)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::SetFileLoader"));
+    
+    iFileLoader = aFileLoader;
+    }
+
+
+void CIEBgpsController::CreateImageProcessing()
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::CreateImageProcessing"));
+    
+    iIEBgpsClient = CIEImageProcessing::NewL(*this);
+    
+    }
+
+
+void CIEBgpsController::ThumbnailGenerationCompleted(TInt aErrorCode)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted++"));
+    
+    if (aErrorCode == KErrCancel)
+        return;
+    
+    /*CImageData* imageData = iIEBgpsControllerObserver.GetImageData(iTnCreationIndex, EImages);
+    TFileName filename;
+    imageData->GetFileName(filename, ESize512x512);
+    DP1_IMAGIC(_L("CFaceBrowser::BrowseFacesL 512x512TNFile = %S ++"), &filename);*/
+        
+    //Single TN generation ----------->
+    if(aErrorCode != KErrNone)
+        {
+        DP1_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - Error in TN creation: %d"), aErrorCode);
+        
+        CImageData* imageData = iIEBgpsControllerObserver.GetImageData(iTnCreationIndex);
+        //Mark image as corrupted so we do not try to generate TN or load it
+        imageData->iGridData.iCorrupted = ETrue;
+            
+        //In Error case any way delete the iCorrupted Thumbnail + file we were trying to generate TN(if it is not original)
+        if(!iSingleFaceDetectionOn)
+            {
+            DeleteCorruptedThumbNailFile(iTNFilename);
+            if(iJpegFilename.Find(KPAlbTNFilePath) != KErrNotFound)
+                {
+                DeleteCorruptedThumbNailFile(iJpegFilename);
+                }
+            }
+        }
+
+    iSingleFaceDetectionOn = EFalse;
+    
+    //If no error mark that TN was created
+    if(aErrorCode == KErrNone)
+        {
+        if(i512x512TNCreationOn)
+            {
+            DP0_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - i512x512TNCreationOn"));
+            iImageDataArray[iTnCreationIndex]->iGridData.iCorrupted = EFalse;
+            iImageDataArray[iTnCreationIndex]->SetImageReady(ESize512x512, ETrue);
+            iIEBgpsControllerObserver.SingleTNGenerationComplete(iTnCreationIndex, ESize512x512);
+
+/*#ifdef FACE_DETECTION
+            TInt count = iFBCoordinateArray.Count();
+            for(TInt i=0; i<count; i++)
+                iFBCoordinateArray.Remove(0);
+                
+            iSingleFBCoordinateArray = &iFBCoordinateArray;
+            iImageData = iIEBgpsControllerObserver.GetImageData(iTnCreationIndex, EImages);
+            
+            iIEBgpsClient->StartSingleFaceDetection(iTnCreationIndex, *iSingleFBCoordinateArray, iImageData);
+            iSingleFaceDetectionOn = ETrue;
+#endif*/
+            }
+        if(i128x128TNCreationOn)
+            {
+            DP0_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - i128x128TNCreationOn"));
+            iImageDataArray[iTnCreationIndex]->SetImageReady(ESize128x128, ETrue);
+            iIEBgpsControllerObserver.SingleTNGenerationComplete(iTnCreationIndex, ESize128x128);
+            }
+        if(i32x32TNCreationOn)
+            {
+            DP0_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - i32x32TNCreationOn"));
+            iImageDataArray[iTnCreationIndex]->SetImageReady(ESize32x32, ETrue);
+            iIEBgpsControllerObserver.SingleTNGenerationComplete(iTnCreationIndex, ESize32x32);
+            
+#ifdef FACE_DETECTION
+            TInt count = iFBCoordinateArray.Count();
+            for(TInt i=0; i<count; i++)
+                iFBCoordinateArray.Remove(0);
+                
+            iSingleFBCoordinateArray = &iFBCoordinateArray;
+            iImageData = iIEBgpsControllerObserver.GetImageData(iTnCreationIndex);
+            
+            //iIEBgpsClient->StartSingleFaceDetection(iTnCreationIndex, *iSingleFBCoordinateArray, iImageData);
+            iSingleFaceDetectionOn = ETrue;
+#endif
+            }
+        }
+
+    if(aErrorCode != KErrNone || !iSingleFaceDetectionOn)
+        {
+        TThumbSize res;
+        iTnCreationIndex = FindMissingTN(res);
+        
+        iAllTNsDone = ETrue;
+        //Check if all TN images are done
+        for(TInt i=0; i<iImageDataArray.Count(); i++)
+            {
+            if((!iImageDataArray[i]->IsImageReady(ESize512x512) || 
+               !iImageDataArray[i]->IsImageReady(ESize128x128) ||
+               !iImageDataArray[i]->IsImageReady(ESize32x32)) &&
+               !iImageDataArray[i]->iGridData.iCorrupted )
+                {
+                iAllTNsDone = EFalse;
+                DP1_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - Continue TN creation from index: %d"), i);
+                break;
+                }
+            }
+                        
+        if(!iAllTNsDone && iTnCreationIndex >= 0)
+            {
+            //Start creating thumbnails by calling TN creator
+            if(res == ESize512x512)
+                {
+                DP1_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - Res: ESize512x512, Index: %d"),iTnCreationIndex);
+                i512x512TNCreationOn = ETrue;
+                i128x128TNCreationOn = EFalse;
+                i32x32TNCreationOn = EFalse;
+                Generate512x512Thumbnails(iTnCreationIndex);
+                }
+            else if(res == ESize128x128)
+                {
+                DP1_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - Res: ESize128x128, Index: %d"),iTnCreationIndex);
+                i128x128TNCreationOn = ETrue;
+                i512x512TNCreationOn = EFalse;
+                i32x32TNCreationOn = EFalse;
+                Generate128x128Thumbnails(iTnCreationIndex);
+                }
+            else if(res == ESize32x32)
+                {
+                DP1_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - Res: ESize32x32, Index: %d"),iTnCreationIndex);
+                i32x32TNCreationOn = ETrue;
+                i512x512TNCreationOn = EFalse;
+                i128x128TNCreationOn = EFalse;
+                Generate32x32Thumbnails(iTnCreationIndex);
+                }
+            }
+        
+        // Callback after completion of all TNs 
+        if(iAllTNsDone)
+            {
+            i32x32TNCreationOn = EFalse;
+            i128x128TNCreationOn = EFalse;
+            i512x512TNCreationOn = EFalse;
+            DP0_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted - All thumbnails are created, start face Detection"));
+            //iIEBgpsClient->StartFaceDetection(iImageDataArray);
+            //iBackGroundFaceDetectionOn = ETrue;
+            iIEBgpsControllerObserver.TNGenerationComplete(ENotDefined);
+            }
+        }
+
+    DP0_IMAGIC(_L("CIEBgpsController::ThumbnailGenerationCompleted --"));    
+    }
+
+
+void CIEBgpsController::HandleError(TInt aError)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::HandleError"));
+    //Handle BGPS errors here
+    
+    //Cancel UI frame blinking, we can not do anythign else if BGPS is jammed??
+    //iIEBgpsControllerObserver.TNGenerationComplete(ENotDefined);
+    if(i32x32TNCreationOn || i128x128TNCreationOn || i512x512TNCreationOn)
+        {
+        DP0_IMAGIC(_L("CIEBgpsController::HandleError - Error on TN generation, try to continue"));
+        ThumbnailGenerationCompleted(aError);
+        }
+    else
+        {
+        iIEBgpsControllerObserver.TNGenerationComplete(ENotDefined);
+        }
+    }
+
+void CIEBgpsController::ThumbnailGenerationCancelled(TInt /*aErrorCode*/)
+    {
+    //Start TN generation again if it was stopped
+    if(iTnCreationCancelled)
+        ;//StartSingleFaceDetection();
+    }
+
+void CIEBgpsController::GenerateThumbNailL(const TDes &aOrgFile, TThumbSize /*aTNResolution*/)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::GenerateThumbNailL ++"));
+    
+    iSavedFileName.Copy(aOrgFile);
+          
+    /*Generating Thumbnail path for 320x320 */
+    iIEEngineUtils.GenerateThumbnailFileName(ESize32x32,iSavedFileName,iTNFilename);
+    
+    /*Creating folder if not exists */
+    TParse parser;
+    parser.Set(iTNFilename, NULL, NULL );
+    TFileName name = parser.NameAndExt();//image file name
+    TFileName tnPath = parser.DriveAndPath();
+       
+    CIEEngineUtils::CreateTNFolder(iFileServer, tnPath);
+    
+    /*Generating TN file with absolute path */
+    tnPath.Append(name);
+     
+    /* TN file name with absolute path*/
+    iTNFilename.Copy(tnPath);
+    
+    /*Set Single Thumbnail generation flag on */
+    iSingleTNGeneration = ETrue; 
+    
+    /*Generate TN for 320x320 resolution */
+    iLatestCreatedTNSize = ESize32x32;
+    iTmpImageData = CImageData::NewL();
+    
+    TSize originalSize;
+    iIEEngineUtils.GetImageSizeL(iSavedFileName, originalSize);
+    
+    DP1_IMAGIC(_L("iTNFilename: %S"), &iTNFilename);
+    
+    TSize size(320, 320);
+    if (originalSize.iWidth && originalSize.iHeight)
+        {
+        if(originalSize.iWidth > originalSize.iHeight)
+            { // Landscape
+            size.iHeight = 320 * originalSize.iHeight / originalSize.iWidth;
+            if(size.iHeight%2 != 0)
+                size.iHeight++;
+            }
+        else // Portrait
+            {
+            size.iWidth = 320 * originalSize.iWidth / originalSize.iHeight;
+            if(size.iWidth%2 != 0)
+                size.iWidth++;
+            }
+        }
+    
+    iTmpImageData->SetSize(size);
+    iIEBgpsClient->GenerateTN(iSavedFileName, iTNFilename, size);
+
+    
+    DP0_IMAGIC(_L("CIEBgpsController::GenerateThumbNailL--"));
+    }
+
+
+//Filename array has been filled(completetely) when this function is called
+void CIEBgpsController::AllFilesAddedToFilenameArrayL()
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::AllFilesAddedToFilenameArrayL++"));
+    
+    //Get filename array
+    iImageDataArray = iFileLoader->GetFileNameArray();
+    
+    // Start TN generation
+    if(iImageDataArray.Count() > 0)
+        {
+        StartTNCreatorL();
+        }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::AllFilesAddedToFilenameArrayL--"));
+    }
+
+TReal CIEBgpsController::GetAspectRatio(TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::GetAspectRatio"));
+    
+    iImageDataArray = iFileLoader->GetFileNameArray();
+    
+    if(aIndex < iImageDataArray.Count())
+        {
+        return iImageDataArray[aIndex]->GetAspectRatio();
+        }
+    else
+        {
+        return 0;
+        }
+    }
+
+TReal CIEBgpsController::GetFacesAspectRatio(TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::GetAspectRatio"));
+    
+    iImageDataArray = iFileLoader->GetFacesFileNameArray();
+    
+    if(aIndex < iImageDataArray.Count())
+        {
+        return iImageDataArray[aIndex]->GetAspectRatio();
+        }
+    else
+        return 0;
+    }
+
+void CIEBgpsController::GenerateTNForEditedImage(const TFileName aEditedFileName, const TReal aAspectRatio)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::GenerateTNForEditedImage++"));
+
+    iSavedFileName.Copy(aEditedFileName);
+    
+    //set iSingleTNGeneration mode on
+    iSingleTNGeneration = ETrue; 
+    iAspectRatio = aAspectRatio;
+     
+    /*Generating 128x128 Thumbnail path */
+    iIEEngineUtils.GenerateThumbnailFileName(ESize128x128, aEditedFileName, iTNFilename);
+ 
+    //Create new imagedata instance to be appended to filename array
+    iTmpImageData = CImageData::NewL();
+    iTmpImageData->SetSize(TSize(128 * iAspectRatio, 128)); // TODO no size info
+    
+    iLatestCreatedTNSize = ESize128x128;
+    iIEBgpsClient->GenerateTN(aEditedFileName, iTNFilename, TSize(128,128));
+    //iIEBgpsClient->GenerateTN(aEditedFileName, iTNFilename, TSize(32,32));//mikares32
+    
+    DP0_IMAGIC(_L("CIEBgpsController::GenerateTNForEditedImage--"));
+    }
+
+void CIEBgpsController::FilenameArrayCountChanged(const RArray<CImageData*>& aImageDataArray)
+    {
+    iImageDataArray = aImageDataArray;
+    //iIEBgpsControllerObserver.TotalNumberOfImagesChanged(iImageDataArray.Count());
+    }
+
+CImageData* CIEBgpsController::GetImageData(const TInt aIndex)
+    {
+    DP1_IMAGIC(_L("CIEBgpsController::GetImageData %d"), aIndex);
+    
+    return (aIndex <= iImageDataArray.Count()) ? iImageDataArray[aIndex] : NULL;
+    }
+
+void CIEBgpsController::GetFaceCoordinates(const TFileName aTNFileName, RArray<TRect>& aFaceCoordinateArray)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::GetFaceCoordinates"));
+    aFaceCoordinateArray.Reset();
+    //iIEBgpsClient->FindFaces(aTNFileName, aFaceCoordinateArray);
+    }
+
+//If background face Detection is still continuing, we have to use GetSingleFaceCoordinates() function to get face coordinates
+void CIEBgpsController::GetSingleFaceCoordinates(TInt aIndex, const TFileName /*aTNFileName*/, RArray<TRect>& aFaceCoordinateArray)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::GetSingleFaceCoordinates++"));
+    
+    if(i128x128TNCreationOn || i512x512TNCreationOn || i32x32TNCreationOn)
+        {
+        iTnCreationCancelled = ETrue;
+        CancelTNGeneration();
+        i128x128TNCreationOn = EFalse;
+        i512x512TNCreationOn = EFalse;
+        i32x32TNCreationOn = EFalse;
+        }
+
+    iSingleFBIndex = aIndex;
+    iSingleFBCoordinateArray = &aFaceCoordinateArray;
+    
+    //If BGPS face Detection was on, we have to stop it first. Othervice we can contiue directly to StartSingleFaceDetection() 
+    if(iBackGroundFaceDetectionOn)
+        {//We just cancel background face Detection, when cancel is complete we get callback to StartSingleFaceDetection()
+        //iIEBgpsClient->CancelFaceDetection();
+        iBackGroundFaceDetectionOn = EFalse;
+        }
+    else
+        {
+        //StartSingleFaceDetection();
+        }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::GetSingleFaceCoordinates--"));
+    }
+
+/* Creating Single Thumbnails for Editing. After editing the image we are 
+ * genereating the thumbnails 128x128 & 640x480 resolution*/
+void CIEBgpsController::CreateSingleTNL()
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::CreateSingleTN++"));
+    
+    if(iLatestCreatedTNSize == ESize128x128)  
+        {
+        //Create and set data to image data item
+        iTmpImageData->SetFileNameL(iSavedFileName);
+        iImageDataArray[iImageIndex]->SetImageReady(EFullSize, ETrue);
+        iImageDataArray[iImageIndex]->SetImageReady(ESize32x32, EFalse);
+        iImageDataArray[iImageIndex]->SetImageReady(ESize512x512, EFalse);
+        iImageDataArray[iImageIndex]->SetImageReady(ESize128x128, ETrue);
+                
+        //Insert new image data to filename array
+        iFileLoader->AddNewImage(iTmpImageData, iImageIndex);
+        iImageDataArray = iFileLoader->GetFileNameArray();
+        //iIEBgpsControllerObserver.TotalNumberOfImagesChanged(iImageDataArray.Count());
+        
+        /*Generating 320x320 Tumbnail path */
+        iIEEngineUtils.GenerateThumbnailFileName(ESize32x32,iSavedFileName,iTNFilename);
+        iIEBgpsControllerObserver.TNGenerationComplete(ESize128x128);
+        
+        iLatestCreatedTNSize = ESize32x32;
+        TSize size;
+
+        TInt w, h;
+        if(iImageDataArray[iImageIndex]->GetAspectRatio() > 1)
+            {//Landscape
+            w=320;
+            h = 320/iImageDataArray[iImageIndex]->GetAspectRatio();
+            if(h%2 != 0)
+                h++;
+            }
+        else//Portrait
+            {
+            h = 320;
+            w = 320 * iImageDataArray[iImageIndex]->GetAspectRatio();
+            if(w%2 != 0)
+                w++;
+            }
+        size.iHeight = h;
+        size.iWidth = w;
+        
+        iTNSize = size;
+        iIEBgpsClient->GenerateTN(iSavedFileName, iTNFilename, size);
+        }
+    
+    else if(iLatestCreatedTNSize == ESize32x32)
+        {
+        iImageDataArray = iFileLoader->GetFileNameArray();
+        iImageDataArray[iImageIndex]->SetImageReady(ESize32x32, ETrue);
+        //iSingleTNGeneration = EFalse;
+        
+        iIEBgpsControllerObserver.TNGenerationComplete(ESize32x32);
+        
+        TSize size;
+        size.iHeight = 512;
+        size.iWidth = 512;
+        
+        iIEEngineUtils.GenerateThumbnailFileName(ESize512x512, iSavedFileName, iTNFilename);
+        
+        iTNSize = size;
+        iIEBgpsClient->GenerateTN(iSavedFileName, iTNFilename, size);
+        
+        iLatestCreatedTNSize = ESize512x512;
+        }
+    
+    //TN creation complete
+    else
+        {
+        iSingleTNGeneration = EFalse;
+        
+        iImageDataArray[iImageIndex]->SetImageReady(ESize512x512, ETrue);
+        
+        //Insert new image data to filename array
+        iFileLoader->ModifyImageData(iTmpImageData, iImageIndex);
+                
+        //Call observer/AppUI class about completing TN creation
+        iIEBgpsControllerObserver.TNGenerationComplete(ENotDefined);
+        }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::CreateSingleTN--"));
+    }
+
+void CIEBgpsController::DeleteCorruptedThumbNailFile(TFileName aFileName)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::DeleteCorruptedThumbNailFile++"));
+    
+    //Checking for if we generated Imgaic TN already from iCorrupted file and delete it
+    //if(aFileName.Find(KPAlbTNFilePath) != KErrNotFound)
+        if(BaflUtils::FileExists(iFileServer, aFileName))
+            {
+            TInt err = BaflUtils::DeleteFile(iFileServer, aFileName);
+            DP2_IMAGIC(_L("CIEBgpsController::DeleteCorruptedThumbNailFile - file found: %S, err:%d"), &aFileName, err);
+            }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::DeleteCorruptedThumbNailFile--"));
+    }
+
+//Finds optimal size for 128x128 TN creation
+void CIEBgpsController::CheckOptimalFileFor128x128TnCreation(TInt aIndex, TFileName& aFileName)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::CheckOptimalFileForTnCreation++"));
+
+    //TFileName tmpName;
+    //iImageDataArray[aIndex]->GetFileName(tmpName, E512x512Thumbnail);
+    if(iImageDataArray[aIndex]->IsImageReady(ESize512x512))
+    //if(BaflUtils::FileExists(iFileServer, tmpName))
+        {
+        iImageDataArray[aIndex]->GetFileName(aFileName, ESize512x512);
+        DP1_IMAGIC(_L("CIEBgpsController::CheckFileNmaesExitst - filename exits: %S"), &aFileName);
+        }
+    else//(iFileNameData[aIndex]->IsImageReady(EOriginalImage))
+        {
+        iImageDataArray[aIndex]->GetFileName(aFileName, EFullSize);
+        DP1_IMAGIC(_L("CIEBgpsController::CheckFileNmaesExitst - filename exits: %S"), &aFileName);
+        }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::CheckOptimalFileForTnCreation--")); 
+    }
+
+//Finds optimal size for 32x32 TN creation
+void CIEBgpsController::CheckOptimalFileFor32x32TnCreation(TInt aIndex, TFileName& aFileName)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::CheckOptimalFileForTnCreation++"));
+    if(iImageDataArray[aIndex]->IsImageReady(ESize128x128))
+        {
+        iImageDataArray[aIndex]->GetFileName(aFileName, ESize128x128);
+        DP1_IMAGIC(_L("CIEBgpsController::CheckFileNmaesExitst - filename exits: %S"), &aFileName);
+        }
+
+/*    else if(iImageDataArray[aIndex]->IsImageReady(E128x96Thumbnail))
+        {
+        iImageDataArray[aIndex]->GetFileName(aFileName, E128x96Thumbnail);
+        DP1_IMAGIC(_L("CIEBgpsController::CheckFileNmaesExitst - filename did not exits: %S"), &aFileName);
+        }*/
+    else if(iImageDataArray[aIndex]->IsImageReady(ESize512x512))
+
+        {
+        iImageDataArray[aIndex]->GetFileName(aFileName, ESize512x512);
+        DP1_IMAGIC(_L("CIEBgpsController::CheckFileNmaesExitst - filename exits: %S"), &aFileName);
+        }
+    else//(iFileNameData[aIndex]->iMG_FileExist)
+        {
+        //DP1_IMAGIC(_L("CIEBgpsController::CheckFileNmaesExitst - filename OK: %S"), &aFilename);
+        iImageDataArray[aIndex]->GetFileName(aFileName, EFullSize);
+        DP1_IMAGIC(_L("CIEBgpsController::CheckFileNmaesExitst - filename exits: %S"), &aFileName);
+        }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::CheckOptimalFileForTnCreation--")); 
+    }
+
+void CIEBgpsController::Generate128x128Thumbnails(TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::Generate128x128Thumbnails++"));
+    //DP1_IMAGIC(_L("CIEBgpsController::Generate128x128Thumbnails - New TN to be created: %S"), &iImageDataArray[aIndex]->iIETN_128x128_Filename);
+    iImageDataArray[aIndex]->GetFileName(iTNFilename, ESize128x128);
+    iImageDataArray[aIndex]->GetFileName(iJpegFilename, EFullSize);
+    CheckOptimalFileFor128x128TnCreation(aIndex,iJpegFilename);
+#ifdef USE_64X64_BITMAP_TN
+    TSize size(64,64);
+#else
+    TSize size(128,128);
+#endif
+    
+    iIEBgpsClient->GenerateTN(iJpegFilename, iTNFilename, size);
+    
+    DP0_IMAGIC(_L("CIEBgpsController::Generate128x128Thumbnails--"));
+    }
+
+void CIEBgpsController::Generate32x32Thumbnails(TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::Generate32x32Thumbnails++"));
+//    DP1_IMAGIC(_L("CIEBgpsController::Generate320x320Thumbnails - New TN to be created: %S"), &iImageDataArray[aIndex]->iIETN_32x32_Filename);
+    iImageDataArray[aIndex]->GetFileName(iTNFilename, ESize32x32);
+    iImageDataArray[aIndex]->GetFileName(iJpegFilename, EFullSize);
+    CheckOptimalFileFor32x32TnCreation(aIndex,iJpegFilename);
+    TSize size(32,32);
+    iIEBgpsClient->GenerateTN(iJpegFilename, iTNFilename, size);
+    
+    DP0_IMAGIC(_L("CIEBgpsController::Generate32x32Thumbnails--"));
+    }
+
+void CIEBgpsController::Generate512x512Thumbnails(TInt aIndex)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::Generate512x512Thumbnails++"));
+    //DP1_IMAGIC(_L("CIEBgpsController::Generate640x480Thumbnails - New TN to be created: %S"), &iImageDataArray[aIndex]->iIETN_512x512_Filename);
+    
+    iImageDataArray[aIndex]->GetFileName(iTNFilename, ESize512x512); 
+    iImageDataArray[aIndex]->GetFileName(iJpegFilename, EFullSize);
+    TSize size(512,512);
+    iIEBgpsClient->GenerateTN(iJpegFilename, iTNFilename, size);
+    
+    DP0_IMAGIC(_L("CIEBgpsController::Generate512x512Thumbnails--"));
+    }
+
+
+/*TReal CIEBgpsController::ReadAspectRatioL(TFileName& aFileName)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::ReadAspectRatio++"));
+
+    CImageDecoder* imageDecoder = NULL;
+    imageDecoder = CImageDecoder::FileNewL(iFileServer, aFileName);
+ 
+    TFrameInfo frameInfo = imageDecoder->FrameInfo();
+    TSize size = frameInfo.iFrameCoordsInPixels.Size();
+    
+    if(imageDecoder)
+        {
+        delete imageDecoder;
+        imageDecoder = NULL;   
+        }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::ReadAspectRatio--"));
+    
+    return (TReal)size.iWidth/(TReal)size.iHeight; 
+
+    }*/
+
+void CIEBgpsController::StartTNCreatorL()
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::StartTNCreator++"));
+    
+    TThumbSize res;
+    if((iTnCreationIndex = FindMissingTN(res)) < 0) {
+        iIEBgpsControllerObserver.TNGenerationComplete(ENotDefined);
+        return;
+    }
+    
+    //start creating thumbnails by calling TN creator
+    //callback when one TN is created is done to CIEBgpsController::ThumbnailGenerationCompleted function
+    if(res == ESize512x512)
+        {
+        i512x512TNCreationOn = ETrue;
+        i128x128TNCreationOn = EFalse;
+        i32x32TNCreationOn = EFalse;
+        Generate512x512Thumbnails(iTnCreationIndex);
+        }
+    else if(res == ESize128x128)
+        {
+        i512x512TNCreationOn = EFalse;
+        i128x128TNCreationOn = ETrue;
+        i32x32TNCreationOn = EFalse;
+        Generate128x128Thumbnails(iTnCreationIndex);
+        }
+    else if(res == ESize32x32)
+        {
+        i512x512TNCreationOn = EFalse;
+        i128x128TNCreationOn = EFalse;
+        i32x32TNCreationOn = ETrue;
+        Generate32x32Thumbnails(iTnCreationIndex);
+        }
+    else
+        {
+        //All TNs were already done
+        iIEBgpsControllerObserver.TNGenerationComplete(ENotDefined);
+        //We complete face Detection here also because if there was no new images added -> no need to start face Detection in BGPS
+        iIEBgpsControllerObserver.FaceDetectionComplete();
+        }
+    
+    DP0_IMAGIC(_L("CIEBgpsController::StartTNCreator--"));
+    }
+
+//Returns index of first missing TN from any TN size
+TInt CIEBgpsController::FindMissingTN(TThumbSize& aRes)
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::FindMissingTN++"));
+    
+    TInt currentIndex = iIEBgpsControllerObserver.GetSelectedImageIndex();
+    CImageData* gridData = iIEBgpsControllerObserver.GetImageData(currentIndex);
+    
+    TInt tnIndex = -1;
+    
+    for(TInt i = 0; i<iImageDataArray.Count(); i++)
+        {
+        // Check to positive and negative direction from current picture
+        for (TInt j=0; j<2; j++)
+            {
+            // Calculate image index
+            tnIndex = currentIndex + (j ? i : -i);
+            
+            // Check that index is valid
+            if (tnIndex < 0 || tnIndex >= iImageDataArray.Count())
+                continue;
+            
+        CImageData* imageData = iIEBgpsControllerObserver.GetImageData(tnIndex);
+        
+        //Mark image as corrupted so we do not try to generate TN or load it
+        if(imageData->iGridData.iCorrupted)
+            {
+            tnIndex = -20/*KErrCorrupt*/;
+            continue;
+            }
+    
+        if(!iImageDataArray[tnIndex]->IsImageReady(ESize512x512))
+            {
+            TFileName filename;
+            iImageDataArray[tnIndex]->GetFileName(filename,ESize512x512);
+            DP1_IMAGIC(_L("CIEBgpsController::FindMissingTN - Filename to be crated: %S"), &filename);
+            aRes = ESize512x512;
+            //break;
+            return tnIndex;
+            }
+        if(!iImageDataArray[tnIndex]->IsImageReady(ESize128x128))
+            {
+            TFileName filename;
+            iImageDataArray[tnIndex]->GetFileName(filename,ESize128x128);
+            DP1_IMAGIC(_L("CIEBgpsController::FindMissingTN - Filename to be crated: %S"), &filename);
+            aRes = ESize128x128;
+            //break;
+            return tnIndex;
+            }
+        if(!iImageDataArray[tnIndex]->IsImageReady(ESize32x32))
+            {
+            TFileName filename;
+            iImageDataArray[tnIndex]->GetFileName(filename,ESize32x32);
+            DP1_IMAGIC(_L("CIEBgpsController::FindMissingTN - Filename to be crated: %S"), &filename);
+            aRes = ESize32x32;
+            //break;
+            return tnIndex;
+            }
+        }
+    }
+    DP0_IMAGIC(_L("CIEBgpsController::FindMissingTN--"));
+    return -1;    
+    }
+
+void CIEBgpsController::CancelTNGeneration()
+    {
+    DP0_IMAGIC(_L("CIEBgpsController::CancelTNGeneration"));
+    
+    iIEBgpsClient->CancelTNGeneration();    
+    }
+
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEBitmapLoader.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,700 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+// Include files
+#include <hal.h> 
+#include "IEBitmapLoader.h"
+#include "IEFileLoader.h"
+#include "IEEngineUtils.h"
+
+_LIT8(KMimeMbm, "image/x-epoc-mbm");
+_LIT8(KMimeJpeg, "image/jpeg");
+
+#define USE_EXIF_TN
+#define USE_EXIF_TN_CROP
+//#define USE_EXIF_TN_EXT_CROP
+
+#ifdef USE_EXIF_TN
+#include <iclextjpegapi.h>  // For CExtJpegDecoder
+#endif
+
+const TInt KMemoryThresholdForSuperZoom = 12*1024;
+
+
+// ============================ MEMBER FUNCTIONS =========================== \\
+
+CIEBitmapLoader* CIEBitmapLoader::NewL(RFs& aFileServer, MBitmapLoaderObserver& aBitmapLoaderObserver, RCriticalSection* aCritical)
+{
+ 	CIEBitmapLoader* self = new (ELeave) CIEBitmapLoader(aFileServer, aBitmapLoaderObserver, aCritical);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CIEBitmapLoader::~CIEBitmapLoader()
+    {
+    DP0_IMAGIC(_L("CIEBitmapLoader::~CIEBitmapLoader++"));
+  	if(iImageDecoder)
+  	    {
+  	    iImageDecoder->Cancel();
+		delete iImageDecoder;
+		iImageDecoder = NULL;	
+        }
+  	
+    if (iExifBitmap)
+        {
+        delete iExifBitmap;
+        iExifBitmap = NULL;
+        }
+#ifdef DECODE_FROM_BUFFER    
+    if(iSourceData) 
+        {
+        delete iSourceData;
+        iSourceData = NULL;
+        }
+#endif
+    DP0_IMAGIC(_L("CIEBitmapLoader::~CIEBitmapLoader--"));
+  	}
+ 
+CIEBitmapLoader::CIEBitmapLoader(RFs& aFileServer, MBitmapLoaderObserver& aBitmapLoaderObserver, RCriticalSection* aCritical)
+    //:CActive(EPriorityLow),    
+    :CActive(EPriorityStandard),
+    //:CActive(EPriorityUserInput),
+    //:CActive(CActive::EPriorityHigh),
+    iFileServer(aFileServer), 
+    iBitmapLoaderObserver(aBitmapLoaderObserver),
+#ifdef DECODE_FROM_BUFFER    
+    iSourceData(NULL), 
+#endif        
+    iCritical(aCritical)
+    {
+    }
+
+void CIEBitmapLoader::ConstructL()
+    {
+	CActiveScheduler::Add(this);
+	iExifTn = NULL;
+	iImageDecoder = NULL;
+	iImageArrayMode = EImages;
+	iOutputBitmap = NULL;
+	iExifBitmap = NULL;
+#ifdef GET_DECODER_UID
+	decoderUid = CIEEngineUtils::GetImageDecoderUid();	
+#else
+	decoderUid = KNullUid;
+#endif
+    }
+
+void CIEBitmapLoader::CropImageL(CFbsBitmap* aOutput, CFbsBitmap* aInput) const
+    {
+    const TInt KMaxScanLine = 320 * 3;
+    TSize inputSize = aInput->SizeInPixels();
+    TSize outputSize = aOutput->SizeInPixels();
+    TDisplayMode mode = aOutput->DisplayMode();
+    
+    // need to have same display mode and output cannot be bigger
+    if (mode != aInput->DisplayMode() || 
+        outputSize.iWidth > inputSize.iWidth ||
+        outputSize.iHeight > inputSize.iHeight)
+        User::Leave(KErrNotSupported);
+
+    TInt len = CFbsBitmap::ScanLineLength(outputSize.iWidth, mode);
+    TBuf8<KMaxScanLine> buf;
+    if (len > KMaxScanLine)
+        {
+        User::Leave(KErrOverflow);
+        }
+    
+    TPoint point((inputSize.iWidth - outputSize.iWidth + 1) / 2,
+                 (inputSize.iHeight - outputSize.iHeight + 1) / 2);
+    for (TInt i = 0;i < outputSize.iHeight;i++, point.iY++)
+        {
+        aInput->GetScanLine(buf, point, outputSize.iWidth, mode);
+        aOutput->SetScanLine(buf, i);
+        }
+    }
+
+void CIEBitmapLoader::RunL()
+    {
+    DP0_IMAGIC(_L("CIEBitmapLoader::RunL++"));
+    
+    SetPriority(EPriorityStandard);
+    iThumbRes = ENotDefined;
+	TInt error = iStatus.Int();
+	
+	DP1_IMAGIC(_L("CIEBitmapLoader::RunL - Error: %d"),error);
+	
+	if(iImageDecoder)
+	    {
+        delete iImageDecoder;
+        iImageDecoder = NULL;   
+	    }
+	
+#ifdef DECODE_FROM_BUFFER    
+    if(iSourceData) 
+        {
+        delete iSourceData;
+        iSourceData = NULL;
+        }
+#endif
+	
+#ifdef USE_EXIF_TN
+    if (iExifTn)
+        {
+        delete iExifTn;
+        iExifTn = NULL;
+        }   
+	
+	if(iUseExifTn && iImageData && error == KErrNone) 
+	    {
+	    iImageData->SetImageReady(EExifThumb, ETrue);
+	    
+	    // Crop exif thumbnail
+	    if (iExifBitmap && iOutputBitmap)
+	        {
+	        TRAP(error, CropImageL(iOutputBitmap, iExifBitmap));
+	        }
+	    }
+
+	if (iExifBitmap)
+	    {
+	    delete iExifBitmap;
+	    iExifBitmap = NULL;
+	    }
+	
+    iOutputBitmap = NULL;
+#endif
+    
+	iBitmapLoaderObserver.BitmapsLoadedL(error);
+	
+	DP0_IMAGIC(_L("CIEBitmapLoader::RunL--"));
+    }
+
+void CIEBitmapLoader::DoCancel()
+    {
+    }
+
+TInt CIEBitmapLoader::RunError(TInt aError)
+    {
+    DP1_IMAGIC(_L("CIEBitmapLoader::RunError - Error: %d"),aError);
+    
+    return KErrNone;
+    }
+
+void CIEBitmapLoader::GetOneBitmapL(CImageData* aImageData, CFbsBitmap* aBitmap, TThumbSize aThumbRes)
+    {
+    DP0_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL++"));
+    DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - TN res: %d"), aThumbRes);
+
+    ASSERT(iImageDecoder == NULL);    
+    
+    iThumbRes = aThumbRes;
+    TBool thumbnailExists = ETrue;
+    //TBool isFileJpg = ETrue;
+    iUseExifTn = EFalse;
+    iImageData = aImageData;
+    iOutputBitmap = aBitmap;
+    
+#ifdef USE_EXIF_TN    
+    CExtJpegDecoder* extImageDecoder = NULL;
+#endif    
+    
+    TFileName fileName;
+    if(aThumbRes == EFullSize)
+        {
+        if(iImageData->IsImageReady(EFullSize))
+            {
+            //SetPriority(EPriorityUserInput);
+            iImageData->GetFileName(fileName, EFullSize);
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+            }
+        else
+            {
+            //If TN is not ready we just return
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - TN res: %d, not found"), aThumbRes);
+            thumbnailExists = EFalse;
+            //iBitmapLoaderObserver.BitmapsLoadedL(KErrNotFound);
+            User::Leave(KErrNotFound);
+            return;
+            }
+        }
+    else if(aThumbRes == ESize128x128)
+        {
+#ifdef USE_64X64_BITMAP_TN
+        //isFileJpg = EFalse;
+        iImageData->GetFileName(fileName, ESize128x128);
+        DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+        TInt error = aBitmap->Load(fileName);
+        if (error == KErrNone)
+            {
+            SetPriority(EPriorityUserInput);
+            SetActive();
+            TRequestStatus* status = &iStatus;
+            User::RequestComplete(status, KErrNone);
+            return;
+            }
+        
+#ifdef USE_EXIF_TN
+        else if(iImageData->IsImageReady(EFullSize))
+            {
+            iUseExifTn = ETrue;
+            iImageData->GetFileName(fileName, EFullSize);
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+            }
+#endif
+        else
+            {
+            //If TN is not ready we just return
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - TN res: %d, not found"), aThumbRes);
+            thumbnailExists = EFalse;     
+            iImageData->SetImageReady(EExifThumb, EFalse);
+            User::Leave(KErrNotFound);
+            return;
+            }
+#else
+        if(iImageData->IsImageReady(ESize128x128))
+            {
+            SetPriority(EPriorityUserInput);
+            //isFileJpg = EFalse;
+            iImageData->GetFileName(fileName, ESize128x128);
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+            }
+#ifdef USE_EXIF_TN
+        //else if(iImageData->IsImageReady((TThumbSize)(EFullSize|EExifThumb)))
+        else if(iImageData->IsImageReady(EExifThumb))
+            {
+            SetPriority(EPriorityUserInput);
+            iUseExifTn = ETrue;
+            iImageData->GetFileName(fileName, EFullSize);
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+            }
+#endif
+        else
+            {
+            //If TN is not ready we just return
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - TN res: %d, not found"), aThumbRes);
+            
+            thumbnailExists = EFalse;
+            iImageData->SetImageReady(EExifThumb, EFalse);
+            //iBitmapLoaderObserver.BitmapsLoadedL(KErrNotFound);
+            User::Leave(KErrNotFound);
+            return;
+            }
+#endif
+        }
+    
+    else if(aThumbRes == ESize512x512)
+        {
+        if(iImageData->IsImageReady(ESize512x512))
+            {
+            iImageData->GetFileName(fileName, ESize512x512);
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+            }
+        else
+            {
+            //If TN is not ready we just return
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - TN res: %d, not found"), aThumbRes);
+            thumbnailExists = EFalse;
+            iImageData->SetImageReady(EExifThumb, EFalse);
+            User::Leave(KErrNotFound);
+            return;
+            }
+        }
+    else if(aThumbRes == ESize32x32)
+        {
+        if(iImageData->IsImageReady(ESize32x32))
+            {
+            //isFileJpg = EFalse;
+            iImageData->GetFileName(fileName, ESize32x32);
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+            TInt error = aBitmap->Load(fileName);
+            if (error == KErrNone)
+                {
+                SetPriority(EPriorityUserInput);
+                SetActive();
+                TRequestStatus* status = &iStatus;
+                User::RequestComplete(status, KErrNone);
+                return;
+                }
+            }
+#ifdef USE_EXIF_TN
+        else if(iImageData->IsImageReady(EFullSize))
+            {
+            iUseExifTn = ETrue;
+            iImageData->GetFileName(fileName, EFullSize);
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - filename: %S"), &fileName);
+            }
+#endif
+        else
+            {
+            //If TN is not ready we just return
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - TN res: %d, not found"), aThumbRes);
+            thumbnailExists = EFalse;     
+            iImageData->SetImageReady(EExifThumb, EFalse);
+            User::Leave(KErrNotFound);
+            return;
+            }
+        }
+            
+    if(thumbnailExists)
+        {
+        TInt error = KErrNone;
+        
+#ifdef USE_EXIF_TN
+        if (iUseExifTn)
+            {
+            ASSERT(iExifTn == NULL);
+            TRAP(error, iExifTn = CIEEngineUtils::ReadExifThumbnailL(iFileServer, fileName));
+        
+            DP0_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - create decoder"));
+            if (error == KErrNone)
+                {
+                DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL data size: %d"), iExifTn->Length());
+                TRAP(error, extImageDecoder = CExtJpegDecoder::DataNewL(iFileServer, *iExifTn, /*KMimeJpeg,*/ CImageDecoder::EOptionNone));
+                iImageDecoder = extImageDecoder;
+                }
+            else
+                {
+                DP0_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - no exif thumb"));
+                iImageData->SetImageReady(EExifThumb, EFalse);
+                }
+
+            DP2_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - Image exif thumb decoder - TN res: %d, error: %d"), aThumbRes, error);
+            }
+        else
+#endif
+            {
+            DP0_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - create decoder"));
+            /*CExtJpegDecoder * extImageDecoder;
+            TRAP(error, iImageDecoder = extImageDecoder = CExtJpegDecoder::FileNewL(
+                    CExtJpegDecoder::EHwImplementation,
+                    iFileServer, 
+                    fileName,
+                    CImageDecoder::EPreferFastDecode));*/
+#ifdef DECODE_FROM_BUFFER    
+            if(iSourceData) 
+                {
+                delete iSourceData;
+                iSourceData = NULL;
+                }
+            
+            RFile jpgFile;
+            TInt fileSize;
+            
+            User::LeaveIfError(jpgFile.Open(iFileServer, fileName, EFileRead));
+            jpgFile.Size(fileSize);
+            iSourceData = HBufC8::NewL(fileSize);
+            
+            TPtr8 buffer = iSourceData->Des();
+            
+            jpgFile.Read(buffer, fileSize);
+            
+            jpgFile.Close();
+            
+            iImageDecoder = CImageDecoder::DataNewL(
+                    iFileServer, 
+                    *iSourceData, 
+                    //CImageDecoder::EOptionNone,
+                    CImageDecoder::TOptions(CImageDecoder::EPreferFastDecode|CImageDecoder::EOptionAlwaysThread),
+                    KNullUid, 
+                    KNullUid, 
+                    decoderUid);
+#else
+            TRAP(error, iImageDecoder = CImageDecoder::FileNewL(
+                    iFileServer, 
+                    fileName,
+                    //CImageDecoder::EPreferFastDecode,
+                    CImageDecoder::TOptions(CImageDecoder::EPreferFastDecode|CImageDecoder::EOptionAlwaysThread),
+                    KNullUid,
+                    KNullUid,
+                    decoderUid));
+#endif
+            }
+
+        if(error != KErrNone)
+            {
+            DP2_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - Image Decoder - TN res: %d, error: %d"), aThumbRes, error);
+            delete iImageDecoder;
+            iImageDecoder = NULL; 
+
+#ifdef USE_EXIF_TN
+            if (iExifTn)
+                {
+                delete iExifTn;
+                iExifTn = NULL;
+                }
+#endif
+//            iBitmapLoaderObserver.BitmapsLoadedL(error);
+            User::Leave(error);
+            return;
+            }
+        
+        TFrameInfo frameInfo = iImageDecoder->FrameInfo();
+        if(aThumbRes == ESize128x128)
+            iImageDecoder->SetDecoderThreadPriority(/*EPriorityNormal*/EPriorityMuchMore);
+        else
+            iImageDecoder->SetDecoderThreadPriority(EPriorityLess);
+        
+        
+#ifdef _IMAGIC_DEBUG
+        TInt mem = 0;
+        TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+#endif
+        DP0_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - #1"));        
+        TSize frameSize = frameInfo.iFrameCoordsInPixels.Size();
+        //If we are loading full resolution image, we have to create smaller target bitmap 
+        //to save memory and to improve speed of further image processing
+        if(aThumbRes == EFullSize)
+            {
+            TInt mem = 0;
+            TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+            if(mem < KMemoryThresholdForSuperZoom*1024)
+                {
+                //User::Leave(KErrNoMemory);
+#ifdef USE_OOM            	
+                ROomMonitorSession oomMonitor;
+                oomMonitor.Connect();
+                TInt errorCode = oomMonitor.RequestFreeMemory( 1024*KMemoryThresholdForSuperZoom );
+                
+                if ( errorCode != KErrNone )
+                    {
+                    // try one more time 
+                    errorCode = oomMonitor.RequestFreeMemory( 1024*KMemoryThresholdForSuperZoom );
+                    }
+                oomMonitor.Close();
+#endif                
+                }
+                
+            
+            //TSize tgtSize(1024, 1024);
+            //DP0_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - #3"));
+            //TargetDecodingSize(tgtSize, frameSizue);
+            if(frameSize.iHeight >= 1024 || frameSize.iWidth >= 1024)
+                {
+                frameSize.iHeight = Min(1024, iBitmapLoaderObserver.GetGleMaxRes());
+                frameSize.iWidth = Min(1024, iBitmapLoaderObserver.GetGleMaxRes());
+                }
+            else
+                {
+                frameSize.iHeight=512;
+                frameSize.iWidth=512;
+                }
+            }   
+        
+        // Crop thumbnail if aspect ratio is not same as full size image
+#ifdef USE_EXIF_TN
+#ifdef USE_EXIF_TN_CROP
+        if (iUseExifTn)
+            {
+#ifdef USE_EXIF_TN_EXT_CROP              
+            TInt cap;
+            TRAP(error, cap = extImageDecoder->CapabilitiesL());
+            if (error == KErrNone && cap & CExtJpegDecoder::ECapCropping)
+#endif                
+                {
+                TReal aspectRatio = aImageData->GetAspectRatio();
+                TReal thumbAspectRatio = TReal(frameSize.iWidth) / frameSize.iHeight; 
+            
+                // calculate final frame size
+                //if (frameSize.iWidth / frameSize.iHeight != size.iWidth / size.iHeight)
+                if (thumbAspectRatio != aspectRatio)
+                    {
+                    TRect finalFrameRect;
+                    finalFrameRect.SetSize(frameSize);
+                    if (thumbAspectRatio < aspectRatio)
+                        {
+                        TInt h = frameSize.iWidth / aspectRatio;
+                        h += h & 1;
+                        finalFrameRect.SetHeight(h);
+                        }
+                    else
+                        {
+                        TInt w = frameSize.iHeight * aspectRatio;
+                        w += w & 1;
+                        finalFrameRect.SetWidth(w);
+                        }
+                    
+                    finalFrameRect.Move(
+                            (frameSize.iWidth - finalFrameRect.Width() + 1) / 2,
+                            (frameSize.iHeight - finalFrameRect.Height() + 1) / 2);
+#ifdef USE_EXIF_TN_EXT_CROP                    
+                    TRAP(error, extImageDecoder->SetCroppingL(finalFrameRect));
+#else         
+                    // Create temporal bitmap
+                    iExifBitmap = new CFbsBitmap;
+                    if (iExifBitmap == NULL)
+                        error = KErrGeneral;
+                    else
+                        error = iExifBitmap->Create(frameSize, frameInfo.iFrameDisplayMode);
+                    aBitmap = iExifBitmap;                 
+#endif
+                    // Reduce final image size
+                    if (error == KErrNone)
+                        {
+                        frameSize.iWidth = finalFrameRect.Width();
+                        frameSize.iHeight = finalFrameRect.Height();
+                        }                    
+                    }
+                }
+            }
+#endif        
+#endif        
+        
+        if (error == KErrNone)
+            {
+#ifdef USE_RGBA
+            error = iOutputBitmap->Create(frameSize, EColor16MU);
+#else
+            error = iOutputBitmap->Create(frameSize, frameInfo.iFrameDisplayMode);
+#endif
+            }
+        
+        if (error == KErrNone)
+            {
+#ifdef USE_EXIF_TN
+            /*if(iUseExifTn)
+                {
+                TRAP(error, iExifDecoder->Convert(&iStatus, *aBitmap));
+                }
+            else*/
+#endif
+                {
+                TRAP(error, iImageDecoder->Convert(&iStatus, *aBitmap));
+                }
+            }
+        
+        if(error != KErrNone)
+            {
+            DP2_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - Image Decoder convert - TN res: %d, error: %d"), aThumbRes, error);
+            delete iImageDecoder;
+            iImageDecoder = NULL; 
+            //aImageData->iGridData.iCorrupted = ETrue;//mika. added 03.06. maybe not good idea????????
+            User::Leave(error);
+            return;
+            }
+        else
+            {
+            DP1_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL - Decoding started TN res: %d"), aThumbRes);
+            
+            if(!IsActive())
+                SetActive();
+            }
+        }
+    
+    DP0_IMAGIC(_L("CIEBitmapLoader::GetOneBitmapL--"));
+    }
+
+/**
+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 CIEBitmapLoader::LoadImageIntoMemoryLC(const TDesC& aFileName)
+    {
+    RFile file;
+    TInt fileSize = 0;
+
+    // Open the file for decoding
+    User::LeaveIfError(file.Open(iFileServer, aFileName, EFileRead));
+    file.Size(fileSize);    
+
+    //HBufC8* imageInMemory = HBufC8::NewMaxLC(fileSize);
+    HBufC8* imageInMemory = HBufC8::NewMaxL(fileSize);
+    TPtr8 imageInMemoryPtr = imageInMemory->Des();
+    if(file.SubSessionHandle())
+        {
+        User::LeaveIfError(file.Read(imageInMemoryPtr));    
+        }
+        
+    file.Close();
+
+    return imageInMemoryPtr;
+    }*/
+
+void CIEBitmapLoader::TargetDecodingSize(TSize aTgtSize, TSize& aSrcSize)
+    {
+    DP0_IMAGIC(_L("CIEBitmapLoader::TargetDecodingSize++"));
+    
+    DP2_IMAGIC(_L("CIEBitmapLoader::TargetDecodingSize - Tgt size.iHeigth: %d, Tgt size.iWidth: %d"),aTgtSize.iHeight, aTgtSize.iWidth);
+    DP2_IMAGIC(_L("CIEBitmapLoader::TargetDecodingSize - Src size.iHeigth: %d, Src size.iWidth: %d"),aSrcSize.iHeight, aSrcSize.iWidth);
+    
+    // up to 32 times downscale in scaler
+    for (TInt i = 0;i < 5;i++)
+        {
+        if (aSrcSize.iWidth < aTgtSize.iWidth * 2 ||
+            aSrcSize.iHeight < aTgtSize.iHeight * 2) 
+            {
+            break;
+            }
+            
+            aSrcSize.iWidth >>= 1;
+            aSrcSize.iHeight >>= 1;
+        }
+    
+    // Check that we do not create odd resolution size thumbnail
+    if(aSrcSize.iHeight & 1)
+        aSrcSize.iHeight++;
+    if(aSrcSize.iWidth & 1)
+        aSrcSize.iWidth++;
+    
+    DP2_IMAGIC(_L("CIEBitmapLoader::TargetDecodingSize - Src size.iHeigth: %d, Src size.iWidth: %d"),aSrcSize.iHeight, aSrcSize.iWidth);
+     
+    DP0_IMAGIC((_L("CIEBitmapLoader::TargetDecodingSize--")));
+    }
+
+
+void CIEBitmapLoader::CancelFullSizeLoading()
+    {
+    //Cancel only if full resolution loading was on
+    DP0_IMAGIC(_L("CIEBitmapLoader::CancelFullSizeLoading++"));
+    if(iThumbRes == EFullSize)
+        {
+        DP0_IMAGIC(_L("CIEBitmapLoader::CancelFullSizeLoading 1"));        
+        if(iImageDecoder)
+            {
+            iImageDecoder->Cancel();
+            delete iImageDecoder;
+            iImageDecoder = NULL;   
+            }
+        DP0_IMAGIC(_L("CIEBitmapLoader::CancelFullSizeLoading 2"));
+        if(IsActive())
+            {
+            Cancel();
+            DP0_IMAGIC(_L("CIEBitmapLoader::CancelFullSizeLoading 21"));
+            iBitmapLoaderObserver.BitmapsLoadedL(KErrCancel);
+            }
+#ifdef DECODE_FROM_BUFFER    
+        if(iSourceData) 
+            {
+            DP0_IMAGIC(_L("CIEBitmapLoader::CancelFullSizeLoading 3"));
+            delete iSourceData;
+            iSourceData = NULL;
+            }
+#endif
+        DP0_IMAGIC(_L("CIEBitmapLoader::CancelFullSizeLoading 4"));
+        }
+        DP0_IMAGIC(_L("CIEBitmapLoader::CancelFullSizeLoading--"));
+    }
+
+void CIEBitmapLoader::SetImageDataMode(TImageArrayMode aMode)
+    {
+    iImageArrayMode = aMode;
+    }
+
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEEngineImp.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,616 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include <e32uid.h>
+#include <BAUTILS.H>
+#include <IEImageProcessing.h>//thumbnail client
+#include "IEEngineImp.h"
+#ifdef IMAGE_EDITOR
+#include "IEEditor.h"
+#endif
+#include "IEFileLoader.h"
+#include "IEImageList.h"
+#include "ImageMonitorAO.h"
+#include "IEImageList.h"
+#include "IEEngineUtils.h"
+
+
+// ============================ MEMBER FUNCTIONS =========================== //
+
+EXPORT_C CIEEngine* CIEEngine::NewL(MIEEngineObserver& aObserver)
+{
+    DP0_IMAGIC(_L("CIEEngine::NewL"));
+	return CIEEngineImp::NewL(aObserver);
+}
+
+EXPORT_C CIEEngine::~CIEEngine()
+    {
+    
+    }
+
+CIEEngineImp* CIEEngineImp::NewL(MIEEngineObserver& aObserver)
+{
+    DP0_IMAGIC(_L("CIEEngine::NewL"));
+	CIEEngineImp* self = new (ELeave) CIEEngineImp(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CIEEngineImp::~CIEEngineImp()
+    {
+    DP0_IMAGIC(_L("CIEEngine::~CIEEngineImp++"));
+
+#if 0
+   if(iIEImageProcessing)
+       {
+       delete iIEImageProcessing;
+       iIEImageProcessing = NULL;
+       }
+#endif
+
+#ifdef IMAGE_EDITOR
+     if(iImageEditor)
+	 {
+         DP0_IMAGIC(_L("CIEEngine::~CIEEngineImp - delete iImageEditor"));
+         delete iImageEditor;
+         iImageEditor = NULL;
+	 }
+#endif
+   
+	 if(iFileLoader)
+	     {
+	     DP0_IMAGIC(_L("CIEEngine::~CIEEngineImp - delete iFileLoader"));
+	     delete iFileLoader;
+	     iFileLoader = NULL;
+	     }
+	
+	 if(iBitmapLoader)
+	     {
+	     DP0_IMAGIC(_L("CIEEngine::~CIEEngineImp - delete iBitmapLoader"));
+	     iBitmapLoader->CancelFullSizeLoading();
+	     DP0_IMAGIC(_L("CIEEngine::~CIEEngineImp - delete iBitmapLoader 2"));
+	     delete iBitmapLoader;
+	     iBitmapLoader = NULL;
+	     }
+	
+	 if(iIEBgpsController)
+	     {
+	     DP0_IMAGIC(_L("CIEEngine::~CIEEngineImp - delete iIEBgpsController"));
+	     delete iIEBgpsController;
+	     iIEBgpsController = NULL;
+	     }
+#ifdef _ACCELEROMETER_SUPPORTED_
+	 if(iSensorMonitor)
+	     {
+	     iSensorMonitor->StopMonitoring();
+	     delete iSensorMonitor;
+	     iSensorMonitor = NULL;
+	     }
+#endif //_ACCELEROMETER_SUPPORTED_
+
+	iFileServer.Close();
+	iCritical.Close();
+	
+	DP0_IMAGIC(_L("CIEEngine::~CIEEngineImp--"));
+    }
+
+CIEEngineImp::CIEEngineImp(MIEEngineObserver& aObserver) :
+    iEngineObserver(aObserver),
+    iIEEngineUtils(iFileServer)
+    {
+    }
+
+void CIEEngineImp::ConstructL()
+    {
+    DP0_IMAGIC(_L("CIEEngine::ConstructL++"));
+    
+    iCritical.CreateLocal();
+    
+    User::LeaveIfError(iFileServer.Connect());
+	
+	/*Creating Engine Utility class pointer */
+	iCurrentEditingMode = EEditModeNone;
+	iEditingMode = EEditModeNone;
+	iImageEdited = EFalse;
+	iImageArrayMode = EImages;
+	iAllFilesScanned = EFalse;
+	iPrevDeviceOrientation = EOrientationDisplayLeftUp;
+	
+
+	TInt err = KErrNone;
+	//Create Bitmap loader
+	iBitmapLoader = CIEBitmapLoader::NewL(iFileServer, *this, &iCritical);
+	//Create BGPS controller
+	iIEBgpsController = CIEBgpsController::NewL(iFileServer, *this, iIEEngineUtils, &iCritical);
+	//Create Fileloader
+	TRAP(err, iFileLoader = CIEFileLoader::NewL(iFileServer, this, &iCritical));
+    if(err != KErrNone)
+        {
+        DP1_IMAGIC(_L("CIEEngine::ConstructL - Error creating file loader, err: %d"),err);
+        User::Leave(err);
+        }
+    
+#ifdef _ACCELEROMETER_SUPPORTED_
+    iDeviceOrientation = EOrientationDisplayLeftUp;
+    err = KErrNone;
+    TRAP(err, iSensorMonitor = CIESensorMonitor::NewL(*this));
+    DP1_IMAGIC(_L("CIEEngine::ConstructL - iSensorMonitor error: %d"), err);
+    if(err == KErrNone)
+        {
+        DP0_IMAGIC(_L("CIEEngine::ConstructL - iSensorMonitor->StartMonitoring()"));
+        iSensorMonitor->StartMonitoring();
+        }
+    else
+        {
+        iSensorMonitor = NULL;
+        }
+
+#endif
+
+    iIEBgpsController->SetFileLoader(iFileLoader); 
+   
+    DP0_IMAGIC(_L("CIEEngine::ConstructL--"));
+}
+
+void CIEEngineImp::SetDBChanged(CImageData* aImageData)
+    {
+    TFileName filename;
+    aImageData->GetFileName(filename, EFullSize);
+    iFileLoader->GetImageList().SetChanged(filename); 
+    }
+
+CIEImageList& CIEEngineImp::GetImageList()
+    {
+    return iFileLoader->GetImageList();
+    }
+
+void CIEEngineImp::AppUIReady()
+    {
+    DP0_IMAGIC(_L("CIEEngine::AppUIReady"));
+    
+    //Create ImageProcessing
+    iIEBgpsController->CreateImageProcessing();
+    }
+
+void CIEEngineImp::CancelFullSizeLoading()
+    {
+    DP0_IMAGIC(_L("CIEEngine::CancelLoading"));
+    
+    iBitmapLoader->CancelFullSizeLoading();
+    }
+
+
+void CIEEngineImp::SetImageDataMode(TImageArrayMode aMode)
+    {
+    iImageArrayMode = aMode;
+    
+    iBitmapLoader->SetImageDataMode(aMode);
+    }
+
+MIEEngineObserver& CIEEngineImp::GetObserver() 
+    {
+    return iEngineObserver;
+    }
+
+void CIEEngineImp::TNGenerationComplete(TThumbSize aTNRes)
+    {
+    DP0_IMAGIC(_L("CIEEngine::TNGenerationComplete++"));
+    
+    iEngineObserver.TNCreationCompleteL(aTNRes);
+    
+    DP0_IMAGIC(_L("CIEEngine::TNGenerationComplete--"));
+    }
+
+void CIEEngineImp::SingleTNGenerationComplete(TInt aIndex, TThumbSize aTNRes)
+    {
+    DP0_IMAGIC(_L("CIEEngine::TNGenerationComplete++"));
+    
+    iEngineObserver.SingleTNCreationCompletedL(aIndex, aTNRes);
+    
+    DP0_IMAGIC(_L("CIEEngine::TNGenerationComplete--"));
+    }
+
+void CIEEngineImp::FaceDetectionComplete()
+    {
+    DP0_IMAGIC(_L("CIEEngine::FaceDetectionComplete"));
+    iEngineObserver.FaceDetectionComplete();
+    }
+
+void CIEEngineImp::SingleFaceDetectionComplete()
+    {
+    DP0_IMAGIC(_L("CIEEngine::SingleFaceDetectionComplete"));
+    
+    iEngineObserver.SingleFaceDetectionComplete();
+    }
+
+void CIEEngineImp::AllFilesAddedToFilenameArrayL()
+    {
+    DP0_IMAGIC(_L("CIEEngine::AllFilesAddedToFilenameArrayL"));
+    
+    iIEBgpsController->AllFilesAddedToFilenameArrayL();
+    iEngineObserver.AllFilesScanned();
+    iAllFilesScanned = ETrue;
+    }
+
+CIEEngineUtils * CIEEngineImp::GetEngineUtils()
+    {
+    DP0_IMAGIC(_L("CIEEngine::GetEngineUtils"));
+    
+    return &iIEEngineUtils;
+    }
+
+CIEFileLoader* CIEEngineImp::GetFileLoader()
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::GetFileLoader"));
+    
+    return iFileLoader;
+    }
+
+void CIEEngineImp::BitmapsLoadedL(TInt aError)
+{
+    DP0_IMAGIC(_L("CIEEngineImp::BitmapsLoaded"));
+    
+	iEngineObserver.ImagesLoadedL(aError);
+}
+
+TBool CIEEngineImp::IsScanningFiles() const
+    {
+    return !iAllFilesScanned;
+    }
+
+void CIEEngineImp::GetTotalNumOfImages(TInt& aNumOfImages, TInt& aNumOfFaces)
+    {
+    //DP0_IMAGIC(_L("CIEEngineImp::GetTotalNumOfImages"));
+    
+    iFileLoader->GetTotalNumOfImages(aNumOfImages, aNumOfFaces);
+    }
+
+TInt CIEEngineImp::GetTotalNumOfImages()
+    {
+    //DP0_IMAGIC(_L("CIEEngineImp::GetTotalNumOfImages"));
+    //return iFileLoader->GetTotalNumOfImages();
+    
+    TInt numOfImages, numOfFaces;
+    if(iImageArrayMode == EImages)
+        {
+        iFileLoader->GetTotalNumOfImages(numOfImages, numOfFaces);
+        return numOfImages;
+        }
+        
+    else if(iImageArrayMode == EFaces)
+        {
+        iFileLoader->GetTotalNumOfImages(numOfImages, numOfFaces);
+        return numOfFaces;
+        }
+    else
+        return 0;
+    
+    }
+
+TInt CIEEngineImp::DeleteFile(TInt aIndex)
+    {  
+    DP0_IMAGIC(_L("CIEEngineImp::DeleteFile++"));
+    TInt err;
+    if(iImageArrayMode == EImages)
+        {
+        err = iFileLoader->DeleteFile(aIndex);
+        iIEBgpsController->FilenameArrayCountChanged(iFileLoader->GetFileNameArray());
+        }
+    else//EFaces
+        {
+        err = iFileLoader->DeleteFaceFile(aIndex);
+        TInt numOfImages = 0;
+        TInt numOfFaces = 0;
+        iFileLoader->GetUpdatedNumOfImages(numOfImages, numOfFaces);
+        }
+    DP1_IMAGIC(_L("CIEEngineImp::DeleteFile-- %d"), err);
+    return err;
+    }
+
+TInt CIEEngineImp::GetImageName(const TInt aIndex, TFileName& aFileName, TThumbSize aThumbRes)
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::GetImageName"));
+    
+    TInt error = KErrNone;
+    TRAP(error, iFileLoader->GetFileNameL(aIndex, aFileName, aThumbRes));
+    return error;
+    }
+
+void CIEEngineImp::GetBitmapL(CImageData* aImageData, CFbsBitmap* aBitmap, TThumbSize aThumbRes)
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::GetBitmapL"));
+    
+    iBitmapLoader->GetOneBitmapL(aImageData, aBitmap, aThumbRes);
+    }
+
+void CIEEngineImp::GetFileNameL(const TInt aIndex, TThumbSize aThumbRes, TFileName& aFilename)
+    {
+    iFileLoader->GetFileNameL(aIndex, aFilename, aThumbRes);
+    }
+
+void CIEEngineImp::StopTNGeneration(TInt& /*aValue*/)
+    {
+    //iIEBgpsController->StopTNGeneration(aValue);
+    iIEBgpsController->CancelTNGeneration();
+    }
+
+TReal CIEEngineImp::GetAspectRatio(TInt aIndex)
+    {
+    return iIEBgpsController->GetAspectRatio(aIndex);
+    }
+
+TReal CIEEngineImp::GetFacesAspectRatio(TInt aIndex)
+    {
+    return iIEBgpsController->GetFacesAspectRatio(aIndex);
+    }
+
+//This function is called in editing mode only when we did not have 320x320 TN ready
+void CIEEngineImp::GenerateThumbNailL(const TDes &aOrgFile, TThumbSize aTNResolution)
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::GenerateThumbNail++"));
+    
+    iIEBgpsController->GenerateThumbNailL(aOrgFile, aTNResolution);
+
+    DP0_IMAGIC(_L("CIEEngineImp::GenerateThumbNail--"));
+    }
+
+//This is used to get face coords from already processed image
+void CIEEngineImp::GetFaceCoordinates(const TFileName aTNFileName, RArray<TRect>& aFaceCoordinateArray)
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::GetFaceCoordinates"));
+    aFaceCoordinateArray.Reset();
+    //iIEBgpsController->GetFaceCoordinates(aTNFileName, aFaceCoordinateArray);
+    }
+
+void CIEEngineImp::AddImageToFaceNameArray()
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::AddImageToFaceNameArray++"));
+    
+    //Tarkista etta jos kuva on jo olemassa sita ei lisata enaa uudelleen 
+    
+    for(TInt i=0; i<iCroppedFilenames.Count(); i++)
+        {
+        //Add newly cropped filenames to filename array
+        CImageData* tmpImageData = CImageData::NewL(EFullSize);
+        
+        TRAP_IGNORE(tmpImageData->SetFileNameL(iCroppedFilenames[i]));
+        
+        DP1_IMAGIC(_L("CIEEngineImp::FaceCroppingComplete - Add face, Filename: %S"), &iCroppedFilenames[i] );
+        
+        TSize size;
+        TRAPD(err, iIEEngineUtils.GetImageSizeL(iCroppedFilenames[i], size));
+        if (err == KErrNone)
+            tmpImageData->SetSize(size);
+        
+        iFileLoader->AddNewFaceCropImage(tmpImageData, 0);    
+        }
+    
+    TInt numOfImages, numOfFaces;
+    iFileLoader->GetUpdatedNumOfImages(numOfImages, numOfFaces);
+    
+    //TotalNumberOfFaceImagesChanged(numOfFaces);
+    
+    //Empty data from array after using it
+    TInt count = iCroppedFilenames.Count();
+    for(TInt i=0; i<count; i++)
+        {
+        iCroppedFilenames.Remove(0);
+        }
+    //iFileLoader->StopFileSystemMonitoring();
+    
+    DP0_IMAGIC(_L("CIEEngineImp::AddImageToFaceNameArray--"));
+    }
+
+//If background face Detection is still continuing, we have to use GetSingleFaceCoordinates() function to get face coordinates
+void CIEEngineImp::GetSingleFaceCoordinates(TInt aIndex, const TFileName aTNFileName, RArray<TRect>& aFaceCoordinateArray)
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::GetSingleFaceCoordinates"));
+    
+    iIEBgpsController->GetSingleFaceCoordinates(aIndex, aTNFileName, aFaceCoordinateArray);
+    }
+
+
+CImageData* CIEEngineImp::GetImageData(TInt aIndex/*, TImageArrayMode aMode*/)
+    {
+    return iFileLoader->GetImageData(aIndex/*, aMode*/);
+    }
+
+void CIEEngineImp::SetImageData(TInt aIndex, CImageData* aGridData)
+    {
+    iFileLoader->SetImageData(aIndex, aGridData);
+    }
+
+TInt CIEEngineImp::GetSelectedImageIndex()
+    {
+    return iEngineObserver.GetImageIndex();
+    }
+    
+
+
+#ifdef _ACCELEROMETER_SUPPORTED_
+
+void CIEEngineImp::SensorDataAvailable(TImagicDeviceOrientation aOrientation, TBool aValue)
+    {
+    //DP0_IMAGIC(_L("CIEEngineImp::SensorDataAvailable++"));
+    
+    if(iPrevDeviceOrientation == aOrientation)
+        {
+        //DP0_IMAGIC(_L("CIEEngineImp::SensorDataAvailable - Orientation not changed--"));
+        return;
+        }
+
+    iPrevDeviceOrientation = aOrientation;
+    
+    CImageData* currentImage = NULL ; //GetGridData(GetSelectedImageIndex(), EImages);
+    TInt totalImages = GetTotalNumOfImages();
+    
+    switch ( aOrientation )
+        {
+#ifdef _S60_3x_ACCELEROMETER_
+        case EOrientationDisplayDown: // Portrait Up
+#else if _S60_5x_ACCELEROMETER_
+        case TSensrvOrientationData::EOrientationDisplayUp: // Portrait Up
+        //case TSensrvOrientationData::EOrientationDisplayDown: // Portrait Up
+#endif            
+            {               
+            DP0_IMAGIC(_L("CIEEngineImp::SensorDataAvailable - EOrientationDisplayUp"));
+            
+            for ( TInt imageIndex = 0 ; imageIndex < totalImages ; imageIndex++ )
+                {
+                currentImage = GetImageData(imageIndex); 
+                currentImage->iGridData.iTargetRotationAngle = (currentImage->GetOrientation() + 90)%360;
+                
+                TReal targetA = currentImage->iGridData.iTargetRotationAngle;
+                TReal currentA = currentImage->iGridData.iRotationAngle;
+                
+                currentImage->iGridData.iTargetRotationAngle = targetA;
+                
+                }
+            
+            iPrevDeviceOrientation = iDeviceOrientation = EOrientationDisplayDown;
+            break;
+            }
+
+#ifdef _S60_3x_ACCELEROMETER_
+        case EOrientationDisplayLeftUp: // Landscape Up
+#else if _S60_5x_ACCELEROMETER_
+        case TSensrvOrientationData::EOrientationDisplayRightUp: // Landscape Up
+        //case TSensrvOrientationData::EOrientationDisplayLeftUp: // Landscape Up
+#endif            
+                {
+            DP0_IMAGIC(_L("CIEEngineImp::SensorDataAvailable - EOrientationDisplayLeftUp"));
+            
+            for ( TInt imageIndex = 0 ; imageIndex < totalImages ; imageIndex++ )
+                {
+                currentImage = GetImageData(imageIndex); 
+                if ( currentImage->iGridData.iRotationAngle == 270 )
+                    {
+                    currentImage->iGridData.iRotationAngle = -90; // Rotate
+                    }
+                currentImage->iGridData.iTargetRotationAngle = (currentImage->GetOrientation() )%360;
+                
+                TReal targetA = currentImage->iGridData.iTargetRotationAngle;
+                TReal currentA = currentImage->iGridData.iRotationAngle;
+                
+                currentImage->iGridData.iTargetRotationAngle = targetA;
+                }              
+  
+            iPrevDeviceOrientation = iDeviceOrientation = EOrientationDisplayLeftUp;
+            break;
+            }
+
+            default:
+                {
+                DP1_IMAGIC(_L("CIEEngineImp::SensorDataAvailable - Ignored orientation: %d"),aOrientation);
+                //progressBuf.Append( _L( "Unknown orientation" ) );
+                break;
+                }
+            }
+    iEngineObserver.ImageRotated(iDeviceOrientation);
+    
+    DP0_IMAGIC(_L("CIEEngineImp::SensorDataAvailable--"));
+   }
+
+void CIEEngineImp::SetImageRotation(TInt aIndex)
+    {
+    CImageData* currentImage = NULL ; //GetGridData(GetSelectedImageIndex(), EImages);
+    //TInt totalImages = GetTotalNumOfImages();
+    
+    currentImage = GetImageData(aIndex); 
+    
+    TReal targetAngle = (currentImage->GetOrientation())%360;
+    //TReal currentAngle = currentImage->iGridData.iRotationAngle;
+    
+    currentImage->iGridData.iTargetRotationAngle = targetAngle;
+    
+    }
+    
+
+TImagicDeviceOrientation CIEEngineImp::GetDeviceOrientation()
+    {
+    DP1_IMAGIC(_L("CIEEngineImp::GetDeviceOrientation: %d"),iDeviceOrientation);
+    return iDeviceOrientation;
+   }
+
+void CIEEngineImp::SetDeviceOrientation(TImagicDeviceOrientation aOrientation)
+    {
+    DP1_IMAGIC(_L("CIEEngineImp::SetDeviceOrientation: %d"),aOrientation);
+    
+    SensorDataAvailable(aOrientation, EFalse);
+   }
+
+void CIEEngineImp::StartAccSensorMonitoring()
+    {
+    if(iSensorMonitor)
+        {
+        DP0_IMAGIC(_L("CIEEngineImp::StartAccSensorMonitoring"));
+        iSensorMonitor->StartMonitoring();
+        }
+        
+    }
+
+void CIEEngineImp::StopAccSensorMonitoring()
+    {
+    if(iSensorMonitor)
+        {
+        DP0_IMAGIC(_L("CIEEngineImp::StopAccSensorMonitoring"));
+        iSensorMonitor->StopMonitoring();
+        }
+    }
+
+#endif
+
+void CIEEngineImp::Stop()
+    {
+    /*TInt err = KErrNone;
+    StopTNGeneration(err); 
+    StopFaceDetection(err);*/
+    iFileLoader->StopImageFinder();
+    }
+
+TBool CIEEngineImp::IsRunning()
+    {
+    //iIEBgpsController->
+    return (iFileLoader->ImageFinderState() != CIEFileLoader::EImageFinderStopped);
+    //return ETrue;
+    }
+ 
+TBool CIEEngineImp::IsAccelerometerExists()
+    {
+    DP0_IMAGIC(_L("CIEEngineImp::IsAccelerometerExists"));
+    
+#ifdef _S60_3x_ACCELEROMETER_
+#ifdef SENSOR_API_LOAD_DYNAMICALLY
+    DP1_IMAGIC(_L("CIEEngineImp::IsAccelerometerExists - iSensorMonitor exists: %d"),iSensorMonitor);
+    return (iSensorMonitor != NULL);
+#endif
+#endif
+    DP0_IMAGIC(_L("CIEEngineImp::IsAccelerometerExists - iSensorMonitor not exists"));
+    return EFalse;
+    }
+
+TInt CIEEngineImp::GetGleMaxRes()
+    {
+    return iEngineObserver.GetGleMaxRes();
+    }
+
+    
+// EOF
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEFileLoader.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,475 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+
+#include <bautils.h>
+#include <IEBgpsInfo.h>
+
+
+#include "IEEngineImp.h"
+#include "IEFileLoader.h"
+#include "IEImageFinder.h"
+#include "ImageMonitorAO.h"
+
+#ifdef _S60_5x_ACCELEROMETER_
+#include "IESensorMonitor.h"
+#endif
+
+#define IMAGEFINDERMONITORAO
+
+//_LIT(KFacesPath, "ImagicFaces");
+
+
+CIEFileLoader* CIEFileLoader::NewL(
+        RFs& aFileServer, 
+        CIEEngineImp* aEngImp, 
+        RCriticalSection* aCritical/*, TRequestStatus& aStatus*/)
+    {
+    DP0_IMAGIC(_L("CIEFileLoader::NewL++"));
+    
+	CIEFileLoader* self = new (ELeave) CIEFileLoader(aFileServer, aEngImp, aCritical/*, aStatus*/);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	DP0_IMAGIC(_L("CIEFileLoader::NewL--"));
+	return self;
+    }
+
+CIEFileLoader::~CIEFileLoader()
+    {
+    DP0_IMAGIC(_L("CIEFileLoader::~CIEFileLoader++"));
+    
+    // Save database file if needed
+    if (iImageList)
+        TRAP_IGNORE(iImageList->WriteDatabaseL());
+    
+   	DP0_IMAGIC(_L("CIEFileLoader::~CIEFileLoader 1"));
+#ifdef IMAGEFINDERMONITORAO
+   	if(iImageFinderMonitor->IsActive())
+   	    {
+   	    DP0_IMAGIC(_L("CIEFileLoader::~CIEFileLoader 1.1"));
+   	    iImageFinderMonitor->Cancel();
+   	    }
+   	
+   	DP0_IMAGIC(_L("CIEFileLoader::~CIEFileLoader 2"));
+   	delete iImageFinderMonitor;
+   	iImageFinderMonitor = NULL;
+#endif
+   	
+	// The object is created in ThreadEngine CreateThreadsL().
+    // This is done because thread1 needs to cleanup before killing
+    // the thread.
+	iImageFinderThread->Stop();
+	delete iImageFinderThread;
+	iImageFinderThread = NULL;
+	DP0_IMAGIC(_L("CIEFileLoader::~CIEFileLoader 3"));
+
+	for(TInt i = 0;i < iFileNameData.Count();i++)
+	    delete iFileNameData[i];
+	
+    for(TInt i = 0;i < iFaceFilenameData.Count();i++)
+        delete iFaceFilenameData[i];
+        
+    iFileNameData.Reset();
+    iFileNameData.Close();
+    
+    iFaceFilenameData.Reset();
+    iFaceFilenameData.Close();
+    
+    delete iImageList;
+	
+	//delete iFileSystemMonitor;
+	DP0_IMAGIC(_L("CIEFileLoader::~CIEFileLoader--"));
+    }
+
+CIEFileLoader::CIEFileLoader(
+        RFs& aFileServer, 
+        CIEEngineImp* aEngImp, 
+        RCriticalSection* aCritical) :
+        iFileServer(aFileServer),
+        iEngImp(aEngImp),
+        iCritical(aCritical)
+    {
+          
+    }
+
+void CIEFileLoader::ConstructL()
+    {
+    DP0_IMAGIC(_L("CIEFileLoader::ConstructL++"));
+    
+	iCurrentFileIndex = 0;
+	//iJpgFileCountingComplete = EFalse;
+	iImageFinderState = EImageFinderRunning;
+
+	iImageList = CIEImageList::NewL(iFileNameData, this);
+	
+	TFileName rootPath;
+    
+	//iFileSystemMonitor = FileSystemMonitorAO::NewL(iFileServer, this);
+	//iFileSystemMonitor->StartMonitoring();
+#ifdef IMAGEFINDERMONITORAO		
+	iImageFinderMonitor = CImageMonitorAO::NewL(iEngImp);
+	iImageFinderMonitor->iStatus = KRequestPending; 
+	iImageFinderMonitor->ActiveRequest();
+#endif    
+	//Create and start ImageFinder thread
+	iImageFinderThread = CFileFinderThread::NewL(
+	        this, 
+	        iFileNameData, 
+	        iFaceFilenameData, 
+	        iCritical, 
+	        rootPath);
+
+	iImageFinderThread->StartL();
+	
+	iMainThreadId = RThread().Id();
+	
+	DP0_IMAGIC(_L("CIEFileLoader::ConstructL--"));
+}
+
+CIEFileLoader::TImageFinderState CIEFileLoader::ImageFinderState() const
+    {
+    return iImageFinderState;
+    //return (iImageFinderThread != NULL);
+    }
+
+CIEImageList& CIEFileLoader::GetImageList()
+    {
+    return *iImageList;
+    }
+
+void CIEFileLoader::StopImageFinder()
+    {
+    DP0_IMAGIC(_L("CIEFileLoader::Stop++"));
+    if (iImageFinderState == EImageFinderRunning)
+        iImageFinderState = EImageFinderStopping;
+    DP0_IMAGIC(_L("CIEFileLoader::Stop--"));
+    }
+
+void CIEFileLoader::ImageFinderStopped()
+    {
+    iImageFinderState = EImageFinderStopped;
+    }
+
+void CIEFileLoader::ImageListChanged(TInt aIndex, TBool aAdded) 
+    {
+    iEngImp->GetObserver().ImageListChanged(aIndex, aAdded);
+    }
+
+/* Added new image */
+void CIEFileLoader::AddNewImage(CImageData* aTmpImageData, TInt aImageIndex)
+    {
+    //Insert new image data to filename array
+    iFileNameData.Insert(aTmpImageData, aImageIndex);
+    }   
+
+/* Added new image */
+void CIEFileLoader::AddNewFaceCropImage(CImageData* aTmpImageData, TInt aImageIndex)
+    {
+    
+    //Insert new image data to filename array
+    aTmpImageData->iGridData.iCorrupted = EFalse;
+    aTmpImageData->iGridData.iRotationAngle = 0;//rotation angle of one image
+    aTmpImageData->iGridData.iTargetRotationAngle = 0;//target rotation angle of one image
+    aTmpImageData->iGridData.iX = aTmpImageData->iGridData.iY = aTmpImageData->iGridData.iZ = 0;//OpenGL Z coord
+    aTmpImageData->iGridData.iScale = 0;//OpenGL iScale
+    aTmpImageData->iGridData.iGlLQ32TextIndex = 0;//OpenGL 32x32 texture index
+    aTmpImageData->iGridData.iGlLQ128TextIndex = 0;//OpenGL 128x128 texture index
+    aTmpImageData->iGridData.iGlHQ512TextIndex = 0;//OpenGL 512x512 texture index
+    aTmpImageData->iGridData.iGlSuperHQTextIndex = 0;//OpenGL 2048x2048 texture index
+    
+    iFaceFilenameData.Insert(aTmpImageData, aImageIndex);
+    }   
+
+
+/*
+void CIEFileLoader::StartFileSystemMonitoring()
+    {
+    //iFileSystemMonitor->StartMonitoring();    
+    }
+
+void CIEFileLoader::StopFileSystemMonitoring()
+    {
+    //iFileSystemMonitor->StopMonitoring();    
+    }
+
+void CIEFileLoader::FileSystemChanged()
+    {
+    
+    }
+*/
+CIEEngineImp* CIEFileLoader::GetEngineImpPtr()
+    {
+    return iEngImp;
+    }
+    
+void CIEFileLoader::ModifyImageData(CImageData* aTmpImageData, TInt aImageIndex)
+    {
+    //Insert new image data to filename array
+    iFileNameData[aImageIndex] = aTmpImageData;
+    }
+
+
+/* All files are added to fine name array */
+void CIEFileLoader::AllFilesAddedToFilenameArray()
+    {
+#ifdef IMAGEFINDERMONITORAO        
+    TRequestStatus* status = &iImageFinderMonitor->iStatus;
+    RThread mainThread;
+    mainThread.Open( iMainThreadId );
+    mainThread.RequestComplete( status, KErrNone );
+#else    
+    iEngImp->AllFilesAddedToFilenameArrayL();
+#endif    
+    DP0_IMAGIC(_L("CIEFileLoader::AllFilesAddedToFilenameArray 1"));
+    //JPG File counting completed
+    //iJpgFileCountingComplete = ETrue;
+    
+    }
+
+//Only used for getting number of TNs in file system 
+#if 0
+void CIEFileLoader::SearchFileCountL(const TDesC& aRootPath, const TDesC& aSearchName, TInt& aImageFileCount, TInt& aFacesFileCount)
+    {
+    DP0_IMAGIC(_L("CIEFileLoader::SearchFileCountL++"));
+    TInt error = KErrNone;
+    TInt tnFileCount = 0;
+    
+    CDirScan* dirScan = CDirScan::NewL(iFileServer);
+    dirScan->SetScanDataL(aRootPath, KEntryAttDir|KEntryAttMatchExclusive, ESortNone, CDirScan::EScanDownTree);
+    
+    while(1)
+        {
+         CDir* dir = NULL;
+         dirScan->NextL(dir);
+         
+         if(error || !dir)
+          break;
+         
+         delete dir;
+         
+         TBool isFace = EFalse;
+         TPtrC FacesDir = dirScan->FullPath();
+         if(FacesDir.Find(KFacesPath) != KErrNotFound)
+             {
+             aFacesFileCount += ScanDirFileCountL(dirScan->FullPath(), aSearchName);    
+             }
+         else
+             {
+             aImageFileCount += ScanDirFileCountL(dirScan->FullPath(), aSearchName);    
+             }
+         } 
+    
+    delete dirScan;
+    dirScan = NULL;
+    
+    DP0_IMAGIC(_L("CIEFileLoader::SearchFileCountL--"));
+    }
+
+
+//Only used for getting number of TNs in file system
+TInt CIEFileLoader::ScanDirFileCountL(const TDesC& aDir, const TDesC& aWild)
+{
+    DP0_IMAGIC(_L("CIEFileLoader::ScanDirFileCountL++"));
+    TParse parse;
+    TInt count = 0;
+    
+    parse.Set(aWild, &aDir, NULL);
+    TPtrC spec(parse.FullName());
+
+    TFindFile findFile(iFileServer);
+    CDir* dir;
+    
+    if (!findFile.FindWildByPath(parse.FullName(), NULL, dir))
+    {
+        CleanupStack::PushL(dir);
+        
+        count = dir->Count(); 
+
+        CleanupStack::PopAndDestroy(dir);
+    }
+ 
+    return count;
+
+}
+#endif
+
+/* Deleting all corresponding Thumbnails including Gallery TNs */
+TInt CIEFileLoader::DeleteFile(TInt aIndex)
+    {
+    TInt err = KErrNotFound;
+    if(aIndex < iFileNameData.Count())
+        {
+        err = DeleteFile(iFileNameData[aIndex]);
+    
+        if (err == KErrNone)
+            {
+            CImageData* imageData = iFileNameData[aIndex];
+            iFileNameData.Remove(aIndex);
+            delete imageData;
+            iNumberOfImages = iFileNameData.Count();
+            }
+        }
+    return err;
+    }
+
+TInt CIEFileLoader::DeleteFile(const CImageData* aImageData)
+    {
+    TFileName fileName;
+    TInt err = KErrNone;
+
+    if(aImageData->IsImageReady(EFullSize))
+        {
+        aImageData->GetFileName(fileName, EFullSize);            
+        TInt err = iFileServer.Delete(fileName);
+        if (err != KErrNone)
+            return err;
+        }
+    
+    //Here if condition is not required. If the file does not exists
+    //then it returns not found system error code ?
+    //There is no value addition for extra check any way we have to remove
+    // that index from the array...( Cross check)
+    if(aImageData->IsImageReady(ESize128x128)) 
+        {
+        aImageData->GetFileName(fileName, ESize128x128);
+        iFileServer.Delete(fileName);
+        }
+        
+    if(aImageData->IsImageReady(ESize512x512))
+        {
+        aImageData->GetFileName(fileName, ESize512x512);        
+        iFileServer.Delete(fileName);
+        }
+            
+    if(aImageData->IsImageReady(ESize32x32))
+        {
+        aImageData->GetFileName(fileName, ESize32x32);
+        iFileServer.Delete(fileName);
+        }
+    
+    // Delete standard gallery thumbnail files
+    TFileName path, imageName;
+    aImageData->GetPath(path);
+    aImageData->GetFileName(imageName);
+    
+    const TPtrC thumbPaths[] = { 
+        _L("_PAlbTN\\320x320\\"), _L("_320x320"),
+        _L("_PAlbTN\\320x240\\"), _L(""),
+        _L("_PAlbTN\\170x128\\"), _L("_170x128"),        
+        _L("_PAlbTN\\"), _L("_128x96"),
+        _L("_PAlbTN\\64x64dat\\"), _L(""),
+        _L("_PAlbTN\\56x42\\"), _L("_56x42")
+    };
+    
+    for (TInt i = 0;i < sizeof(thumbPaths) / sizeof(TPtrC) ;i+=2)
+        {
+        fileName = path;
+        fileName.Append(thumbPaths[i]);
+        fileName.Append(imageName);
+        fileName.Append(thumbPaths[i + 1]);
+        iFileServer.Delete(fileName);
+        }
+
+    return err;
+    }
+
+/* Deleting all corresponding Thumbnails including Gallery TNs */
+TInt CIEFileLoader::DeleteFaceFile(TInt aIndex)
+    {
+    TInt err = KErrNotFound;
+    if(aIndex < iFaceFilenameData.Count())
+        {
+        //Here if condition is not required. If the file does not exists
+        //then it returns not found system error code ?
+        //There is no value addition for extra check any way we have to remove
+        // that index from the array...( Cross check)
+        err = DeleteFile(iFaceFilenameData[aIndex]);
+        CImageData* imageData = iFaceFilenameData[aIndex];
+        iFaceFilenameData.Remove(aIndex);
+        delete imageData;
+        iNumberOfFaces = iFaceFilenameData.Count();
+        }
+    return err;
+    }
+
+ 
+RArray<CImageData*>& CIEFileLoader::GetFileNameArray()
+{
+    return iFileNameData;
+}
+
+RArray<CImageData*>& CIEFileLoader::GetFacesFileNameArray()
+{
+    return iFaceFilenameData;
+}
+
+TInt CIEFileLoader::GetTotalNumOfImages()
+{
+    //return iNumberOfImages;
+    return iFileNameData.Count();
+}
+
+void CIEFileLoader::GetTotalNumOfImages(TInt& aNumOfImages, TInt& aNumOfFaces)
+    {
+    aNumOfImages = iFileNameData.Count();
+    aNumOfFaces = iFaceFilenameData.Count();
+    }
+
+void CIEFileLoader::GetUpdatedNumOfImages(TInt& aNumOfImages, TInt& aNumOfFaces)
+    {
+    aNumOfImages = iFileNameData.Count();
+    aNumOfFaces = iFaceFilenameData.Count();
+    }
+
+void CIEFileLoader::GetFileNameL(TInt aFileIndex, TFileName& aFileName, TThumbSize aThumbRes)
+{
+	if(aFileIndex < 0 || aFileIndex > iFileNameData.Count())
+	    {
+		User::Leave(KErrArgument);
+	    }
+	else
+	    {
+        iFileNameData[aFileIndex]->GetFileName(aFileName, aThumbRes);
+    	}
+}
+
+/*CImageData* CIEFileLoader::GetImageData(TInt aIndex)
+    {
+    return (aIndex < iFileNameData.Count()) ? iFileNameData[aIndex] : NULL;
+    }*/
+
+CImageData* CIEFileLoader::GetImageData(TInt aIndex/*, TImageArrayMode aMode*/)
+    {
+    return (aIndex >= 0 && aIndex < iFileNameData.Count()) ? iFileNameData[aIndex] : NULL;
+    }
+
+void CIEFileLoader::SetImageData(TInt aIndex, CImageData* aGridData)
+    {
+    if(aIndex < iFileNameData.Count())
+        iFileNameData[aIndex] = aGridData;
+    }
+
+#ifdef _ACCELEROMETER_SUPPORTED_
+TImagicDeviceOrientation CIEFileLoader::DeviceOrientation()
+    {
+    return iEngImp->GetDeviceOrientation();
+    }
+#endif
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEImageDecoder.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,214 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include "IEImageDecoder.h"
+
+
+// ========================== MEMBER FUNCTIONS ============================= //
+
+CIEImageDecoder* CIEImageDecoder::NewL(RFs& aFileServer, MDecodingObserver& aObserver)
+{
+	CIEImageDecoder* self = new (ELeave) CIEImageDecoder(aFileServer, aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CIEImageDecoder::~CIEImageDecoder()
+{
+	if(iImageDecoder)
+	{
+		delete iImageDecoder;
+		iImageDecoder = NULL;
+	}
+	
+	if(iExtImageDecoder)
+	{
+		delete iExtImageDecoder;
+		iExtImageDecoder = NULL;
+	}
+	
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+}
+
+//EPriorityIdle, EPriorityLow, EPriorityStandard, EPriorityUserInput, EPriorityHigh
+CIEImageDecoder::CIEImageDecoder(RFs& aFileServer, MDecodingObserver& aObserver)
+: CActive(EPriorityStandard), iFileServer(aFileServer), iObserver(aObserver), iSrcPtr(NULL, 0, 0)
+{	
+}
+
+void CIEImageDecoder::ConstructL()
+{
+	CActiveScheduler::Add(this);
+	
+	iDecoderBusy = EFalse;
+	iDecode2Yuv = EFalse;
+	iDecode2Bitmap = EFalse;
+	
+	iNumOfBitmaps = 0;
+}
+
+void CIEImageDecoder::RunL()
+{
+	TPtr8 ptr = iVisualFrame->DataPtrL();
+	TInt dataSize = ptr.Size(); 
+	TUint8* bufU = (TUint8*) ptr.Ptr();
+
+	if(iDecode2Yuv)
+	{
+		iDecode2Yuv = EFalse;
+		//iObserver.YuvImageReadyL(iStatus.Int());
+	}
+		
+	if(iDecode2Bitmap)
+	{
+		iDecode2Bitmap = EFalse;
+		iObserver.BitmapReadyL(iStatus.Int());
+	}		
+	
+	iDecoderBusy = EFalse;	
+}
+
+void CIEImageDecoder::DoCancel()
+{
+	
+}
+
+void CIEImageDecoder::GetImageSizeL(const TFileName aFileName, TSize& aSize)
+{
+	if(iImageDecoder)
+	{
+		delete iImageDecoder;
+		iImageDecoder = NULL;
+	}
+	
+	iImageDecoder = CImageDecoder::FileNewL(iFileServer, aFileName);
+	TFrameInfo frameInfo = iImageDecoder->FrameInfo();
+	
+	aSize.iWidth = frameInfo.iOverallSizeInPixels.iWidth;
+	aSize.iHeight = frameInfo.iOverallSizeInPixels.iHeight;
+	
+	delete iImageDecoder;
+	iImageDecoder = NULL;	
+}
+
+void CIEImageDecoder::ConvertJpeg2YuvL(const TDesC& aSourceFile, 
+								HBufC8& aBuffer, 
+								const TImageForamt /*aImageFormat*/)
+{
+	TInt fileSize = 0;
+	TInt blocks = 0;
+	
+	iDecoderBusy = ETrue;
+	iDecode2Yuv = ETrue;
+	
+	if(iExtImageDecoder)
+	{
+		delete iExtImageDecoder;
+		iExtImageDecoder = NULL;
+	}
+	
+	iExtImageDecoder = CExtJpegDecoder::FileNewL(iFileServer, aSourceFile);
+	
+	TFrameInfo frameInfo = iExtImageDecoder->FrameInfo();
+	
+	TInt width = frameInfo.iOverallSizeInPixels.iWidth;
+	TInt height = frameInfo.iOverallSizeInPixels.iHeight;
+
+	/*if(width%2 != 0)
+	    width++;
+    if(height%2 != 0)
+        height++;*/
+	        
+	TPtr8 bufPtr = aBuffer.Des();
+	
+	iBufU = (TUint8*)bufPtr.Ptr();
+	
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+	
+	iVisualFrame = CVisualFrame::NewL(bufPtr, 
+											TSize(width, height), 
+											CVisualFrame::EFormatYUV420Planar);
+	
+	
+	iExtImageDecoder->ConvertL(&iStatus, iVisualFrame, blocks);
+	
+	if(!IsActive())
+		SetActive();
+}
+
+
+void CIEImageDecoder::ConvertJpeg2BitmapL(CFbsBitmap& aDestBitmap, TDesC8& aSourceData)
+{
+	TInt frameNumber = 0;
+	
+	iDecoderBusy = ETrue;
+	iDecode2Bitmap = ETrue;
+	
+	TInt dataSize = aSourceData.Size();
+	
+	iSrcPtr.Set((TUint8*)aSourceData.Ptr(), aSourceData.Size(), aSourceData.Size());
+	
+	if(iImageDecoder)
+	{
+		delete iImageDecoder;
+		iImageDecoder = NULL;
+	}
+	
+	iImageDecoder = CImageDecoder::DataNewL(iFileServer, iSrcPtr);
+	
+	iImageDecoder->Convert(&iStatus, aDestBitmap, frameNumber);
+	
+	iNumOfBitmaps++;
+	
+	if(!IsActive())
+		SetActive();
+}
+
+
+TPtr8 CIEImageDecoder::GetVisualFrame()
+{
+	return iVisualFrame->DataPtrL();	 
+}
+
+void CIEImageDecoder::CancelDecoding()
+{
+	if(iDecoderBusy)
+	{
+		if(iImageDecoder)
+			iImageDecoder->Cancel();
+	
+		if(iExtImageDecoder)
+			iExtImageDecoder->Cancel();
+	}
+		
+	if(IsActive())
+		Cancel();	
+}
+
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEImageEncoder.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,189 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include "IEImageEncoder.h"
+
+// ========================== MEMBER FUNCTIONS ============================= //
+
+CIEImageEncoder* CIEImageEncoder::NewL(RFs& aFileServer, MEncodingObserver& aObserver)
+{
+	CIEImageEncoder* self = new (ELeave) CIEImageEncoder(aFileServer, aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CIEImageEncoder::~CIEImageEncoder()
+{
+	if(iFrameImageData)
+	{
+		delete iFrameImageData;
+		iFrameImageData = NULL;
+	}
+	
+	if(iImageEncoder)
+	{
+		delete iImageEncoder;
+		iImageEncoder = NULL;
+	}
+	
+	if(iExtImageEncoder)
+	{
+		delete iExtImageEncoder;
+		iExtImageEncoder = NULL;
+	}
+	
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+}
+
+
+CIEImageEncoder::CIEImageEncoder(RFs& aFileServer, MEncodingObserver& aObserver)
+: CActive(EPriorityStandard), iFileServer(aFileServer), iObserver(aObserver)
+{	
+}
+
+void CIEImageEncoder::ConstructL()
+{
+	iEncoderBusy = EFalse;
+	
+	CActiveScheduler::Add(this);
+}
+
+void CIEImageEncoder::RunL()
+{
+	TInt error = iStatus.Int();
+	
+	//iObserver.JpegImageReadyL(iStatus.Int());
+	iEncoderBusy = EFalse;
+}
+
+void CIEImageEncoder::DoCancel()
+{
+	
+}
+
+void CIEImageEncoder::ConvertYuv2JpegL(HBufC8*& aDestBuffer, 
+								HBufC8& aSourceBuffer, 
+								const TSize aSize, 
+								const TImageForamt /*aFormat*/)
+{
+	TInt blocks = 0;
+
+	iEncoderBusy = ETrue;
+
+	if(iExtImageEncoder)
+	{
+		delete iExtImageEncoder;
+		iExtImageEncoder = NULL;
+		
+	}
+	
+	iExtImageEncoder = CExtJpegEncoder::DataNewL(aDestBuffer, _L8("image/jpeg"));
+	
+	TPtr8 ptrSrc = aSourceBuffer.Des();
+	TInt bufSize = aSourceBuffer.Size();
+		
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+	
+	iVisualFrame = CVisualFrame::NewL(ptrSrc, aSize, CVisualFrame::EFormatYUV420Planar);
+	
+	SetJpegImageDataL();
+	iExtImageEncoder->ConvertL(&iStatus, iVisualFrame, blocks, iFrameImageData);
+	
+	if(!IsActive())
+		SetActive();
+}
+
+void CIEImageEncoder::ConvertYuv2JpegL(TDesC& aFileName, 
+								HBufC8& aSourceBuffer, 
+								const TSize aSize, 
+								const TImageForamt /*aFormat*/)
+{
+	TInt blocks = 0;
+
+	iEncoderBusy = ETrue;
+
+	if(iExtImageEncoder)
+	{
+		delete iExtImageEncoder;
+		iExtImageEncoder = NULL;
+		
+	}
+	
+	iExtImageEncoder = CExtJpegEncoder::FileNewL(iFileServer, aFileName, _L8("image/jpeg"));
+	
+	TPtr8 ptrSrc = aSourceBuffer.Des();
+	TInt bufSize = aSourceBuffer.Size();
+		
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+	
+	iVisualFrame = CVisualFrame::NewL(ptrSrc, aSize, CVisualFrame::EFormatYUV420Planar);
+	
+	SetJpegImageDataL();
+	iExtImageEncoder->ConvertL(&iStatus, iVisualFrame, blocks, iFrameImageData);
+	
+	if(!IsActive())
+		SetActive();
+}
+
+void CIEImageEncoder::SetJpegImageDataL()
+{
+	TJpegImageData* jpegImageData;
+	jpegImageData = new (ELeave) TJpegImageData;
+	jpegImageData->iSampleScheme = TJpegImageData::EColor420;
+	jpegImageData->iQualityFactor = 90;	
+	
+	if(iFrameImageData)
+	{
+		delete iFrameImageData;
+		iFrameImageData = NULL;
+	}
+	
+	iFrameImageData = CFrameImageData::NewL();
+	// Ownership of jpegImageData lies with CFrameImageData
+	User::LeaveIfError(iFrameImageData->AppendImageData(jpegImageData));
+}
+
+void CIEImageEncoder::CancelEncoding()
+{
+	if(iEncoderBusy)
+	{
+		if(iImageEncoder)
+			iImageEncoder->Cancel();
+		if(iExtImageEncoder)
+			iExtImageEncoder->Cancel();
+	}
+	
+	if(IsActive())
+		Cancel();
+}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEImageFinder.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,391 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// INCLUDE FILES
+
+#include <eikenv.h>
+#include <exifread.h>
+#include <f32file.h>
+#include "IEImageFinder.h"
+#include "IEImageList.h"
+#include "IEImageProcessing.h"
+#include "IEImageData.h"
+#include "IEEngineImp.h"
+#include "IEEngineUtils.h"
+#ifdef _S60_5x_ACCELEROMETER_
+#include "IESensorMonitor.h"
+#endif
+
+#define LATETHUMBCHECK
+
+// ================= MEMBER FUNCTIONS =======================
+
+CIEImageFinder* CIEImageFinder::NewL(
+        CIEFileLoader* aCallback, 
+        RArray<CImageData*>& aFileNameData, 
+        RArray<CImageData*>& aFaceFileNameData,
+        RCriticalSection* aCritical)
+    {
+    CIEImageFinder* self = new(ELeave) CIEImageFinder(aCallback, aFileNameData, aFaceFileNameData, aCritical);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+CIEImageFinder* CIEImageFinder::NewLC(
+        CIEFileLoader* aCallback, 
+        RArray<CImageData*>& aFileNameData, 
+        RArray<CImageData*>& aFaceFileNameData, 
+        RCriticalSection* aCritical)
+    {
+    CIEImageFinder* self = new(ELeave) CIEImageFinder(aCallback, aFileNameData, aFaceFileNameData, aCritical);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+CIEImageFinder::CIEImageFinder(
+        CIEFileLoader* aCallback, 
+        RArray<CImageData*>& aFileNameData, 
+        RArray<CImageData*>& aFaceFileNameData, 
+        RCriticalSection* aCritical) :
+        //iList(aFileNameData, aCallback),
+        iCallback(aCallback),
+        iFileNameData(aFileNameData),
+        iFaceFileNameData(aFaceFileNameData),
+        iCritical(aCritical),
+        iIEEngineUtils(iFileServer)
+    {
+    DP0_IMAGIC(_L("CIEImageFinder::CIEImageFinder++ --"));
+    }
+
+
+void CIEImageFinder::ConstructL()
+    {
+    DP0_IMAGIC(_L("CIEImageFinder::ConstructL++"));
+    
+    User::LeaveIfError(iFileServer.Connect());
+    
+    iImageList = &iCallback->GetImageList();
+    
+    //iFileSystemMonitor = CFileSystemMonitorAO::NewL(iFileServer, this);
+    
+    // Creating Engine Utility class pointer */
+        
+    DP0_IMAGIC(_L("CIEImageFinder::ConstructL--"));
+    }
+
+CIEImageFinder::~CIEImageFinder()
+    {
+    DP0_IMAGIC(_L("CIEImageFinder::~CIEImageFinder++"));
+  	
+    iFileServer.Close();
+  	
+  	DP0_IMAGIC(_L("CIEImageFinder::~CIEImageFinder--"));
+    }
+
+TBool CIEImageFinder::IsSearching() const
+    {
+    return (iCallback->ImageFinderState() == CIEFileLoader::EImageFinderRunning);
+    }
+
+void CIEImageFinder::StartFinderL(const TDesC& aSearchName)
+    {
+    DP0_IMAGIC(_L("CIEImageFinder::StartFinderL++"));
+
+#ifdef IMAGIC_DATABASE
+    // Read initial list from database
+    TRAP_IGNORE(iImageList->ReadDatabaseL());
+#endif    
+    if (IsSearching())
+        SearchFilesL(aSearchName);
+    
+    DP0_IMAGIC(_L("CIEImageFinder::StartFinderL--"));
+    }
+
+void CIEImageFinder::SearchFilesL(const TDesC& aSearchName)
+    {
+    DP0_IMAGIC(_L("CIEImageFinder::SearchFilesL++"));
+     
+    // Use phone memory, external memory card and internal memory card for file scanning 
+    TFileName rootPathPhoneMemory = PathInfo::PhoneMemoryRootPath();
+    rootPathPhoneMemory.Append(ImagePath);
+     
+    TFileName rootPathMCard = PathInfo::MemoryCardRootPath();
+    rootPathMCard.Append(ImagePath);
+     
+    TFileName rootPathFDrive;
+    rootPathFDrive.Copy(KRootPathFDrive);
+    rootPathFDrive.Append(ImagePath);
+     
+    //Append drives to array
+    RArray<TFileName> drives;
+    drives.Append(rootPathPhoneMemory);
+    drives.Append(rootPathMCard);
+    drives.Append(rootPathFDrive);
+
+    DP0_IMAGIC(_L("CIEImageFinder::SearchFilesL start"));    
+    
+    for(TInt i=0; i<drives.Count() && IsSearching(); i++)
+        {
+        if(BaflUtils::PathExists(iFileServer, drives[i]))
+            {
+            DP2_IMAGIC(_L("CIEImageFinder::SearchFilesL  aRootPath = %S, aSearchName = %S ++"), &drives[i], &aSearchName);
+             
+            CDirScan* dirScan = CDirScan::NewL(iFileServer);
+             
+            TRAPD(err, dirScan->SetScanDataL(
+                    drives[i], 
+                    KEntryAttDir|KEntryAttMatchExclusive, 
+                    EDirDescending/*|EDescending*/|ESortByDate, 
+                    CDirScan::EScanUpTree));
+
+            if(err == KErrNone)
+                {
+                CDir* dir;
+                while(IsSearching())
+                    {
+                    TRAP(err, dirScan->NextL(dir));
+                    if(err != KErrNone || dir == NULL)
+                        {
+                        if (dir)
+                            delete dir;
+                        break;
+                        }
+                  
+                    TRAP(err, ScanDirL(dir, dirScan->FullPath(), aSearchName));
+                    delete dir;
+                    if (err != KErrNone)
+                        break;
+                    }
+                }
+          
+            delete dirScan;
+            }
+        }
+    
+#ifdef IMAGIC_DATABASE      
+        // Remove files from deleted directories
+    if (IsSearching())
+        iImageList->RemoveNonExistImagesL(NULL, iFileServer);
+#endif
+    
+#ifdef LATETHUMBCHECK    
+    // Check all thumbnails
+    for (TInt i = 0;i < iFileNameData.Count() && IsSearching();i++)
+        {
+        CheckCreatedThumbnails(*iFileNameData[i]);
+        
+        // Number of faces is unknown and thumbnail exists
+        if (iFileNameData[i]->GetNumberOfFaces() < 0 &&
+            iFileNameData[i]->IsImageReady(ESize512x512))
+            {
+            // Read number of faces from thumb's exif
+            RArray<TRect> faceCoordinates;
+            TFileName fileName;
+            iFileNameData[i]->GetFileName(fileName, ESize512x512);
+            TRAPD(error, iIEEngineUtils.ReadFaceCoordinatesL(fileName, faceCoordinates));
+            if (error == KErrNone)
+                {
+                TInt count = faceCoordinates.Count();
+                DP2_IMAGIC(_L("Read face# %d for %S"), count, &fileName);
+                iFileNameData[i]->SetNumberOfFaces(count);
+                iImageList->SetChanged(fileName);
+                }
+            }
+        }
+#endif    
+
+    // Let engine know that all file has been added to filename array
+    //iCallback->AllFilesAddedToFilenameArray();
+         
+    drives.Close();
+
+#ifdef IMAGIC_DATABASE    
+    // Write list to database
+    TRAP_IGNORE(iImageList->WriteDatabaseL());
+#endif    
+    
+    DP0_IMAGIC(_L("CIEImageFinder::SearchFilesL--"));
+    }
+
+void CIEImageFinder::ScanDirL(CDir* aDir, const TDesC& aDirPath, const TDesC& aWild)
+    {
+    DP1_IMAGIC(_L("CIEImageFinder::ScanDirL++ %S"), &aDirPath);
+    
+    TParse parse;
+    parse.Set(aWild, &aDirPath, NULL);
+    TPtrC spec(parse.FullName());
+    
+    /*if(aDirPath.Find(KCRootBgroundImages) != KErrNotFound)
+        return;*/
+     
+    TFindFile findFile(iFileServer);
+     
+    if (findFile.FindWildByPath(parse.FullName(), NULL, aDir) == KErrNone)
+        {
+        // Sort in time order
+        aDir->Sort(EDescending|ESortByDate);
+
+        // Go through dir in inverted order
+        for(TInt i = 0;i < aDir->Count() && IsSearching();i++)
+            {
+            parse.Set((*aDir)[i].iName, &spec, NULL);
+               
+            // Full filename with path of original image
+            TFileName imageFileName;
+            imageFileName = parse.FullName();
+               
+            // Check if file exist and not be hidden
+            TBool visible = EFalse;
+            TRAPD(err, visible = iImageList->IsImageViewableL(imageFileName, iFileServer));
+            if (err != KErrNone || !visible)
+                {
+                DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - not found or hidden file"));
+                continue;
+                }
+            
+            CImageData* imageData = iImageList->GetImageData(imageFileName);
+            
+            // Read file time
+            TTime fileTime(0);
+            TRAP(err, iIEEngineUtils.GetModifiedTimeL(imageFileName, fileTime));
+            if (err != KErrNone)
+                {
+                DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - get file time failed"));
+
+                // File is locked for writing, use old file time if possible
+                if (imageData == NULL)
+                    continue;
+                else
+                    fileTime = imageData->GetFileTime();
+                }
+            
+            // Image already exist in list
+            if (imageData != NULL)
+                {
+                DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - image exist"));
+                // File has been changed
+                if (imageData->GetFileTime() != fileTime)
+                    {
+                    DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - file time is different"));
+                    // Delete thumbnails and remove image from the list
+                    iIEEngineUtils.DeleteThumbnails(imageFileName, iFileServer);
+                    iImageList->Remove(iImageList->GetImageIndex(imageData), iFileServer);
+                    imageData = NULL;
+                    }
+                }
+
+            // Image already exist
+            if (imageData == NULL)
+                {
+                // Read aspect ratio
+                TSize size;
+                TRAP(err, iIEEngineUtils.GetImageSizeL(imageFileName, size));
+                if (err != KErrNone)
+                    {
+                    DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - get size failed"));
+                    continue;
+                    }
+
+                // Read EXIF created time (use file time if EXIF fails)
+                TTime createdTime;
+                TUint16 orientation = 0;
+                TRAP(err, iIEEngineUtils.GetExifDateTimeAndOrientationL(
+                        imageFileName, 
+                        createdTime, 
+                        orientation));
+                
+                if (err != KErrNone) 
+                    {
+                    DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - No EXIF date"));
+                    createdTime = fileTime;
+                    }
+                  
+                // Add image to list
+                DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - Call AddImageL"));
+                TRAP(err, imageData = iImageList->CreateImageDataL(imageFileName, createdTime, orientation));
+                DP1_IMAGIC(_L("CIEImageFinder::ScanDirL - AddImageL returned: err:% d"), err);
+                
+                if (err != KErrNone)
+                    {
+                    imageData = NULL;
+                    }
+                else if (imageData) 
+				    {
+                    imageData->SetFileTime(fileTime);
+                    imageData->SetSize(size);
+                    iImageList->AddImage(imageData);
+                    }
+                iImageList->SetChanged(imageFileName);
+                }
+            
+            DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - 03"));
+            // Mark original image as ready
+            if (imageData)
+                {
+                DP0_IMAGIC(_L("CIEImageFinder::ScanDirL - 04"));
+                imageData->SetImageReady(EFullSize, ETrue);
+                }
+            }
+        
+            delete aDir;
+        }
+    
+#ifdef IMAGIC_DATABASE    
+    //RemoveDeletedImagesL(*array, &aDirPath);
+#endif    
+    
+    DP0_IMAGIC(_L("CIEImageFinder::ScanDirL--"));
+    }
+
+void CIEImageFinder::CheckCreatedThumbnails(CImageData& aImageData) const
+    {
+    TThumbSize sizes[] = { /*EFullSize,*/ ESize512x512, ESize128x128, ESize32x32 };
+    
+    TInt numSizes = sizeof(sizes) / sizeof(TThumbSize);
+    for (TInt i = 0;i < numSizes; i++)
+        {
+        TFileName fileName;
+        aImageData.GetFileName(fileName, sizes[i]);
+        if (BaflUtils::FileExists(iFileServer, fileName))
+            aImageData.SetImageReady(sizes[i], ETrue);
+        else
+            // Mark all smaller sizes non-exist
+            //while (i < numSizes)
+                {
+                aImageData.SetImageReady(sizes[i], EFalse);
+                //i++;
+                }
+        }    
+    }
+
+void CIEImageFinder::FileSystemChanged()
+    {
+    //Scan filesystem for new images
+    //SearchForNewFilesL(KRootImagePath, KFileString);
+    
+#ifdef __WINS__
+    SearchFilesL(KFileString);
+#else
+    TFileName rootPath = PathInfo::MemoryCardRootPath();
+    rootPath.Append(ImagePath);
+    SearchFilesL(KFileString);
+#endif
+    
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEImageList.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,679 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// INCLUDE FILES
+
+#include <eikenv.h>
+#include <exifread.h>
+#include <f32file.h>
+#include <s32file.h>
+#include <bautils.h>
+#include "IEImageList.h"
+#include "IEImageData.h"
+#include "IEEngineImp.h"
+#include "IEEngineUtils.h"
+#include "ImageMonitorAO.h"
+#include "IEFileLoader.h"
+#ifdef _S60_5x_ACCELEROMETER_
+#include "IESensorMonitor.h"
+#endif
+
+#define LATETHUMBCHECK
+//#define GROUP_FOLDERS_BY_NAME
+#define CHECK_IF_IMAGE_IS_VISIBLE
+
+_LIT(KDatabaseFileName, "photobrowser.db");
+_LIT8(KDatabaseId, "IMGC0008");
+const TInt KNumOfDrives = 3;
+
+EXPORT_C CIEImageList* CIEImageList::NewL(        
+        RArray<CImageData*>& aImageData, 
+        CIEFileLoader* aCallback)
+    {
+    CIEImageList* self = new (ELeave) CIEImageList(aImageData, aCallback);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+CIEImageList::CIEImageList(
+        RArray<CImageData*>& aImageData, 
+        CIEFileLoader* aCallback) :
+    iCallback(aCallback),
+    iImageDataList(aImageData),
+    iGridMode(EGridModeTime)	
+    {
+    for (TInt i = 0;i < KNumOfDrives;i++)
+        iDatabaseChanged[i] = EFalse; 
+    }
+
+void CIEImageList::ConstructL() 
+    {
+    User::LeaveIfError(iCritical.CreateLocal());
+    }
+        
+EXPORT_C CIEImageList::~CIEImageList()
+    {
+    iCritical.Close();
+    }
+        
+EXPORT_C void CIEImageList::SetGridMode(TGridMode aGridMode)
+    {
+    if (iGridMode != aGridMode) 
+        {
+        iGridMode = aGridMode;
+        iCritical.Wait();
+        Rearrange(0);
+        iCritical.Signal();
+        }
+    }
+
+EXPORT_C TGridMode CIEImageList::GetGridMode() const
+    {
+    return iGridMode; 
+    }
+
+EXPORT_C void CIEImageList::SetChanged(TDesC& aPath)
+    {
+    TImageListDrive drive = EImageListDriveC;
+    TRAPD(err, drive = GetPathDriveL(aPath));
+    if (err == KErrNone)
+        {
+        iDatabaseChanged[drive] = ETrue;
+        }
+    }
+
+void CIEImageList::SetChanged(CImageData* aImageData)
+    {
+    TFileName fileName;
+    aImageData->GetFileName(fileName, EFullSize);
+    SetChanged(fileName);
+    }
+
+CImageData* CIEImageList::CreateImageDataL(
+        const TFileName& aFileName, 
+        const TTime& aTime,
+        const TReal orientation)
+    {
+    DP0_IMAGIC(_L("CIEImageList::CreateImageDataL++"));
+    
+    // Create new image data instance
+    CImageData* imageData = CImageData::NewL(
+#ifdef LATETHUMBCHECK            
+            /*EFullSize|*/ESize512x512|ESize128x128|ESize32x32
+#endif            
+            );
+    
+    imageData->SetCreatedTime(aTime);
+    imageData->SetFileNameL(aFileName);
+    imageData->SetOrientation(orientation);    
+    
+#ifdef _S60_5x_ACCELEROMETER_
+    // Portrait
+    if(iCallback->DeviceOrientation() == TSensrvOrientationData::EOrientationDisplayUp)
+        {
+        imageData->iGridData.iTargetRotationAngle = 90 + orientation;
+        }
+    // Landscape
+    else//(iCallback->DeviceOrientation() == TSensrvOrientationData::EOrientationDisplayRightUp)
+        {
+        imageData->iGridData.iTargetRotationAngle = orientation;
+        }
+    imageData->iGridData.iRotationAngle = orientation;
+#else
+    imageData->iGridData.iRotationAngle = orientation;
+    imageData->iGridData.iTargetRotationAngle = orientation;
+#endif
+    
+    DP1_IMAGIC(_L("CIEImageList::AddImageL - filename: %S"), &aFileName);
+
+#ifndef LATETHUMBCHECK    
+    //Check and mark to imageData which thumbnails exists
+    CheckCreatedThumbnails(*imageData);
+#endif
+    
+    DP0_IMAGIC(_L("CIEImageList::CreateImageDataL--"));
+    return imageData;
+    }
+    
+TBool CIEImageList::IsImageBefore(CImageData* aNewImageData, TInt aIndex) const
+    {
+    if (aIndex >= iImageDataList.Count())
+        return ETrue;
+    
+    // Use folder grouping
+    if (iGridMode != EGridModeTime)      
+        {
+        TFileName newPath, path;
+        aNewImageData->GetPath(newPath);
+        iImageDataList[aIndex]->GetPath(path);
+
+#ifdef GROUP_FOLDERS_BY_NAME
+        // Folders are sorted by name
+        if (newPath > path)      // TODO: should trim drive + base path (e.g. C:\data\)
+            return ETrue;
+        if (newPath < path)
+            return EFalse;
+#else
+
+        if (iGridMode == EGridModePeople)
+            {
+            return (iImageDataList[aIndex]->iPersonId > 
+                    aNewImageData->iPersonId);
+            }
+        else if (iGridMode == EGridModeFolder && aIndex > 0)
+            {
+            // Current image path is not same
+            if (path != newPath)
+                {
+                TFileName prevPath;
+                iImageDataList[aIndex - 1]->GetPath(prevPath);
+                  
+                // Previous image path is same, add after that
+                if (newPath == prevPath)
+                     return ETrue;
+                
+                // Compare only against the first image in the folder
+                if (path == prevPath)
+                     return EFalse;
+                }
+            }
+#endif
+        }
+    
+    // Compare times
+    return (aNewImageData->GetCreatedTime() > iImageDataList[aIndex]->GetCreatedTime());
+    }
+
+TInt CIEImageList::GetNewImageIndex(CImageData* aImageData) const
+    {
+    TInt index = 0; 
+    while(index < iImageDataList.Count())
+        {
+        if(IsImageBefore(aImageData, index))
+            {
+            break;
+            }
+        index++;
+        }
+    return index;
+    }
+
+void CIEImageList::Rearrange(TInt aStartIndex)
+    {
+    for (TInt i = aStartIndex;i < iImageDataList.Count();i++)
+        {
+        CImageData* imageData = iImageDataList[i];            
+        iImageDataList.Remove(i);
+        TInt newIndex = GetNewImageIndex(imageData);
+        iImageDataList.Insert(imageData, newIndex);
+        }
+    }
+
+EXPORT_C void CIEImageList::AddImage(CImageData* aImageData)
+    {
+    DP0_IMAGIC(_L("CIEImageList::AddImageL++"));
+    
+    iCritical.Wait();  
+    
+    // Insert image to list
+    TInt index = GetNewImageIndex(aImageData);
+    iImageDataList.Insert(aImageData, index);
+        
+    // Need to resort all items if use time based folder sort
+#ifndef GROUP_FOLDERS_BY_NAME
+    if (iGridMode != EGridModeTime)      
+        {
+        Rearrange(index + 1);
+        }
+#endif        
+
+    // Image is not added as last image
+    if (index < iImageDataList.Count() - 1)
+        {
+        // Mark database as changed
+        SetChanged(aImageData);
+        
+        // Inform UI
+        //iCallback->ImageListChanged(index, ETrue);
+        }
+    
+    iCallback->ImageListChanged(index, ETrue);
+    
+    iCritical.Signal();
+    
+    DP0_IMAGIC(_L("CIEImageList::AddImageL-- tmpImageData"));
+    }
+
+#ifdef IMAGIC_DATABASE
+
+void CIEImageList::GetDatabaseFileName(TFileName& aFileName, TImageListDrive aDrive)
+    {
+    switch (aDrive)
+        {
+        case EImageListDriveC:
+            aFileName.Copy(PathInfo::PhoneMemoryRootPath());
+            break;
+            
+        case EImageListDriveE:
+            aFileName.Copy(PathInfo::MemoryCardRootPath());
+            break;
+            
+        case EImageListDriveF:           
+            aFileName.Copy(KRootPathFDrive);
+            break;
+           
+        default:
+            return;
+        }
+    
+    aFileName.Append(KDatabaseFileName);
+    }
+
+EXPORT_C void CIEImageList::ReadDatabaseL()
+    {  
+    DP0_IMAGIC(_L("CIEImageList::ReadDatabaseL++"));
+
+    RFileReadStream readStreams[KNumOfDrives];
+    TBool openStreams[KNumOfDrives];
+    CImageData* imageDatas[KNumOfDrives];
+    RFs fs;
+    
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL(fs);
+    
+    // Open databases
+    for (TInt i = 0;i < KNumOfDrives;i++)
+        {
+        openStreams[i] = EFalse;
+        imageDatas[i] = NULL;        
+        
+        TFileName databaseFileName;
+        GetDatabaseFileName(databaseFileName, TImageListDrive(i));
+        if (readStreams[i].Open(fs, databaseFileName, EFileShareAny) == KErrNone)
+            {
+            // Check file validity and version
+            TUint8 buf[8];
+            TPtr8 ptr(buf, sizeof(buf));
+            readStreams[i].ReadL(ptr, KDatabaseId.iTypeLength);
+            if (ptr.Compare(KDatabaseId) != 0)
+                readStreams[i].Close();
+            else
+                openStreams[i] = ETrue;
+            }
+        }
+    
+    // Read databases
+    while(iCallback->ImageFinderState() == CIEFileLoader::EImageFinderRunning)
+        {
+        // Read image datas from each database
+        TBool endOfData = ETrue;
+        for(TInt i = 0;i < KNumOfDrives;i++)
+            {
+            // Database is open and no image data is left
+            if (imageDatas[i] == NULL && openStreams[i])
+                {
+                TRAPD(err, imageDatas[i] = ReadImageDataL(readStreams[i], fs));
+                if (err != KErrNone || imageDatas[i] == NULL) 
+                    {
+                    openStreams[i] = EFalse;
+                    readStreams[i].Close();
+                    }
+                }
+            
+            if (imageDatas[i])
+                endOfData = EFalse;
+            }
+        
+        if (endOfData)
+            break;
+        
+        // Pick the most leftmost image 
+        TInt index = -1;
+        for (TInt i = 0;i < KNumOfDrives;i++)
+            {
+            if (imageDatas[i] && 
+                    (index < 0 || 
+                     IsImageBefore(imageDatas[i], index)))
+                index = i;
+            }
+            
+        // Add image to list
+        if (index >= 0) 
+            {
+            AddImage(imageDatas[index]);
+            imageDatas[index] = NULL;
+            }
+        }
+    
+    CleanupStack::Pop();
+    fs.Close();
+
+    DP0_IMAGIC(_L("CIEImageList::ReadDatabaseL--"));
+    }
+
+CImageData* CIEImageList::ReadImageDataL(RFileReadStream& readStream, RFs& aFs)
+    {
+    TUint8 buf[KMaxFileName * 2];
+    TPtr8 ptr(buf, sizeof(buf));
+    TFileName fileName;
+    TTime fileTime, createdTime;
+    TSize size;
+    TInt faces;
+    TUint16 orientation;
+    CImageData* imageData = NULL;
+           
+    // Read until get valid image data
+    while (imageData == NULL) {
+    
+        // Read file name (1 byte length, unicode name)
+        TInt len = readStream.ReadUint8L();
+    
+        // End of list
+        if (len == 0)
+            return NULL;
+
+        readStream.ReadL(ptr, len * 2);
+        TPtrC16 ptr16((const TUint16*)buf, len);
+        fileName.Copy(ptr16);
+            
+        // Read file time
+        readStream.ReadL(ptr, sizeof(TTime));
+        fileTime = *(TTime*)ptr.Ptr();
+
+        // Read created time
+        readStream.ReadL(ptr, sizeof(TTime));
+        createdTime = *(TTime*)ptr.Ptr();                    
+
+        // Read orientation (in 90 degrees angles)
+        orientation = readStream.ReadUint8L() * 90L;
+            
+        // Read resolution
+        size.iWidth = readStream.ReadUint32L();
+        size.iHeight = readStream.ReadUint32L();
+
+        // Read number of faces
+        faces = readStream.ReadInt8L();
+        
+        TInt personId = readStream.ReadInt32L();
+
+        // Check that no multiple entries
+        if ((imageData = GetImageData(fileName)) != NULL) 
+            {
+            imageData = NULL;
+            continue;
+            }
+        
+        // Check if image exist and not be hidden
+        TInt error = KErrNone;
+        TBool visible = ETrue;
+#ifdef CHECK_IF_IMAGE_IS_VISIBLE        
+
+        TRAP(error, visible = IsImageViewableL(fileName, aFs));
+#endif        
+        if (error == KErrNone && visible)
+            {
+            // Create image data object
+            imageData = CreateImageDataL(
+                    fileName, 
+                    createdTime, 
+                    orientation);
+
+            if (imageData) 
+                {
+                imageData->SetFileTime(fileTime);
+                imageData->SetSize(size);
+                imageData->SetNumberOfFaces(faces);
+                imageData->iPersonId = personId;
+                //imageData->SetImageReady(EFullSize, ETrue);
+                }        
+            }
+        else
+            {
+            // Delete thumbnails if file could not be read
+            if (error != KErrNone)
+                CIEEngineUtils::DeleteThumbnails(fileName, aFs);
+            SetChanged(fileName);
+            }
+        }
+    
+    return imageData;
+    }
+    
+EXPORT_C void CIEImageList::WriteDatabaseL() 
+    {
+    DP0_IMAGIC(_L("CIEImageList::WriteDatabaseL++"));
+
+    RFs fs;
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL(fs);
+    
+    for (TInt i = 0;i < KNumOfDrives;i++) 
+        {
+        if (iDatabaseChanged[i])
+            {
+            TRAP_IGNORE(WriteDatabaseL(TImageListDrive(i), fs)); 
+            iDatabaseChanged[i] = EFalse;
+            }
+        }
+    
+    CleanupStack::Pop(); // fs
+    fs.Close();    
+    
+    DP0_IMAGIC(_L("CIEImageList::WriteDatabaseL--"));    
+    }
+        
+void CIEImageList::WriteDatabaseL(TImageListDrive aDrive, RFs& aFs)
+    {
+    TUint8 buf[sizeof(TUint32)];
+    TPtr8 ptr(buf, sizeof(buf));
+    RFile f;
+
+    TFileName path, fileName;
+    GetDatabaseFileName(fileName, aDrive);
+    
+    TParse parser;
+    parser.Set(fileName, NULL, NULL);
+    path = parser.DriveAndPath();
+    TRAP_IGNORE(BaflUtils::EnsurePathExistsL(aFs, path));    
+    
+    if (f.Replace(
+            aFs, 
+            fileName, 
+            EFileWrite) != KErrNone) 
+        return;
+        
+    CleanupClosePushL(f);
+    
+    f.SetAtt(KEntryAttHidden, 0);
+    
+    RFileWriteStream writeStream(f); 
+    CleanupClosePushL(writeStream); 
+    
+    writeStream.WriteL(KDatabaseId);
+
+    for (TInt32 i = 0;i < iImageDataList.Count();i++)
+        {
+        TFileName fileName;
+        TImageListDrive drive = EImageListDriveC;
+        iImageDataList[i]->GetFileName(fileName, EFullSize);
+        
+        // Write only files that belong to this drive
+        TRAPD(err, drive = GetPathDriveL(fileName));
+        if (err != KErrNone || drive != aDrive)
+            continue;
+
+        // Write file name
+        writeStream.WriteUint8L(fileName.Length());
+        writeStream.WriteL(fileName, fileName.Length());
+          
+        // Write file time
+        TTime fileTime = iImageDataList[i]->GetFileTime();
+        TPtrC8 fileTimeptr((const TUint8 *)&fileTime, sizeof(TTime));
+        writeStream.WriteL(fileTimeptr);
+
+        // Write created time
+        TTime createdTime = iImageDataList[i]->GetCreatedTime();
+        TPtrC8 createdTimeptr((const TUint8 *)&createdTime, sizeof(TTime));
+        writeStream.WriteL(createdTimeptr);
+
+        // Write orientation (in 90 degrees)
+        writeStream.WriteUint8L(iImageDataList[i]->GetOrientation() / 90);
+                
+        // Write size
+        writeStream.WriteUint32L(iImageDataList[i]->GetSize().iWidth);
+        writeStream.WriteUint32L(iImageDataList[i]->GetSize().iHeight);
+
+        // Write number of faces
+        writeStream.WriteInt8L(iImageDataList[i]->GetNumberOfFaces());
+        writeStream.WriteInt32L(iImageDataList[i]->iPersonId);
+        }
+
+    // End of stream notification
+    writeStream.WriteUint8L(0);
+    
+    writeStream.Close();
+    
+    CleanupStack::PopAndDestroy(); // write stream
+    CleanupStack::PopAndDestroy(); // f
+    }
+#endif
+
+EXPORT_C TBool CIEImageList::IsImageViewableL(TDesC& aFileName, RFs& aFs) const 
+    {
+    TUint att;
+    //if(!IsFileExist(fileName))
+    TInt error = aFs.Att(aFileName, att);
+    if (error != KErrNone)
+        User::Leave(error);
+    
+    return ((att & KEntryAttHidden) == KEntryAttHidden) ? EFalse : ETrue;  
+    }
+
+EXPORT_C TInt CIEImageList::GetImageIndex(CImageData* aImageData)
+    {
+    for (TInt i = 0;i < iImageDataList.Count();i++) 
+        {
+        if (aImageData == iImageDataList[i])
+            return i;
+        }
+    return -1;
+    }
+
+EXPORT_C CImageData* CIEImageList::GetImageData(const TFileName& aFileName)
+    {
+    CImageData* imageData = NULL;
+    iCritical.Wait();
+    
+    for (TInt i = 0;i < iImageDataList.Count();i++) 
+        {
+        TFileName fileName;
+        iImageDataList[i]->GetFileName(fileName, EFullSize);
+        if (fileName.Compare(aFileName) == 0)
+            {
+            imageData = iImageDataList[i];
+            break;
+            }
+        }
+    
+    iCritical.Signal();
+        
+    return imageData;
+    }
+
+EXPORT_C void CIEImageList::RemoveNonExistImagesL(TDesC* aPath, RFs& aFs)
+    {
+    DP0_IMAGIC(_L("CIEImageList::RemoveNonExistImagesL++"));
+    
+    TInt i = 0;
+    while (i < iImageDataList.Count()) 
+        {
+        iCritical.Wait();
+        
+        // File may not exist
+        TBool bRemove = !iImageDataList[i]->IsImageReady(EFullSize); 
+        
+        // Start of path must be same
+        if (bRemove && aPath) {
+            TFileName path;
+            iImageDataList[i]->GetPath(path);
+            bRemove = (aPath->Compare(path) == 0);
+        }
+
+        iCritical.Signal();
+        
+        // Remove from list
+        if (bRemove)
+            {
+            Remove(i, aFs);
+            if (aPath)
+                SetChanged(*aPath);
+            }
+        else
+            {
+            i++;
+            }
+        }
+    
+    DP0_IMAGIC(_L("CIEImageList::RemoveNonExistImagesL--"));
+    }
+
+CIEImageList::TImageListDrive CIEImageList::GetPathDriveL(TDesC& aPath)
+    {
+    TParse parser;
+    parser.Set(aPath, NULL, NULL);
+    TPtrC drive = parser.Drive();
+    const TPtrC drives[] = { _L("C:"), _L("E:"), _L("F:") };
+    
+    for (TInt i = 0;i < sizeof(drives) / sizeof(TPtrC);i++)
+        {
+        if (drive.Compare(drives[i]) == 0)
+            {
+            return TImageListDrive(i);
+            }
+        }
+    
+    User::Leave(KErrArgument);
+    return EImageListDriveC;
+    }
+
+EXPORT_C void CIEImageList::Remove(TInt aIndex, RFs& aFs)
+    {
+    TFileName fileName;
+    
+    if (aIndex < 0 || aIndex >= iImageDataList.Count())
+        return;
+    
+    // Delete thumbnails if original file doesn't exist anymore
+    iImageDataList[aIndex]->GetFileName(fileName, EFullSize);
+    if(!BaflUtils::FileExists(aFs, fileName))
+        CIEEngineUtils::DeleteThumbnails(fileName, aFs);
+    
+    iCritical.Wait();
+    
+    // Remove from the list
+    CImageData* pRemovedImageData = iImageDataList[aIndex];
+    iImageDataList.Remove(aIndex);
+    delete pRemovedImageData;
+    
+    iCritical.Signal();
+    
+    SetChanged(fileName);
+    
+    iCallback->ImageListChanged(aIndex, EFalse);
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IESensorDataFilter.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "IESensorDataFilter.h"
+
+CIESensorDataFilter::CIESensorDataFilter()
+    {
+    // No implementation required
+    }
+
+CIESensorDataFilter::~CIESensorDataFilter()
+    {
+    delete iRingBuffer;
+    }
+
+CIESensorDataFilter* CIESensorDataFilter::NewLC()
+    {
+    CIESensorDataFilter* self = new (ELeave) CIESensorDataFilter();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+CIESensorDataFilter* CIESensorDataFilter::NewL()
+    {
+    CIESensorDataFilter* self = CIESensorDataFilter::NewLC();
+    CleanupStack::Pop(); // self;
+    return self;
+    }
+
+void CIESensorDataFilter::ConstructL()
+    {
+    iRingBuffer = new (ELeave) TInt[KDataBufferSize];
+    
+    memset(iRingBuffer, '\0', KDataBufferSize * sizeof (TInt));
+    
+    iRingBufferPointer = iRingBuffer;
+    
+    }
+
+TInt CIESensorDataFilter::FilterSensorData(TInt aNewValue)
+    {
+    // Returns the average of the measures inside the circular buffer avoiding the noise  
+    
+    *iRingBufferPointer = aNewValue;
+    
+    iRingBufferPointer++;
+    
+    if(iRingBufferPointer >= (iRingBuffer + (KDataBufferSize - 1 )))
+        {
+        iRingBufferPointer = iRingBuffer;
+        }
+    
+    TInt sum = 0;
+    for (TInt i = 0; i < KDataBufferSize; i++ )
+        {
+        sum = sum + iRingBuffer[i];
+        }
+        
+    return (sum / KDataBufferSize);
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IESensorMonitor.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,334 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "IESensorMonitor.h"
+#include "debug.h"
+
+#ifdef _ACCELEROMETER_SUPPORTED_
+
+#ifdef _S60_3x_ACCELEROMETER_
+const TInt KAccelerometerSensorUID = 0x10273024;
+#endif
+
+CIESensorMonitor* CIESensorMonitor::NewL(MIESensorMonitorObserver& aSensorObserver)
+{
+    DP0_IMAGIC(_L("CIESensorMonitor::NewL++"));
+    CIESensorMonitor* self=new (ELeave) CIESensorMonitor(aSensorObserver);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    
+    DP0_IMAGIC(_L("CIESensorMonitor::NewL--"));
+    return self;
+}
+
+
+void CIESensorMonitor::ConstructL()
+{
+    DP0_IMAGIC(_L("CIESensorMonitor::ConstructL++"));
+
+#ifdef _S60_3x_ACCELEROMETER_
+    // Noise filter for the accelerometer;
+    iAccSensorDataX = 0;
+    iAccSensorDataY = 0;
+    iAccSensorDataZ = 0;
+
+#ifdef SENSOR_API_LOAD_DYNAMICALLY
+    _LIT( KSensorApiDll, "RRSensorApi" );
+    TUidType dllUid( KDynamicLibraryUid );
+    TInt error = iSensorApi.Load( KSensorApiDll, dllUid );
+    User::LeaveIfError(error);
+#endif    
+    
+    iSensorDataFilterX = CIESensorDataFilter::NewL();
+    iSensorDataFilterY = CIESensorDataFilter::NewL();
+    iSensorDataFilterZ = CIESensorDataFilter::NewL();
+    
+#ifdef SENSOR_API_LOAD_DYNAMICALLY
+    // If Sensor API library is dynamically linked
+    typedef void ( *TFindSensorsLFunction )( RArray<TRRSensorInfo>& ); 
+    TFindSensorsLFunction findSensorsLFunction = ( TFindSensorsLFunction )iSensorApi.Lookup( 1 );
+    findSensorsLFunction( iSensorList );
+#else
+    TRAPD( error , CRRSensorApi::FindSensorsL(iSensorList));
+    if (error)
+    {
+    // Error found in sensors  
+    }
+#endif    
+    
+    TInt sensorCount = iSensorList.Count();
+    
+    for (TInt i = 0; i < sensorCount; i++ )
+    {
+        if (iSensorList[i].iSensorId == KAccelerometerSensorUID)
+        {
+            iAccelerometerSensorIndex = i;       
+            break;
+        }
+    }
+#endif _S60_3x_ACCELEROMETER_
+#ifdef _S60_5x_ACCELEROMETER_
+    
+    DP0_IMAGIC(_L("CIESensorMonitor::ConstructL - create CSensrvChannelFinder"));
+    iSensrvChannelFinder = CSensrvChannelFinder::NewL();
+    DP1_IMAGIC(_L("CIESensorMonitor::ConstructL - CSensrvChannelFinder created: %d"),iSensrvChannelFinder);
+        
+    iChannelInfoList.Reset();
+    TSensrvChannelInfo mySearchConditions; // none, so matches all.
+    DP0_IMAGIC(_L("CIESensorMonitor::ConstructL - iSensrvChannelFinder->FindChannelsL"));
+    TRAPD(err, iSensrvChannelFinder->FindChannelsL(iChannelInfoList, mySearchConditions));
+    if(err != KErrNone)
+        {
+        DP1_IMAGIC(_L("CIESensorMonitor::ConstructL - iSensrvChannelFinder->FindChannelsL ERROR: %d"), err);
+        User::Leave(err);
+        }
+    DP0_IMAGIC(_L("CIESensorMonitor::ConstructL - iSensrvChannelFinder->FindChannelsL - OK"));
+    
+    TInt senIndex(0); // Sensor Selection 
+    
+    TBuf<256> text;
+    text.Append(_L(" ----------------------------FOUND SENSOR=" ));
+    text.AppendNum(iChannelInfoList.Count());
+    DP0_IMAGIC(text);
+    
+    if(senIndex >= 0 && senIndex < iChannelInfoList.Count())
+    {
+        DP0_IMAGIC(_L("CIESensorMonitor::ConstructL++"));
+        iSensrvSensorChannel = CSensrvChannel::NewL( iChannelInfoList[senIndex] );
+        iSensrvSensorChannel->OpenChannelL();
+    }
+    
+#endif //_S60_5x_ACCELEROMETER_
+    
+    DP0_IMAGIC(_L("CIESensorMonitor::ConstructL++"));
+}
+
+
+CIESensorMonitor::CIESensorMonitor(MIESensorMonitorObserver& aSensorObserver)
+    :iSensorObserver(aSensorObserver)
+    {
+    }
+
+
+CIESensorMonitor::~CIESensorMonitor()
+{
+    DP0_IMAGIC(_L("CIESensorMonitor::~CIESensorMonitor"));
+    
+    StopMonitoring();
+    
+#ifdef _S60_3x_ACCELEROMETER_ 
+
+#ifdef SENSOR_API_LOAD_DYNAMICALLY
+    // Close dynamically loaded library
+    iSensorApi.Close();
+#endif //SENSOR_API_LOAD_DYNAMICALLY    
+    
+    delete iAccelerometerSensor;
+    iAccelerometerSensor = NULL;
+#endif
+#ifdef _S60_5x_ACCELEROMETER_ 
+
+    if(iSensrvSensorChannel)
+	    iSensrvSensorChannel->CloseChannel();
+    
+    delete iSensrvSensorChannel;
+    
+    iChannelInfoList.Reset();
+    delete iSensrvChannelFinder;
+    
+#endif
+}
+
+void CIESensorMonitor::StartMonitoring()
+{
+    DP0_IMAGIC(_L("CIESensorMonitor::StartMonitoring+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"));
+
+#ifdef _S60_3x_ACCELEROMETER_
+    
+#ifdef SENSOR_API_LOAD_DYNAMICALLY
+    // If Sensor API library is dynamically linked
+    typedef CRRSensorApi* ( *TNewLFunction )( TRRSensorInfo ); 
+    TNewLFunction newLFunction = ( TNewLFunction )iSensorApi.Lookup( 2 );
+    iAccelerometerSensor = newLFunction( iSensorList[iAccelerometerSensorIndex] );
+#else    
+    iAccelerometerSensor = CRRSensorApi::NewL(iSensorList[iAccelerometerSensorIndex]);
+#endif
+
+    if (iAccelerometerSensor)
+        iAccelerometerSensor->AddDataListener(this);
+#endif
+#ifdef _S60_5x_ACCELEROMETER_
+    if(iSensrvSensorChannel)
+        iSensrvSensorChannel->StartDataListeningL( this, 1,1,iUpdateInterval);         
+#endif
+}
+
+void CIESensorMonitor::StopMonitoring()
+{
+    DP0_IMAGIC(_L("CSensorMonitor::StopMonitoring++"));
+    
+#ifdef _S60_3x_ACCELEROMETER_
+    if(iAccelerometerSensor)
+        iAccelerometerSensor->RemoveDataListener();
+#endif
+#ifdef _S60_5x_ACCELEROMETER_
+    if(iSensrvSensorChannel)
+        iSensrvSensorChannel->StopDataListening();
+    
+#endif
+}
+
+#ifdef _S60_3x_ACCELEROMETER_
+
+void CIESensorMonitor::HandleDataEventL(TRRSensorInfo aSensor, TRRSensorEvent aEvent)
+    {
+    TImagicDeviceOrientation deviceOrientation;
+     // Axis Data
+    switch (aSensor.iSensorId)
+        {
+        case KAccelerometerSensorUID:
+            {
+            iAccSensorDataX = iSensorDataFilterX->FilterSensorData(aEvent.iSensorData1); // X 
+            iAccSensorDataY = iSensorDataFilterY->FilterSensorData(aEvent.iSensorData2); // Y
+            iAccSensorDataZ = iSensorDataFilterZ->FilterSensorData(aEvent.iSensorData3); // Z
+            
+            TInt x = Abs(iAccSensorDataX);
+            TInt y = Abs(iAccSensorDataY);
+            TInt z = Abs(iAccSensorDataZ);
+            
+            // Calculate the orientation of the screen
+            if (x>z && x>z) // Landscape
+                {
+                if (iAccSensorDataX > 0)
+                    deviceOrientation = EOrientationDisplayRigthUp;
+                else
+                    deviceOrientation = EOrientationDisplayLeftUp;
+                }
+            if (y>x && y>z) // Portrait Mode
+                {
+                if (iAccSensorDataY > 0)
+                    deviceOrientation = EOrientationDisplayUp;
+                else
+                    deviceOrientation = EOrientationDisplayDown;
+                
+                }
+            //if (z>x && z>y)  
+            //    {
+            //    if (iAccSensorDataZ)
+                  //Not used  deviceOrientation = EOrientationDisplayDownwards;
+            //    else
+                  //Not used  deviceOrientation = EOrientationDisplayUpwards;
+            //    } 
+            
+            iSensorObserver.SensorDataAvailable(deviceOrientation, EFalse);
+            
+            }
+            break;
+        default:
+            break;
+        }
+    }
+#endif
+#ifdef _S60_5x_ACCELEROMETER_
+
+ _LIT( KTimeString, "%-B%:0%J%:1%T%:2%S%.%*C4%:3%+B" );
+ 
+void CIESensorMonitor::DataReceived( CSensrvChannel& aChannel, TInt aCount, TInt aDataLost )
+{
+    DP0_IMAGIC(_L("CSensorMonitor::DataReceived"));
+    
+    TBuf<250> progressBuf;
+	
+	TInt errErr(KErrNone);
+	
+	//iDataLostCount = iDataLostCount + aDataLost;
+	//iDataCount = iDataCount + aCount;
+
+	if( aChannel.GetChannelInfo().iChannelType == KSensrvChannelTypeIdOrientationData )
+	{
+		TSensrvOrientationData data;
+		
+		//TRAP(errErr,
+		for( TInt i = 0; i < aCount; i++ )
+	    {
+	    	TPckgBuf<TSensrvOrientationData> dataBuf;
+	    	aChannel.GetData( dataBuf );
+	    	data = dataBuf();
+	    	data.iTimeStamp.FormatL(progressBuf, KTimeString );
+	    }
+
+	    if(errErr != KErrNone)
+	    {
+	    	progressBuf.Zero();
+	    }
+	
+    	switch ( data.iDeviceOrientation )
+        {
+        case EOrientationDisplayUp:
+            {
+            progressBuf.Append( _L( "Display up" ) );
+            DP1_IMAGIC( _L( "Display up: %d" ),data.iDeviceOrientation );
+            break;
+            }
+        case EOrientationDisplayDown:
+            {
+            progressBuf.Append( _L( "Display down" ) );
+            DP1_IMAGIC( _L( "Display down: %d" ),data.iDeviceOrientation );
+            break;
+            }
+        case EOrientationDisplayLeftUp:
+            {
+            progressBuf.Append( _L( "Display left up" ) );
+            DP1_IMAGIC( _L( "Display left up: %d" ),data.iDeviceOrientation );
+            break;
+            }
+        case EOrientationDisplayRigthUp:
+            {
+            progressBuf.Append( _L( "Display right up" ) );
+            DP1_IMAGIC( _L( "Display right up: %d" ),data.iDeviceOrientation );
+            break;
+            }
+        default:
+            {
+            progressBuf.Append( _L( "Unknown orientation" ) );
+            DP1_IMAGIC( _L( "Unknown orientation: %d" ),data.iDeviceOrientation );
+            break;
+            }
+        }
+    	iSensorObserver.SensorDataAvailable(TImagicDeviceOrientation(data.iDeviceOrientation), EFalse);
+	}
+	else
+	{
+		progressBuf.Copy(_L("Channel = " ));
+	    progressBuf.AppendNum(aChannel.GetChannelInfo().iChannelType,EHex);
+	}
+	
+	DP0_IMAGIC(progressBuf);
+	
+}
+
+void CIESensorMonitor::DataError( CSensrvChannel& /*aChannel*/, TSensrvErrorSeverity /*aError*/)
+{
+    DP0_IMAGIC(_L("CIESensorMonitor::DataReceived"));
+}
+
+#endif //_S60_5x_ACCELEROMETER_
+
+#endif //_ACCELEROMETER_SUPPORTED_
+// End of File
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/IEThreadEngine.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,221 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// INCLUDES
+#include <e32base.h> 
+#include <aknnotewrappers.h>
+
+#include "IEThreadEngine.h"
+#include "IEImageFinder.h"
+#include "ImagicConsts.h"
+
+
+// ----------------------------------------------------------------------------
+// CFileFinderThread::CFileFinderThread(CSharedIntermediator* aSMediator)
+//
+// Constructor.
+// ----------------------------------------------------------------------------
+CFileFinderThread::CFileFinderThread(
+        CIEFileLoader* aFileLoader, 
+        RArray<CImageData*>& aFileNameData, 
+        RArray<CImageData*>& aFaceFileNameData,
+        RCriticalSection* aCritical,
+        TDesC& aFileName) :
+    iCreatedThreads(EFalse),
+    iFileLoader(aFileLoader),
+    iFileNameData(aFileNameData),
+    iFaceFileNameData(aFaceFileNameData),
+    iCritical(aCritical)
+    {
+	iFilename.Copy(aFileName);
+	}
+
+// ----------------------------------------------------------------------------
+// CFileFinderThread::~CFileFinderThread(void)
+//
+// Destructor.
+// ----------------------------------------------------------------------------
+CFileFinderThread::~CFileFinderThread(void)
+	{
+	DP0_IMAGIC(_L("CFileFinderThread::~CFileFinderThread++"));
+	
+	if(iSMediator)
+	{
+		delete iSMediator;
+		iSMediator = NULL;
+	}
+	
+	// Thread should be killed allready, if thread is already killed this does nothing
+	iThreadOne.Kill(KErrNone);
+	
+	// Handles should be closed
+	iThreadOne.Close();
+	DP0_IMAGIC(_L("CFileFinderThread::~CFileFinderThread--"));
+	}
+
+CFileFinderThread* CFileFinderThread::NewL(
+        CIEFileLoader* aFileLoader,  
+        RArray<CImageData*>& aFileNameData, 
+        RArray<CImageData*>& aFaceFileNameData,
+        RCriticalSection* aCritical,
+        TDesC& aFileName)
+	{
+	CFileFinderThread* self = CFileFinderThread::NewLC(
+	        aFileLoader, 
+	        aFileNameData, 
+	        aFaceFileNameData,
+	        aCritical,
+	        aFileName);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CFileFinderThread* CFileFinderThread::NewLC(
+        CIEFileLoader* aFileLoader,  
+        RArray<CImageData*>& aFileNameData,
+        RArray<CImageData*>& aFaceFileNameData,
+        RCriticalSection* aCritical,
+        TDesC& aFileName)
+	{
+	CFileFinderThread* self = new (ELeave) CFileFinderThread(
+	        aFileLoader, 
+	        aFileNameData,
+	        aFaceFileNameData,
+	        aCritical,
+	        aFileName);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+// Standard Symbian OS 2nd phase constructor
+void CFileFinderThread::ConstructL()
+	{
+	DP0_IMAGIC(_L("CFileFinderThread::ConstructL ++ --"));
+	}
+
+void CFileFinderThread::StartL()
+	{
+	DP0_IMAGIC(_L("CFileFinderThread::Start++"));
+	// Create threads only once
+	if ( iCreatedThreads == EFalse )
+		{
+		CreateThreadsL();
+		}
+	DP0_IMAGIC(_L("CFileFinderThread::Start--"));
+	}
+
+
+void CFileFinderThread::Stop()
+	{
+	//TRequestStatus aStatus;
+	//iThreadOne.Logon(aStatus);
+	//iThreadOne.Suspend();
+	}
+
+// ----------------------------------------------------------------------------
+// CFileFinderThread::ExecuteThread(TAny *aPtr)
+//
+// Threadfunction of threadOne. Executed only by threadOne.
+// ----------------------------------------------------------------------------
+TInt CFileFinderThread::ExecuteThreadOne(TAny *aPtr)
+	{
+	DP0_IMAGIC(_L("CFileFinderThread::ExecuteThreadOne++"));
+	
+	CMediator* aSMediator = static_cast<CMediator*>( aPtr );
+	
+	//Create cleanupstack	
+	CTrapCleanup* cleanupStack = CTrapCleanup::New();
+	
+	//Test cleanup stack, additional cleanup stack must be prosessed under
+	//TRAP
+    //We can't use low level cleanup stack handling
+	TRAPD(error, CFileFinderThread::CreateFileFinderL(aSMediator));
+
+	delete cleanupStack;
+	
+	DP0_IMAGIC(_L("CFileFinderThread::ExecuteThreadOne--"));
+	
+	return 0;
+	}
+
+
+// ----------------------------------------------------------------------------
+// CFileFinderThread::CreateActiveScheduler(CSharedIntermediator* aSMediator)
+//
+// Create ActiveScheduler for thread1.
+// ----------------------------------------------------------------------------
+void CFileFinderThread::CreateFileFinderL(CMediator* aSMediator)
+	{
+	DP0_IMAGIC(_L("CFileFinderThread::CreateFileFinderL++"));
+	// create a new active scheduler
+	CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
+	CleanupStack::PushL(activeScheduler);
+
+	// use static function Install to install previously created scheduler
+	CActiveScheduler::Install(activeScheduler);
+	
+	//Create and use iTNImageFinder to handle in backround AO iFileNameData array filling
+	CIEImageFinder* TNImageFinder = new (ELeave) CIEImageFinder(
+	        aSMediator->iFileLoader, 
+            *aSMediator->iFileNameData,
+            *aSMediator->iFaceFileNameData,
+            aSMediator->iCritical);
+    
+	CleanupStack::PushL(TNImageFinder);
+	TNImageFinder->ConstructL();
+	TNImageFinder->StartFinderL(KFileString);
+
+	DP0_IMAGIC(_L("CFileFinderThread::CreateFileFinderL finder ended"));
+	aSMediator->iFileLoader->ImageFinderStopped();
+	aSMediator->iFileLoader->AllFilesAddedToFilenameArray();
+	
+	// Start active scheduler
+    //CActiveScheduler::Start();
+    
+    // Remove and delete scheduler and the rest.
+	CleanupStack::PopAndDestroy(2);
+	DP0_IMAGIC(_L("CFileFinderThread::CreateFileFinderL--"));
+	}
+
+
+// ----------------------------------------------------------------------------
+// CFileFinderThread::CreateThreadsL()
+//
+// Create thread1 and resume it. Activate thread1 listener.
+// ----------------------------------------------------------------------------
+void CFileFinderThread::CreateThreadsL()
+	{
+	DP0_IMAGIC(_L("CFileFinderThread::CreateThreadsL++"));
+	iSMediator = new (ELeave) CMediator();
+	
+	iSMediator->iFileLoader = iFileLoader;
+    iSMediator->iFileNameData = &iFileNameData;
+    iSMediator->iFaceFileNameData = &iFaceFileNameData;
+    iSMediator->iCritical = iCritical;
+    iSMediator->iFileName = iFilename;
+    
+	// Create thread which uses the same heap as main program.
+	iThreadOne.Create(_L("FileFinderThread"), ExecuteThreadOne, 12040, NULL, iSMediator);
+	//EPriorityNormal, EPriorityLess, EPriorityMuchLess
+	iThreadOne.SetPriority(EPriorityMuchLess);
+	iThreadOne.Resume();
+	
+	iCreatedThreads = ETrue;
+	DP0_IMAGIC(_L("CFileFinderThread::CreateThreadsL--"));
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EngSrc/ImageMonitorAO.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "IEEngineImp.h"
+#include "ImageMonitorAO.h"
+
+// Here Engine pointer is not required 
+// we will define one internal observer class between Engine and ImageMonitor thread
+// 
+    
+CImageMonitorAO* CImageMonitorAO::NewL(CIEEngineImp* aEngImp)
+{
+CImageMonitorAO* self = new(ELeave) CImageMonitorAO(aEngImp);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+}
+
+CImageMonitorAO* CImageMonitorAO::NewLC(CIEEngineImp* aEngImp)
+    {
+    CImageMonitorAO* self = new(ELeave) CImageMonitorAO(aEngImp);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+ 
+CImageMonitorAO::CImageMonitorAO(CIEEngineImp* aEngImp) :
+        CActive(CActive::EPriorityLow),
+        iEngImp(aEngImp)
+        
+    {
+    CActiveScheduler::Add(this);
+    }
+
+void CImageMonitorAO::ConstructL()
+    {
+        
+    }
+
+
+CImageMonitorAO::~CImageMonitorAO()
+    {
+    Cancel();
+    }
+ 
+void CImageMonitorAO::RunL()
+    {
+    iEngImp->AllFilesAddedToFilenameArrayL();
+    }
+
+ 
+void CImageMonitorAO::DoCancel()
+    {
+    }
+
+ 
+void CImageMonitorAO::RunError()
+    {
+    // Nothing here
+    }
+
+//This name should be changed to IssueActiveRequest()
+//This is more meaningful...
+void CImageMonitorAO::ActiveRequest()
+    {
+    if(!IsActive())
+        SetActive();
+    }
+
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/group/IEBgpClient.mmp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "UidList.txt"
+
+TARGET        IEBgpClient.dll
+TARGETTYPE    dll
+UID           0xE000008d IEBgpsclient_UID3
+
+#ifdef TUBE_PR1
+CAPABILITY		UserEnvironment ReadDeviceData ReadUserData WriteUserData LocalServices
+#else
+CAPABILITY		UserEnvironment ReadUserData WriteUserData LocalServices
+#endif
+
+EPOCHEAPSIZE 0x10000 0x8000000
+
+VENDORID 0
+
+SOURCEPATH    ..\src
+SOURCE        IEImageProcessingImp.cpp
+SOURCE		  	IEBgpClient.cpp
+
+USERINCLUDE   ..\inc
+USERINCLUDE   ..\..\common\inc
+USERINCLUDE   ..\..\EngInc
+SYSTEMINCLUDE \Epoc32\include
+
+LIBRARY       euser.lib
+LIBRARY 			IEBgps.lib
+ 
+// EXPORTUNFROZEN 
+nostrictdef
+
+SOURCE IEImagicGBPSAO.cpp
+
+EXPORTUNFROZEN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/group/bld.inf	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// ====================================================================
+// BLD.INF
+//
+// ====================================================================
+
+PRJ_PLATFORMS
+default
+
+PRJ_EXPORTS
+ 
+..\inc\IEImageProcessing.h		\epoc32\include\IEImageProcessing.h
+ 
+ 
+
+PRJ_MMPFILES
+IEBgpClient.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/inc/IEBGPSTrace.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBGPSTRACE_H__
+#define __IEBGPSTRACE_H__
+
+#define _DEBUG
+#ifdef _DEBUG
+
+#include <e32debug.h>
+
+#define IEBGPSPRINT(x)	RDebug::Print x;
+
+#else
+
+#define IEBGPSPRINT(x)	
+
+#endif // _DEBUG
+
+
+#endif //__IEBGPSTRACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/inc/IEBgpClient.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBGPCLIENT_H__
+#define __IEBGPCLIENT_H__
+
+// Include files
+#include <e32base.h>
+#include <IEImageProcessing.h>
+#include <IEBgpsInfo.h>
+
+/**
+ * EIGBPS client 
+ * 
+ */
+class RIEBgpClient : public RSessionBase
+{
+public:
+	/**
+	Connects to the server, creates a session.
+	
+	@return - it returns KErrNone if connection is successful, else error code
+	*/	
+	TInt Connect();
+	
+	/**
+	Disconnects from the server.
+	*/
+	void Disconnect();
+	
+	/**
+	Gets the session ID.
+	
+	@return - it returns the session id with the server.
+	*/
+	TInt SessionId();
+	
+	/**
+	Gets the version of the server
+	
+	@return - it returns the version of the server
+	*/
+	TVersion Version() const;
+	
+	/**
+	Closes the session with the server. Destroy kernel side object also.
+	*/
+	void Close();
+	
+	/**
+     * Overloaded function generates Thumbnails. 
+     *  
+     * @Param aMGDir - Jpeg File with absolute path.
+     * @aImageArrary aTNDir - Thumbnail file name with abolutepath
+     */ 
+	void GenerateThumbnails(TRequestStatus &aStatus, const TDesC& aMGDir,  const TDesC& aTNDir);
+	
+	/**
+     * Overloaded function generates Thumbnails. 
+     * 
+     * @Param aMGDir - Jpeg File with absolute path.
+     * @param aImageArrary aTNDir - Thumbnail file name with abolutepath
+     * @Param aSize - Thumbnail size.
+     */ 
+	void GenerateThumbnails(TRequestStatus &aStatus, const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize);
+	void GenerateThumbnails(TRequestStatus &aStatus, const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize, CFbsBitmap* aSrcBitmap);
+	void CancelTNGeneration();
+	
+private: 
+    /** Server Thread **/
+	RThread iServerThread;	
+	
+	/** Jpeg file name **/
+	TFileName iJpegFileName;
+	
+	/** Gallery file name **/
+	TFileName iGalleryFileName;
+	/** Thumbmail size**/
+	TSize iSize;
+	
+	TFileName iTempFileName;
+};
+
+#endif // __IEBGPCLIENT_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/inc/IEImageProcessing.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEPROCESSING_H__
+#define __IEIMAGEPROCESSING_H__
+
+// Include files
+#include <e32base.h>
+#include "IEBgpsInfo.h"
+#include "IEImageData.h"
+#include <FBS.H> //CFbsBitmap
+
+// Forward class declarations
+
+/**
+ *  Observer class. Provides the interface functions
+ *   
+ */ 
+class MIETNObserver
+{
+public:
+    /**
+     *  When Thumbnail Genration is completed IEBGPS client
+     *  call this function.
+     *   
+     * @param aErrorCode - Systemwide error code in case of error 
+     *                   - KErrNone in case of no errors.
+     */ 
+	virtual void ThumbnailGenerationCompleted(TInt aErrorCode) = 0;
+	virtual void ThumbnailGenerationCancelled(TInt aErrorCode) = 0;
+	
+	/**
+     *  When Thumbnail Genration is completed IEBGPS client
+     *  calls this function.
+     *   
+     * @param aErrorCode - Systemwide error code in case of error 
+     *                   - KErrNone in case of no errors.
+     */ 
+	virtual void HandleError(TInt aError) = 0;
+		
+};
+
+/**
+ *  Thumbnail generation class.
+ */ 
+class CIEImageProcessing : public CBase
+{
+public:
+    /**
+     *  Symbian First phase constructor to create Imageprocessing Object
+     * 
+     * @param aObserver - Thumbnail observer
+     */ 
+	IMPORT_C static CIEImageProcessing* NewL(MIETNObserver& aObserver);
+	
+	/**
+     * Overloaded function generates Thumbnails. 
+     *  
+     * @Param  aMGDir - Jpeg File with absolute path.
+     * @parama aTNDir - Thumbnail file name with abolutepath
+     */
+	IMPORT_C virtual void GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir) = 0;
+	/**
+     * Overloaded function generates Thumbnails. 
+     * 
+     * @Param aMGDir - Jpeg File with absolute path.
+     * @param aImageArrary aTNDir - Thumbnail file name with abolutepath
+     * @Param aSize - Thumbnail size.
+     */ 
+	IMPORT_C virtual void GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize) = 0;
+	
+	IMPORT_C virtual void GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize, CFbsBitmap* aSrcBitmap) = 0;
+	
+	IMPORT_C virtual void CancelTNGeneration() = 0;
+		
+};
+
+#endif // __IEIMAGEPROCESSING_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/inc/IEImageProcessingImp.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEPROCESSINGIMP_H__
+#define __IEIMAGEPROCESSINGIMP_H__
+
+#include <IEBgpsInfo.h>
+
+#include <IEImageProcessing.h>
+
+#include "IEImagicBGPSAO.h"
+
+// Include files
+
+#include "IEBgpClient.h"
+
+class CImagicBGPSAO;
+// Forward class declarations
+
+/**
+ * Thumbnail generation implementation class.
+ */ 
+class CIEImageProcessingImp : public CIEImageProcessing,public MIETNInternalObserver
+{
+public:
+    /**
+     * Symbian 1st Phase construction.
+     * Creation implementatation class.
+     * 
+     * @param aObserver - Thumbnail Observer
+     */
+	static CIEImageProcessingImp* NewL(MIETNObserver& aObserver);
+	/**
+     * Destructor.
+     *
+     */
+	~CIEImageProcessingImp();
+private:
+	void ConstructL();
+	CIEImageProcessingImp(MIETNObserver& aObserver);
+
+private: // from MIETNInternalObserver
+    /**
+     *  When Thumbnail generation is completed this method is 
+     *  called.
+     * 
+     * @param  aErrorCode - KErrNone in case of no error otherwise
+     *                    - System wide error code
+     */
+	void HandleEvents(TInt aErrorCode);
+	
+private: // From CIEImageProcessing	 	
+	void GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir);
+	void GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize);
+	void GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize, CFbsBitmap* aSrcBitmap);
+	void CancelTNGeneration();
+
+private: // Data members
+    /** Observer reference **/
+	MIETNObserver& iObserver;
+	/** Client **/
+	RIEBgpClient iIEBgpClient;	
+	/** TNCreation Active object pointer **/
+	CImagicBGPSAO *iImagicBGPSAO;
+};
+
+#endif // __IEIMAGEPROCESSINGIMP_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/inc/IEImagicBGPSAO.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,88 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IETNCREATOR_H__
+#define __IETNCREATOR_H__
+
+#include <IEImageProcessing.h>
+#include <IEBgpsInfo.h>
+
+/**
+ *  Internal Observer class between client and server
+ */ 
+class MIETNInternalObserver
+{
+public:
+    /**
+    *  When Thumbnail generation is completed this method is 
+    *  called from RunL.
+    * 
+    * @param  aErrorCode - KErrNone in case of no error otherwise
+    *                    - System wide error code
+    */
+	virtual void HandleEvents(TInt aErrorCode) = 0;
+};
+/**
+ *  ThumbnailCreator class
+ */ 
+class  CImagicBGPSAO : public CActive
+{
+public:
+    /**
+     * Symbian 1st Phase construction.
+     * Creating CImagicBGPSAO object.
+     * 
+     * @param aIETNObserver - Internal observer between client and server
+     * @return A pointer to a new instance of the CImagicBGPSAO class.
+     */
+	static CImagicBGPSAO* NewL(MIETNInternalObserver& aIETNObserver);
+	
+	/**
+	 * Destructor.
+	 */
+	virtual ~CImagicBGPSAO();
+	
+private:
+	void ConstructL();
+	CImagicBGPSAO(MIETNInternalObserver& aIETNObserver);
+	
+protected: // From CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+	
+public:  
+    /**
+     * Activate Thumbnail genration request.
+     * 
+     */
+	void ActivateTNCreatorAO();
+	
+	/**
+     * Cancels Thumbnail genration request.
+     * 
+     */
+	void DeActivateTNCreatoAO();
+	
+private:
+    /** Internal observer reference **/
+    MIETNInternalObserver &iIETNObserver;
+};
+
+#endif
+
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/inc/debug.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IMAGIC_TRACE_H__
+#define __IMAGIC_TRACE_H__
+
+//#define _IMAGIC_DEBUG
+#ifdef _IMAGIC_DEBUG
+
+#include <e32debug.h>
+
+#define DP0_IMAGIC(string)                            RDebug::Print(string)
+#define DP1_IMAGIC(string,arg1)                       RDebug::Print(string,arg1)
+#define DP2_IMAGIC(string,arg1,arg2)                  RDebug::Print(string,arg1,arg2)
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             RDebug::Print(string,arg1,arg2,arg3)
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        RDebug::Print(string,arg1,arg2,arg3,arg4)
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)   RDebug::Print(string,arg1,arg2,arg3,arg4,arg5)
+
+#else
+
+#define DP0_IMAGIC(string)                            
+#define DP1_IMAGIC(string,arg1)                       
+#define DP2_IMAGIC(string,arg1,arg2)                  
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)
+#endif // _DEBUG
+
+
+#endif //__IMAGIC_TRACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/src/IEBgpClient.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,149 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include <IEBgpsInfo.h>
+#include "debug.h"
+#include "IEBgpClient.h"
+
+
+//const TInt KTimeDelay = 2000000;
+//const TInt KTimeDelay = 100000;
+const TInt KTimeDelay = 10000;
+
+/**
+ *  Create server thread, session.
+ *  returns KErrNone in case of no error otherwise
+ *  system wide error code.
+ */
+TInt RIEBgpClient::Connect()
+{
+	DP0_IMAGIC((_L("RIEBgpClient::Connect ++")));
+	TInt error = KErrNone;
+	
+	// First create the server thread
+	DP0_IMAGIC((_L("RIEBgpClient::Connect - Start creating ServerThread")));
+	error = CreateServerThread(iServerThread);
+	DP0_IMAGIC((_L("RIEBgpClient::Connect - ServerThread created")));
+	
+	if(error != KErrNone)
+		return error;	
+	else
+	    {
+	    //User::After( KTimeDelay );
+		error = CreateSession(KIEBgpServerName, Version(), KIEDefaultMsgSlot);
+		DP0_IMAGIC((_L("RIEBgpClient::Connect - Create session finished")));
+	}		
+	DP0_IMAGIC((_L("RIEBgpClient::Connect --")));
+	return error;
+}
+
+/** 
+ * Close the client 
+ */
+void RIEBgpClient::Disconnect()
+{
+	DP0_IMAGIC((_L("RIEBgpClient::Disconnect ++")));
+	Close();
+	DP0_IMAGIC((_L("RIEBgpClient::Disconnect --")));
+}
+
+TInt RIEBgpClient::SessionId()
+{
+	return KErrNone;
+}
+
+/** client version*/
+TVersion RIEBgpClient::Version() const
+{
+	DP0_IMAGIC((_L("RIEBgpClient::Version ++")));
+	return (TVersion(KIEBgpServerMajorVersion, 
+				KIEBgpServerMinorVersion, 
+				KIEBgpServerBuildVersion));
+	
+}
+/**
+ *  Closes server thread and session.
+ */
+void RIEBgpClient::Close()
+{
+	
+	DP0_IMAGIC((_L("RIEBgpClient::Close ++")));
+	DP0_IMAGIC((_L("RIEBgpClient::Close 1")));
+	TInt err = SendReceive(EIECancelThumbnailGeneration);
+    DP0_IMAGIC((_L("RIEBgpClient::Close 2")));		
+	iServerThread.Close();
+	
+	RSessionBase::Close();
+	
+	DP0_IMAGIC((_L("RIEBgpClient::Close --")));
+}
+
+void RIEBgpClient::GenerateThumbnails(TRequestStatus &aStatus, const TDesC& aMGDir, const TDesC& aTNDir)
+{
+	DP0_IMAGIC((_L("RIEBgpClient::GenerateThumbnails ++")));
+	
+	iJpegFileName.Copy(aMGDir);
+	iGalleryFileName.Copy(aTNDir);
+	
+	TIpcArgs args(&iJpegFileName, &iGalleryFileName);
+	
+	SendReceive(EIESingleTNGeneration,args,aStatus);
+	
+	DP0_IMAGIC((_L("RIEBgpClient::GenerateThumbnails --")));
+}
+
+void RIEBgpClient::CancelTNGeneration()
+{
+    DP0_IMAGIC((_L("RIEBgpClient::CancelTNGeneration ++")));
+    
+    SendReceive(EIECancelThumbnailGeneration);
+    
+    DP0_IMAGIC((_L("RIEBgpClient::CancelTNGeneration --")));
+}
+
+void RIEBgpClient::GenerateThumbnails(TRequestStatus &aStatus, const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize)
+{
+	DP0_IMAGIC((_L("RIEBgpClient::GenerateThumbnails ++")));
+	
+	iJpegFileName.Copy(aMGDir);
+	iGalleryFileName.Copy(aTNDir);
+	iSize = aSize;
+	
+	TIpcArgs args(&iJpegFileName, &iGalleryFileName, &iSize);
+	
+	SendReceive(EIESingleTNGeneration,args,aStatus);
+	
+	DP0_IMAGIC((_L("RIEBgpClient::GenerateThumbnails --")));
+}
+
+void RIEBgpClient::GenerateThumbnails(TRequestStatus &aStatus, const TDesC& aMGDir, const TDesC& aTNDir, 
+                                      const TSize &aSize, CFbsBitmap* aSrcBitmap)
+{
+    DP0_IMAGIC((_L("RIEBgpClient::GenerateThumbnails ++")));
+    
+    iJpegFileName.Copy(aMGDir);
+    iGalleryFileName.Copy(aTNDir);
+    iSize = aSize;
+    
+    TIpcArgs args(&iJpegFileName, &iGalleryFileName, &iSize, &aSrcBitmap);
+    
+    SendReceive(EIESingleTNGenerationWithBitmap,args,aStatus);
+    
+    DP0_IMAGIC((_L("RIEBgpClient::GenerateThumbnails --")));
+}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/src/IEImageProcessingImp.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,154 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "IEImageProcessingImp.h"
+
+#include "IEImagicBGPSAO.h"
+#include "debug.h"
+
+EXPORT_C CIEImageProcessing* CIEImageProcessing::NewL(MIETNObserver& aObserver)
+    {
+	DP0_IMAGIC((_L("CIEImageProcessing::NewL ++")));
+	return CIEImageProcessingImp::NewL(aObserver);
+    }
+
+CIEImageProcessingImp* CIEImageProcessingImp::NewL(MIETNObserver& aObserver)
+    {
+	CIEImageProcessingImp* self = new (ELeave) CIEImageProcessingImp(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+    }
+
+CIEImageProcessingImp::~CIEImageProcessingImp()
+    {
+	DP0_IMAGIC((_L("CIEImageProcessingImp::~CIEImageProcessingImp ++")));
+
+	if(iImagicBGPSAO)
+	{
+	delete iImagicBGPSAO;	
+	iImagicBGPSAO = NULL;
+	}
+	
+	iIEBgpClient.Close();
+	
+	DP0_IMAGIC((_L("CIEImageProcessingImp::~CIEImageProcessingImp --")));
+    }
+
+CIEImageProcessingImp::CIEImageProcessingImp(MIETNObserver& aObserver)
+    : iObserver(aObserver)
+    {
+    DP0_IMAGIC((_L("CIEImageProcessingImp::CIEImageProcessingImp ++")));
+    DP0_IMAGIC((_L("CIEImageProcessingImp::CIEImageProcessingImp --")));	
+    }
+
+void CIEImageProcessingImp::ConstructL()
+    {
+	DP0_IMAGIC((_L("CIEImageProcessingImp::ConstructL ++")));
+	User::LeaveIfError(iIEBgpClient.Connect());
+	iImagicBGPSAO = CImagicBGPSAO::NewL(*this);
+    }
+
+void CIEImageProcessingImp::HandleEvents(TInt aErrorCode)
+    {
+    DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents++")));
+    
+    switch(aErrorCode)
+        {
+        case ETNGenerationCancelled:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - ETNGenerationCancelled")));
+            iObserver.ThumbnailGenerationCancelled(KErrNone);
+            break;
+        case ETNGenerationcomplete:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - ETNGenerationcomplete")));
+            iObserver.ThumbnailGenerationCompleted(KErrNone);
+            break;
+        /*case EFaceDetectionComplete:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - EFaceDetectionComplete")));
+            iObserver.FaceDetectionComplete(KErrNone);
+            break;
+        case EFaceCroppingComplete:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - EFaceCroppingComplete")));
+            iObserver.FaceCroppingComplete(KErrNone);
+            break;
+        case EFaceAddedToExif:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - EFaceAddedToExif")));
+            iObserver.FaceCoordinatesAdded(aErrorCode);
+            break;
+        case EFaceRemovedFromExif:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - EFaceRemovedFromExif")));
+            iObserver.FaceCoordinatesRemoved(aErrorCode);
+            break;
+        case ESingleFaceDetectionComplete:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - ESingleFaceDetectionComplete")));
+            iObserver.SingleFaceDetectionComplete(KErrNone);
+            break;
+        case EFaceDetectionCancelled:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - EFaceDetectionCancelled")));
+            iObserver.StartSingleFaceDetection();*/
+        default:
+            DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents - Error in BGPS processing")));
+            iObserver.HandleError(aErrorCode);
+            break;
+        }	
+    DP0_IMAGIC((_L("CIEImageProcessingImp::HandleEvents--")));
+    } 
+
+
+void CIEImageProcessingImp::GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir)
+    {
+	DP0_IMAGIC((_L("CIEImageProcessingImp::GenerateTN ++")));
+
+	iIEBgpClient.GenerateThumbnails(iImagicBGPSAO->iStatus,aMGDir,aTNDir);
+	iImagicBGPSAO->ActivateTNCreatorAO();
+
+	DP0_IMAGIC((_L("CIEImageProcessingImp::GenerateTN --")));
+    }
+
+void CIEImageProcessingImp::CancelTNGeneration()
+    {
+    DP0_IMAGIC((_L("CIEImageProcessingImp::CancelTNGeneration ++")));
+
+    iIEBgpClient.CancelTNGeneration();
+
+    DP0_IMAGIC((_L("CIEImageProcessingImp::CancelTNGeneration --")));
+    }
+
+
+void CIEImageProcessingImp::GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize)
+    {
+	DP0_IMAGIC((_L("CIEImageProcessingImp::GenerateTN ++")));
+
+	iIEBgpClient.GenerateThumbnails(iImagicBGPSAO->iStatus,aMGDir,aTNDir,aSize);
+	iImagicBGPSAO->ActivateTNCreatorAO();
+
+	DP0_IMAGIC((_L("CIEImageProcessingImp::GenerateTN --")));
+    }
+
+void CIEImageProcessingImp::GenerateTN(const TDesC& aMGDir, const TDesC& aTNDir, const TSize &aSize, CFbsBitmap* aSrcBitmap)
+    {
+    DP0_IMAGIC((_L("CIEImageProcessingImp::GenerateTN ++")));
+
+    iIEBgpClient.GenerateThumbnails(iImagicBGPSAO->iStatus,aMGDir,aTNDir,aSize,aSrcBitmap);
+    iImagicBGPSAO->ActivateTNCreatorAO();
+
+    DP0_IMAGIC((_L("CIEImageProcessingImp::GenerateTN --")));
+    }
+
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgpClient/src/IEImagicGBPSAO.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include "IEImagicBGPSAO.h"
+#include "debug.h"
+
+CImagicBGPSAO* CImagicBGPSAO::NewL(MIETNInternalObserver& aObserver)
+{
+	CImagicBGPSAO* self = new (ELeave) CImagicBGPSAO(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CImagicBGPSAO::~CImagicBGPSAO()
+{
+    DP0_IMAGIC((_L("CIETNGeneratorAO::SetImageArray --")));
+    DeActivateTNCreatoAO();
+    DP0_IMAGIC((_L("CIETNGeneratorAO::SetImageArray --")));
+}
+
+//EPriorityIdle, EPriorityLow, EPriorityStandard, EPriorityUserInput, EPriorityHigh
+CImagicBGPSAO::CImagicBGPSAO(MIETNInternalObserver& aObserver)
+: CActive(EPriorityIdle),
+iIETNObserver(aObserver)
+{
+    
+}
+
+void CImagicBGPSAO::ConstructL()
+{
+	CActiveScheduler::Add(this);
+}
+
+void CImagicBGPSAO::RunL()
+{
+	TInt error = iStatus.Int();
+	iIETNObserver.HandleEvents((TBGPSEventCode)iStatus.Int());
+}
+
+void CImagicBGPSAO::DoCancel()
+{	
+}
+
+TInt CImagicBGPSAO::RunError(TInt /*aError*/)
+{
+	return KErrNone;
+}
+
+void CImagicBGPSAO::ActivateTNCreatorAO()
+{
+	if(!IsActive())
+		SetActive();
+}
+
+void CImagicBGPSAO::DeActivateTNCreatoAO()
+{
+    DP0_IMAGIC((_L("CIETNGeneratorAO::DeActivateTNCreatoAO ++")));
+	if(IsActive())
+		Cancel();
+	DP0_IMAGIC((_L("CIETNGeneratorAO::DeActivateTNCreatoAO --")));
+}
+
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/group/IEBgps.mmp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+//#include <domain/osextensions/platform_paths.hrh> // For the MW_LAYER_SYSTEMINCLUDE
+
+#include "UidList.txt"
+
+TARGET        IEBgps.dll
+TARGETTYPE    dll
+UID           0xA000008d IEBgps_UID3
+
+#ifdef TUBE_PR1
+CAPABILITY		UserEnvironment ReadDeviceData ReadUserData WriteUserData LocalServices
+#else
+CAPABILITY		UserEnvironment ReadUserData WriteUserData LocalServices
+#endif
+VENDORID 0
+
+EPOCHEAPSIZE 0x10000 0x3000000
+EPOCSTACKSIZE	0x10000
+
+SOURCEPATH    ..\src
+SOURCE        IEBgpServer.cpp
+SOURCE	      IEBgpServerSession.cpp
+SOURCE  	  IETNGenerator.cpp IEFaceBrowser.cpp IEImageDecoder.cpp IEImageEncoder.cpp
+//SOURCE		  FaceRecognitionEngine.cpp
+
+USERINCLUDE   ..\inc
+USERINCLUDE   ..\..\Common\inc
+USERINCLUDE   ..\..\EngInc
+SYSTEMINCLUDE \Epoc32\include
+SYSTEMINCLUDE   \epoc32\include\stdapis
+SYSTEMINCLUDE   \epoc32\include\icl
+
+// new S60 5.0 header include path
+MW_LAYER_SYSTEMINCLUDE
+ 
+/* Image DL dependent */
+SYSTEMINCLUDE   \epoc32\include\ImagingDL\API
+SYSTEMINCLUDE   \epoc32\include\ImagingDL\Features
+
+LIBRARY       euser.lib
+LIBRARY	      efsrv.lib
+LIBRARY 	  imageconversion.lib  
+LIBRARY 	  fbscli.lib 
+LIBRARY       hal.lib
+LIBRARY       bitmaptransforms.lib 
+LIBRARY 	  exiflib.lib
+LIBRARY		  IclExtJpegApi.lib 
+LIBRARY       bafl.lib
+LIBRARY		  IEUtils.lib
+
+EXPORTUNFROZEN 
+
+EPOCALLOWDLLDATA
+
+nostrictdef
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/group/bld.inf	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// ===================================================================
+// BLD.INF
+//
+// ===================================================================
+
+PRJ_PLATFORMS
+default
+
+PRJ_EXPORTS
+..\inc\IEBgpsInfo.h      \epoc32\include\IEBgpsInfo.h
+//..\inc\IEBGPSTrace.h					 \epoc32\include\IEBGPSTrace.h
+ 
+PRJ_MMPFILES
+
+IEBgps.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IEBGPSTrace.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBGPSTRACE_H__
+#define __IEBGPSTRACE_H__
+
+#ifdef _DEBUG
+
+#include <e32debug.h>
+
+#define IEBGPSPRINT(x)	RDebug::Print x;
+
+#else
+
+#define IEBGPSPRINT(x)	
+
+#endif // _DEBUG
+
+
+#endif //__IEBGPSTRACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IEBgpServer.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBGPSERVER_H__
+#define __IEBGPSERVER_H__
+
+// Include files
+#include <e32base.h>
+#include <f32file.h>
+#include "debug.h"
+
+enum TIDLServerPanic
+{
+	EBadRequest = 1,
+	EBadDescriptor,
+	EMainSchedulerError,
+	ESrvCreateError,
+	ESvrStartError,
+	ETrapCleanupError,
+	EGeneralError
+};
+
+class CIEBgpServer : public CServer2
+{
+public:
+	static 	CIEBgpServer* NewL();
+	~CIEBgpServer();
+
+private:
+	void ConstructL();
+	CIEBgpServer();
+
+public: // From CServer2
+	CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
+	
+public: // New functions
+	static TInt ThreadFunction(TAny* aParam);
+	static void PanicServer(TIDLServerPanic aPanic);
+	
+private: // other private functions
+	static void StartServerL();	
+	
+private: // Data members
+    RFs    iFileServer;
+		
+};
+
+#endif // __IEBGPSERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IEBgpServerSession.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBGPSERVERSESSION_H__
+#define __IEBGPSERVERSESSION_H__
+
+// Include files
+#include <e32base.h>
+#include <e32cmn.h>
+
+#include <IEBgpsInfo.h>
+#include "IEFaceBrowser.h"
+
+
+class CIETNGeneratorAO;
+class MIEFaceBrowserObserver;
+
+class MIEThumbNailObserver
+{
+public:
+
+virtual void ThumbNailGenerationCompleted(TInt aError) = 0;
+//virtual void ThumbNailGenerationCompleted(TInt aError) = 0;
+};
+
+
+
+class CIEBgpServerSession : public CSession2, 
+                            public MIEThumbNailObserver,
+                            public MIEFaceBrowserObserver
+{
+public:
+	static CIEBgpServerSession* NewL(RFs* aFileServer);
+	~CIEBgpServerSession();
+	
+private:
+	void ConstructL(RFs* aFileServer);
+	CIEBgpServerSession();	
+	
+public: // From CSession2
+	void ServiceL(const RMessage2& aMessage);
+
+public:
+
+    void ThumbNailGenerationCompleted(TInt aError);
+    
+public: // From MIEFaceBrowserObserver
+    void FaceBrowsingComplete();
+    void FaceBrowsingError(TInt aError);
+    void FaceCroppingError(TInt aError);
+    void FaceSingleFaceBrowsingComplete();
+	
+private:
+
+TBool iSingleTNGeneration;
+
+CFaceBrowser* iFaceBrowser;
+
+TInt iCount;
+TInt iImageCount;
+RArray<CImageData*> iImageArray; 
+CIETNGeneratorAO *iIETNGeneratorAO;
+RMessage2 iMessage;	
+
+TFileName iJpegFileName;
+TFileName iImagicThumbFileName;
+TSize iResolutionSize;
+CFbsBitmap* iSrcBitmap;
+
+
+};
+
+#endif // __IEBGPSERVERSESSION_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IEBgpsInfo.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEBGPSINFO_H__
+#define __IEBGPSINFO_H__
+
+// Include files
+#include <e32base.h> 
+
+/**
+ * Server name
+ */
+_LIT(KIEBgpServerName, "IEBgpServer_0x2002135"); 
+
+/**
+ * Server version
+ */
+const TUint KIEBgpServerMajorVersion = 0;
+const TUint KIEBgpServerMinorVersion = 1;
+const TUint KIEBgpServerBuildVersion = 1; 
+
+/**
+ * Default message slots for the server
+ */
+const TInt KIEDefaultMsgSlot = 4; 
+
+/**
+ * Thread's max and min heap sizes
+ */
+const TUint KIEHeapSizeMin = 0x10000;
+const TUint KIEHeapSizeMax = 0x3000000;
+
+enum TImageArrayMode
+    {
+    EImages = 1,
+    EFaces
+    };
+
+/**
+ * Server seesion sevices
+ */
+enum TIEBgpServerRequests
+{
+	EIESrvTest = 1,
+	EIESrvCloseSession,
+	EIEThumbnailGeneration,
+	EIESingleTNGeneration,
+	EIESingleTNGenerationWithBitmap,
+	EIECancelThumbnailGeneration ,
+	EIEStartProcessing
+};
+
+enum TBGPSEventCode
+{
+	EEventNone = 1,
+	ETNGenerationcomplete,
+	ETNGenerationCancelled,
+	EFaceDetectionComplete,
+	EFaceAddedToExif,
+	EFaceRemovedFromExif,
+	ESingleFaceDetectionComplete,
+	EFaceDetectionCancelled
+};
+
+/**
+ * starts the server thread
+ * called by client
+ */
+IMPORT_C TInt CreateServerThread(RThread& aThread);
+
+#endif // __IEBGPSINFO_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IEFaceBrowser.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEFACEBROWSER_H__
+#define __IEFACEBROWSER_H__
+
+#include <e32base.h>
+#include <f32file.h>
+#include <f32file.h>
+//#include <IDLImageProcessing.h>
+#include <ImageConversion.h>
+//#include <IclExtJpegApi.h>
+
+#include "IEBgpsInfo.h"
+#include "IEImageData.h"
+#include "IEImageEncoder.h"
+#include "IEImageDecoder.h"
+#include "IEEngineUtils.h"
+
+// Foraward class declaration
+class CIEImageDecoder;
+class CIEImageEncoder;
+
+// Class declaration
+class MIEFaceBrowserObserver
+{
+public:
+    virtual void FaceBrowsingComplete() = 0;
+    virtual void FaceBrowsingError(TInt aError) = 0;
+    virtual void FaceSingleFaceBrowsingComplete() = 0;
+    
+};
+
+class CFaceBrowser : public CActive, 
+                        public MDecodingObserver,
+                        public MEncodingObserver
+#ifdef IDL_BGPS                        
+                        , public MIDLObserver
+#endif
+{
+private:
+    enum TFaceBrowsingState
+        {
+        EStateIdle = 0,
+        EFaceBrowsingRunning,
+        ESingleFaceBrowsingRunning,
+        EFaceBrowsingPaused,
+        EFaceBrowsingStopped,
+        EFaceBrowsingCompleted,
+        EFaceCroppingRunning,
+        EEncodingFaces,
+        EFaceCroppingCompleted,
+        ESingleFaceBrowsingComplete,
+        ECreatingBitmap
+        };
+/*
+    enum TFaceBrowsingMode
+        {
+        EBrowseModeNone = 0,
+        EBrowseModeSingleImage,
+        EBrowseModeBulkImages,
+        EModeCroppingFaces        
+        };
+*/
+    class TCroppedFaces
+        {
+        public:
+            HBufC8* iYuvdata;
+            TFileName iFileName;
+            TSize iCroppedSize;
+        };
+public: // First phase constructor and destructor
+    static CFaceBrowser* NewLC(RFs& aFileServer, MIEFaceBrowserObserver& aFaceBrowserObserver);
+    virtual ~CFaceBrowser();
+
+private: // Second phase constuctor and C++ default constructor
+    void ConstructL();
+    CFaceBrowser(RFs& aFileServer, MIEFaceBrowserObserver& aFaceBrowserObserver);
+
+protected: // From CActive
+    void RunL();
+    void DoCancel();
+    TInt RunError(TInt aError);
+    
+public: // From MDecodingObserver
+    void YuvImageReady(TInt aError);
+    void BitmapReady(TInt aError);
+
+public: // From MEncodingObserver
+    void JpegImageReady(TInt aError);
+    
+public: // From MIDLObserver
+    inline void ProcessingComplete(TDesC8& /*aData*/){};
+    inline void HandleError(TInt /*aError*/){}; 
+
+public: // New public functions
+    void StartFaceBrowsing(RArray<CImageData*> aImageDataArray);
+    void StartSingleFaceBrowsing(TInt aIndex, RArray<TRect>* aImageCoordArray, CImageData* aImageData);
+    void CancelFaceBrowsing();
+    TInt FindFaces(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+    TInt GetNumberOfFaces(const TFileName aFile);
+    void StartFaceCropping(RArray<CImageData*> aImageDataArray, RArray<TFileName>* aCroppedFilenames);
+    void CancelFaceCropping();
+    TInt AddFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+    TInt RemoveFaceCoordinate(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+    HBufC8* ReadExifMakerNoteL(const TDes &aFileName, TInt& aSize);
+    
+    
+private: // Internal functions
+    
+    // Common functions
+#ifdef IDL_BGPS
+    void InitializeL(const TIDLFeatures aIDLFeature, const TSize aInSize, const TSize aOutSize, TAny* aValue, TBool aInBufferCreate);
+#endif
+    void PrepareInOutBuffersL(TBool aInBufferCreate, const TInt aInBufSize, TBool aOutBufferCreate, const TInt aOutBufSize);
+    TFileName MakeTNFileName(const TFileName aImageFileName, TBool a128TNFile, TBool a320TNFileName);
+    void Cleanup();
+    void Cleanup2();
+    void ContinueLoop();
+    TBool CheckOddSize(const TSize aSize);
+    
+    //New function to handle RGB conversion
+    void ContinueFBAfterImageConversionL();
+    void ConvertRgb2Yuv(CFbsBitmap* aSourceBitmap, TUint8* aYuv, TInt aBytesPerPixel, const TSize aSize);
+        
+    // Face browsing related functions
+    void BrowseFacesL(CImageData* aImageData);
+#ifdef IDL_BGPS
+    void BrowseFacesL(TFileName a128x128TNFileName, RArray<TRect>& aFaceCoordinates);
+#endif
+    void GetFaceCoordinates(TInt& aNumberOfFaces, RArray<TRect>& aCordArray);
+    //void WriteFaceCoordinatesToExifDataL(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+    //void IsCoordinateExistsL(const TFileName a128x128TNFileName, TBool& aBool);
+    //void ReadFaceCoordinatesL(const TFileName a128x128TNFileName, RArray<TRect>& aCordArray);
+        
+    // Face cropping related functions    
+    void CropFacesL(CImageData* aImageData);
+    void CropFacesL(const TFileName aImageFileName, RArray<TRect>& aFaceCoordinates);
+    TInt MakeFacesDir(const TFileName aImageName);
+    TRect GetFaceRect(const TSize aOrgImageSize, const TSize aRelImageSize, const TRect aFaceRect);    
+    void EncodeFaceL(const TCroppedFaces aCroppedFace);
+    void CheckCroppedFaceFileNames();
+    
+    // Face detection
+    void WriteFaceCoordToExif(TInt numOfFaces, RArray<TRect> faceCoordinates);
+
+private: // Data members
+    RFs& iFileServer;
+    MIEFaceBrowserObserver& iFaceBrowserObserver;
+
+    RArray<CImageData*> iImageDataArray;
+    RArray<TCroppedFaces> iFaceYuvDataArray;
+    RArray<TRect> iFaceCoordinates;
+    RArray<TRect>* iTempFaceCoordinates;
+    
+    CIEImageDecoder* iImageDecoder;
+    CIEImageEncoder* iImageEncoder;
+    CImageDecoder*   iSymbianImageDecoder;
+    
+#ifdef IDL_BGPS
+    CIDLImageProcessing* iIDLImageProcessor;
+#endif
+    
+    HBufC8* iInputBuffer;
+    HBufC8* iOutputBuffer;
+    
+    CImageData* iCurrentImageData;
+    
+    TFaceBrowsingState iBrowsingState;
+    TFaceBrowsingState iPrevBrowsingState;
+//    TFaceBrowsingMode iBrowseMode;
+    
+    TSize iSize;
+    
+    TInt iNumberOfImages;
+    TInt iNumberOfImagesBrowsed;
+    TInt iSingleFaceBrowsingIndex;
+    TInt iNumberOfFacesCropped;    
+    TInt iNumberOfFaces;   
+    
+    TFileName iCurrentImageFileName;
+    TFileName iCurrent512x512TNFileName;
+    TInt        iTotalNumberOfFaces;
+    CIEEngineUtils iUtils;
+    
+    RArray<TFileName>* iCroppedFilenames;
+    //RArray<TRect> iImageCoordArray;
+    CFbsBitmap*     iBitmap;
+};
+
+#endif // __IEFACEBROWSER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IEImageDecoder.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEDECODER_H__
+#define __IEIMAGEDECODER_H__
+
+// Include files
+#include <e32base.h>
+#include <f32file.h>
+#include <fbs.h>
+#include <ImageConversion.h>
+#include <IclExtJpegApi.h>
+
+class MDecodingObserver
+{
+public:
+	//virtual void YuvImageReady(TInt aError) = 0;
+	virtual void BitmapReady(TInt aError) = 0;
+};
+
+// Forward class declarations
+
+// Class declaration
+class CIEImageDecoder : CActive
+{
+public:
+	static CIEImageDecoder* NewL(RFs& aFileServer, MDecodingObserver& aObserver);
+	~CIEImageDecoder();
+
+private:
+	void ConstructL();
+	CIEImageDecoder(RFs& aFileServer, MDecodingObserver& aObserver);
+	
+public: // From CAtive
+	void RunL()	;
+	void DoCancel();
+	
+public:
+	void GetImageSizeL(const TFileName aFileName, TSize& aSize);
+	void ConvertJpeg2YuvL(const TDesC& aSourceFile, 
+					HBufC8& aBuffer);
+	
+	void ConvertJpeg2BitmapL(CFbsBitmap& aDestBitmap, TDesC8& aSourceData);
+	
+	TPtr8 GetVisualFrame();
+	
+	void CancelDecoding();
+	
+private: // Data
+	RFs& iFileServer;
+	MDecodingObserver& iObserver;
+	CImageDecoder* iImageDecoder;
+	CExtJpegDecoder* iExtImageDecoder;
+	CVisualFrame* iVisualFrame;
+	TBool iDecoderBusy;
+	TBool iDecode2Yuv;
+	TBool iDecode2Bitmap;
+	TPtr8 iSrcPtr;
+	
+	TUint8* iBufU;
+	TInt iNumOfBitmaps;
+};
+
+#endif // __IEIMAGEDECODER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IEImageEncoder.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IEIMAGEENCODER_H__
+#define __IEIMAGEENCODER_H__
+
+// Include files
+#include <e32base.h>
+#include <f32file.h>
+#include <fbs.h>
+#include <ImageConversion.h>
+#include <IclExtJpegApi.h>
+
+
+// Forward class declarations
+class MEncodingObserver
+{
+public:
+	//virtual void JpegImageReady(TInt aError) = 0;
+};
+
+
+// Class declaration
+class CIEImageEncoder : CActive
+{
+public:
+	static CIEImageEncoder* NewL(RFs& aFileServer, MEncodingObserver& aObserver);
+	~CIEImageEncoder();
+
+private:
+	void ConstructL();
+	CIEImageEncoder(RFs& aFileServer, MEncodingObserver& aObserver);
+	
+public:
+	void ConvertYuv2JpegL(HBufC8*& aDestBuffer, 
+					HBufC8& aSourceBuffer, 
+					const TSize aSize);
+	
+	void ConvertYuv2JpegL(TDesC& aFileName, 
+					HBufC8& aSourceBuffer, 
+					const TSize aSize);
+
+	void CancelEncoding();
+	
+private:	
+	void SetJpegImageDataL();
+	
+public: // From CAtive
+	void RunL()	;
+	void DoCancel();
+	
+private: // Data
+	RFs& iFileServer;
+	MEncodingObserver& iObserver;
+	
+	CImageEncoder* iImageEncoder;
+	CExtJpegEncoder* iExtImageEncoder;
+	
+	CVisualFrame* iVisualFrame;
+	
+	CFrameImageData* iFrameImageData;
+		
+	TBool iEncoderBusy;
+};
+
+#endif // __IEIMAGEENCODER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/IETNGenerator.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IETNGENERATORAO_H__
+#define __IETNGENERATORAO_H__
+
+#include <e32base.h>
+#include <f32file.h>
+#include <BitmapTransforms.h>
+#include <ImageConversion.h>
+
+#include "IEBgpServerSession.h"
+#include <IEBgpsInfo.h>
+#include <ICLExif.h> 
+#include <exifmodify.h>
+#include <exifread.h>
+#include "debug.h"
+
+class CImageDecoder;
+class CFbsBitmap;
+
+//#define USE_EXT_JPEG_DEC
+
+#ifdef USE_EXT_JPEG_DEC
+class CExtJpegDecoder;
+#endif
+
+
+#define DECODE_FROM_BUFFER
+
+// CONSTANTS
+const TInt KMimeStringLength = 256;
+
+class  CIETNGeneratorAO : public CActive
+{
+public:
+	static CIETNGeneratorAO* NewL(RFs& aFileServer, MIEThumbNailObserver &aObserver);
+	virtual ~CIETNGeneratorAO();
+	
+private:
+	void ConstructL();
+	
+	CIETNGeneratorAO(RFs& aFileServer, MIEThumbNailObserver &aObserver);
+
+
+protected:  // Type declarations
+    enum TIETNConvertStatus
+    {
+    	ENone = 0,
+        EDecoding,
+        EScaling,
+        EEncoding,
+        EReady
+    };
+	
+public:
+
+	void SetImageArray(	RArray<CImageData*> aImageArray);
+	void CancelOutStaningRequests();
+	void DeleteObjects();
+	void CancelRequestsAndDeleteObjects();
+	
+public: // From CActive
+	void RunL();
+	void DoCancel();
+	TInt RunError(TInt aError);
+	
+public: // Other public functions
+ 
+	RArray<CImageData*> iImageArray;
+	void CreateThumbnailL(const TDes& aSourceFile, const TDes& aThumbnailFile, const TSize &aSize);
+	void CreateThumbnailL(const TDes& aSourceFile, const TDes& aThumbnailFile, const TSize &aSize, CFbsBitmap* a512x512TnBitmap);
+	
+	
+private:
+	void SetJpegImageDataL();
+	void WriteExifDataL(const TDes &aFilename, TSize aSize);
+	void DecodeL();
+	void EncodeL();
+	void ScaleL();
+	void TargetDecodingSize(const TSize aTgtSize, TSize& aSrcSize);
+	TBool IsLargeThumbnail(const TSize& aResolution) const;
+	TBool IsJPEG(const TSize& aResolution) const;
+	
+private:
+  
+    RFs&                  iFileServer;
+#ifdef USE_EXT_JPEG_DEC
+    CExtJpegDecoder*      iImageDecoder;
+#else
+    CImageDecoder*        iImageDecoder;
+#endif
+    CImageEncoder*        iImageEncoder;
+    CFbsBitmap*           iBitmap;
+    CBitmapScaler*        iBitmapScaler;
+    TIETNConvertStatus    iConvertStatus;   /** Convert status */
+    MIEThumbNailObserver& iThumbnailObserver;
+    TFileName             iSourceFileName;
+    TFileName             iThumbnailFileName;
+    TBuf8<KMimeStringLength> iMimeString;   /** The source file Mime-string */
+    TSize                 iSourceSize;
+    CFrameImageData*      iFrameImageData;
+    TSize                 iThumbnailSize;
+    TTime                 iSourceTime;      /** Source file time */
+    TInt                  iError;  
+    CFbsBitmap*           i512x512TnBitmap;
+    TUid                  decoderUid;
+
+#ifdef DECODE_FROM_BUFFER
+    HBufC8*               iSourceData;
+#endif
+
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/inc/debug.h	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#ifndef __IMAGIC_TRACE_H__
+#define __IMAGIC_TRACE_H__
+
+//#define _IMAGIC_DEBUG
+#ifdef _IMAGIC_DEBUG
+
+#include <e32debug.h>
+
+#define DP0_IMAGIC(string)                            RDebug::Print(string)
+#define DP1_IMAGIC(string,arg1)                       RDebug::Print(string,arg1)
+#define DP2_IMAGIC(string,arg1,arg2)                  RDebug::Print(string,arg1,arg2)
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             RDebug::Print(string,arg1,arg2,arg3)
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        RDebug::Print(string,arg1,arg2,arg3,arg4)
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)   RDebug::Print(string,arg1,arg2,arg3,arg4,arg5)
+
+#else
+
+#define DP0_IMAGIC(string)                            
+#define DP1_IMAGIC(string,arg1)                       
+#define DP2_IMAGIC(string,arg1,arg2)                  
+#define DP3_IMAGIC(string,arg1,arg2,arg3)             
+#define DP4_IMAGIC(string,arg1,arg2,arg3,arg4)        
+#define DP5_IMAGIC(string,arg1,arg2,arg3,arg4,arg5)
+#endif // _DEBUG
+
+
+#endif //__IMAGIC_TRACE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/src/IEBgpServer.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,175 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include <e32cons.h>
+
+#include <IEBgpsInfo.h>
+//#include <IEBGPSTrace.h>
+
+#include "IEBgpServer.h"
+#include "IEBgpServerSession.h"
+
+
+// --------------------------- MEMBER FUNCTIONS ---------------------------- //
+
+// ----------------------------------------------------------------------------
+//
+//
+// ----------------------------------------------------------------------------
+CIEBgpServer* CIEBgpServer::NewL()
+{
+	DP0_IMAGIC((_L("CIEBgpServer::NewL ++")));
+	CIEBgpServer* self = new (ELeave) CIEBgpServer();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	DP0_IMAGIC((_L("CIEBgpServer::NewL --")));
+	return self;
+}
+
+CIEBgpServer::~CIEBgpServer()
+{
+DP0_IMAGIC((_L("CIEBgpServer::~CIEBgpServer")));
+
+iFileServer.Close();
+RFbsSession::Disconnect();
+
+DP0_IMAGIC((_L("CIEBgpServer::~CIEBgpServer")));	
+}
+
+//EPriorityIdle, EPriorityLow, EPriorityStandard, EPriorityUserInput, EPriorityHigh
+CIEBgpServer::CIEBgpServer()
+:CServer2(EPriorityIdle)
+{	
+}
+
+void CIEBgpServer::ConstructL()
+{
+	DP0_IMAGIC((_L("CIEBgpServer::ConstructL ++")));
+	StartL(KIEBgpServerName);
+	
+	User::LeaveIfError(iFileServer.Connect());
+    User::LeaveIfError( FbsStartup() );
+    User::LeaveIfError(RFbsSession::Connect());
+	
+	DP0_IMAGIC((_L("CIEBgpServer::ConstructL --")));
+}
+
+CSession2* CIEBgpServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
+{
+	DP0_IMAGIC((_L("CIEBgpServer::NewSessionL ++")));
+	CIEBgpServerSession* session = CIEBgpServerSession::NewL(const_cast<RFs*>(&iFileServer));
+	DP0_IMAGIC((_L("CIEBgpServer::NewSessionL --")));
+	return session;
+}
+
+// ----------------------------------------------------------------------------
+// Thread function to start the server
+//
+// ----------------------------------------------------------------------------
+GLDEF_C TInt CIEBgpServer::ThreadFunction(TAny* /*aParam*/)
+{
+	DP0_IMAGIC((_L("CIEBgpServer::ThreadFunction ++")));
+	// First get the cleanup stack
+	CTrapCleanup* cleanupStack = CTrapCleanup::New();
+	
+	TRAPD(error, StartServerL());
+	
+	delete cleanupStack;
+	
+	DP0_IMAGIC((_L("CIEBgpServer::ThreadFunction --")));
+	
+	return error;
+}
+
+// ----------------------------------------------------------------------------
+// Starts the server
+//
+// ----------------------------------------------------------------------------
+void CIEBgpServer::StartServerL()
+{
+	DP0_IMAGIC((_L("CIEBgpServer::StartServerL ++")));
+	// Create an active scheduler before server is created
+	CActiveScheduler* as = new (ELeave) CActiveScheduler();
+	CleanupStack::PushL(as);
+	CActiveScheduler::Install(as);
+	
+	// Create server
+	CIEBgpServer* server = CIEBgpServer::NewL();
+	CleanupStack::PushL(server);
+	
+	RThread::Rendezvous(KErrNone);
+	
+	// Start active scheduler
+	CActiveScheduler::Start();
+	
+	// Clean up
+	CleanupStack::PopAndDestroy(2, as);
+	
+	DP0_IMAGIC((_L("CIEBgpServer::StartServerL --")));
+}
+
+// ----------------------------------------------------------------------------
+// Creates the server thread
+//
+// ----------------------------------------------------------------------------
+EXPORT_C TInt CreateServerThread(RThread& aThread)
+{
+	DP0_IMAGIC((_L("CIEBgpServer::CreateServerThread ++")));
+	TInt error = KErrNone;
+	
+	// Check if the server already exists
+	TFindServer findServer(KIEBgpServerName);
+	TFileName matchingServer;
+	
+	if(findServer.Next(matchingServer) != KErrNone)
+	{
+		error = aThread.Create(KIEBgpServerName, // Server name
+							CIEBgpServer::ThreadFunction, // thread function to call when thread is created and resumed
+							KDefaultStackSize, // stack size
+							KIEHeapSizeMin, // min heap size
+							KIEHeapSizeMax, // max heap size
+							NULL); // data ptr needed (if)
+
+		if(error == KErrNone)
+		{
+			// Thread created successfully, resume it
+			TRequestStatus rendezvousStatus;
+			
+			//Keep priority low to enable smooth UI drawing
+			//aThread.SetPriority(EPriorityNormal);
+			aThread.SetPriority(EPriorityLess);//EPriorityNormal, EPriorityLess, EPriorityMuchLess, EPriorityNull
+			aThread.Rendezvous(rendezvousStatus);
+			aThread.Resume();
+			User::WaitForRequest(rendezvousStatus);
+		}
+		else
+		{
+			// error in thread creation
+			aThread.Close();
+		}
+	}
+	else
+	{
+		error = KErrAlreadyExists;
+	}
+	DP0_IMAGIC((_L("CIEBgpServer::CreateServerThread --")));
+	return error;
+}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/src/IEBgpServerSession.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,265 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include <e32cons.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "IEBgpsInfo.h"
+#include "IEImageData.h"
+//#include <IEBGPSTrace.h>
+
+#include "IEBgpServerSession.h"
+#include "IETNGenerator.h"
+
+// --------------------------- MEMBER FUNCTIONS ---------------------------- //
+
+CIEBgpServerSession* CIEBgpServerSession::NewL(RFs* aFileServer)
+{
+	DP0_IMAGIC((_L("CIEBgpServerSession::NewL ++")));
+	CIEBgpServerSession* self = new (ELeave) CIEBgpServerSession();
+	CleanupStack::PushL(self);
+	self->ConstructL(aFileServer);
+	CleanupStack::Pop();
+	DP0_IMAGIC((_L("<CIEBgpServerSession::NewL --")));
+	return self;
+}
+
+CIEBgpServerSession::~CIEBgpServerSession()
+{
+	DP0_IMAGIC((_L("CIEBgpServerSession::~CIEBgpServerSession ++")));
+ 
+ 	if(iIETNGeneratorAO)
+ 	{
+ 		delete iIETNGeneratorAO;
+ 		iIETNGeneratorAO = NULL;
+ 	}
+ 	
+ 	if(iFaceBrowser)
+ 	{
+ 	    delete iFaceBrowser;
+ 	    iFaceBrowser = NULL;
+ 	}
+	DP0_IMAGIC((_L("<CIEBgpServerSession::~CIEBgpServerSession --")));
+}
+
+CIEBgpServerSession::CIEBgpServerSession()
+{	
+	DP0_IMAGIC((_L("CIEBgpServerSession::CIEBgpServerSession ++")));
+	DP0_IMAGIC((_L("CIEBgpServerSession::CIEBgpServerSession --")));
+}
+
+void CIEBgpServerSession::ConstructL(RFs* aFileServer)
+    {
+	DP0_IMAGIC((_L("CIEBgpServerSession::ConstructL ++")));
+/*	
+	TInt initError = KErrNone;
+	if(initError != KErrNone)
+	{
+	DP0_IMAGIC((_L("CIEBgpServerSession::ConstructL- IDL Engine Creation Failed")));
+	User::Leave(initError);
+	}
+	
+*/	
+	iResolutionSize.iHeight = 512;
+	iResolutionSize.iWidth = 512;
+	
+	iIETNGeneratorAO = CIETNGeneratorAO::NewL(*aFileServer, *this);
+	
+	iFaceBrowser = CFaceBrowser::NewLC(*aFileServer, *this);
+	
+	DP0_IMAGIC((_L("CIEBgpServerSession::ConstructL --")));
+    }
+
+void CIEBgpServerSession::ServiceL(const RMessage2& aMessage)
+    {
+	DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL++")));
+
+	TInt error = KErrNone;
+	
+	switch(aMessage.Function())
+    	{
+    		case EIESrvTest:
+        		{
+                TInt value = aMessage.Int0();
+                aMessage.Complete(error);
+                break;
+        		}
+    		case EIESrvCloseSession:
+        		{
+        		DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL - EIESrvCloseSession")));
+                break;
+        		}
+    	
+    		case EIEStartProcessing:
+        		{     
+        		DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL - EIEStartProcessing")));
+                break;
+        		}
+    		
+    		case EIEThumbnailGeneration:
+        		{
+        		DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL - EIEThumbnailGeneration")));
+        		iMessage = aMessage;
+        		iImageArray = *(RArray<CImageData*>*)aMessage.Ptr0();
+        		TInt count = iImageArray.Count();
+        		iIETNGeneratorAO->SetImageArray(iImageArray);
+        		
+        		iCount = 0;
+         		TFileName jpegFileName;
+         		TFileName imagicThumbFileName;
+                iImageArray[0]->GetFileName(jpegFileName, EFullSize);         		
+         		iImageArray[0]->GetFileName(imagicThumbFileName, ESize512x512);
+        	
+        		iIETNGeneratorAO->CreateThumbnailL(jpegFileName, imagicThumbFileName, iResolutionSize);
+        		break;	
+        		}
+    	
+    		case EIESingleTNGeneration:
+        		{
+        		DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL - EIESingleTNGeneration")));
+        		iSingleTNGeneration = ETrue;
+        		iMessage = aMessage;
+        	
+        		TFileName jpegFileName;
+        	 	TFileName imagicThumbFileName;
+        	
+        		error  =  aMessage.Read(0, iJpegFileName, 0);
+        		error  =  aMessage.Read(1, iImagicThumbFileName, 0);
+        		
+        	 	iResolutionSize = *(TSize*)aMessage.Ptr2();
+        		if(error  == KErrNone)
+        			{
+        			iIETNGeneratorAO->CreateThumbnailL(iJpegFileName,iImagicThumbFileName,iResolutionSize);	
+        			}
+        		else
+        			{
+        			iSingleTNGeneration	= EFalse;
+        			iMessage.Complete(error);	
+        			}
+                break;
+        		}
+        		
+    		case EIESingleTNGenerationWithBitmap:
+                {
+                DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL - EIESingleTNGenerationWithBitmap")));
+                iSingleTNGeneration = ETrue;
+                iMessage = aMessage;
+            
+                TFileName jpegFileName;
+                TFileName imagicThumbFileName;
+            
+                error  =  aMessage.Read(0, iJpegFileName, 0);
+                error  =  aMessage.Read(1, iImagicThumbFileName, 0);
+                
+                iResolutionSize = *(TSize*)aMessage.Ptr2();
+                iSrcBitmap = (CFbsBitmap*)aMessage.Ptr3();
+                
+                if(error  == KErrNone)
+                    {
+                    iIETNGeneratorAO->CreateThumbnailL(iJpegFileName,iImagicThumbFileName,iResolutionSize); 
+                    }
+                else
+                    {
+                    iSingleTNGeneration = EFalse;
+                    iMessage.Complete(error);   
+                    }
+                break;
+                }
+        		
+    		case EIECancelThumbnailGeneration:
+        		{
+        		DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL - EIECancelThumbnailGeneration")));
+        		iIETNGeneratorAO->CancelRequestsAndDeleteObjects();
+        		//Complete current "Cancel" message
+                aMessage.Complete(KErrNone);
+        		break;
+        		}   		
+    	
+    		default:
+    			break;
+    	}
+	
+	DP0_IMAGIC((_L("CIEBgpServerSession::ServiceL --")));	
+    }
+
+void CIEBgpServerSession::ThumbNailGenerationCompleted(TInt aError)
+    {
+    DP0_IMAGIC((_L("CIEBgpServerSession::ThumbNailGenerationCompleted++")));
+    
+	if(aError != KErrNone)
+	    {
+	    if(aError == KErrCancel)
+	        iMessage.Complete(ETNGenerationCancelled);
+	    else
+	        iMessage.Complete(aError);   
+	    }
+	if(aError == KErrNone)
+	    {
+    	if(iSingleTNGeneration)
+    		{
+    		iSingleTNGeneration	= EFalse;
+    		iMessage.Complete(ETNGenerationcomplete);	
+    		}
+    	else
+    		{
+    		iCount++;
+    
+    		if(iCount > iImageArray.Count()-1 )
+    		    {
+    			iMessage.Complete(ETNGenerationcomplete);	
+    		    }
+    		else
+    		    {
+    	        TFileName jpegFileName; 
+    	        TFileName imagicThumbFileName;
+    			iImageArray[0]->GetFileName(jpegFileName, EFullSize);
+                iImageArray[0]->GetFileName(imagicThumbFileName, ESize512x512);    			
+    			iIETNGeneratorAO->CreateThumbnailL(jpegFileName, imagicThumbFileName, iResolutionSize);		
+    		    }
+    		}
+	    }
+	DP0_IMAGIC((_L("CIEBgpServerSession::ThumbNailGenerationCompleted --")));
+    }
+
+void CIEBgpServerSession::FaceBrowsingComplete()
+    {
+    DP0_IMAGIC((_L("CIEBgpServerSession::FaceBrowsingComplete")));
+    iMessage.Complete(EFaceDetectionComplete);
+    }
+
+void CIEBgpServerSession::FaceBrowsingError(TInt aError)
+    {
+    DP0_IMAGIC((_L("CIEBgpServerSession::FaceBrowsingError")));
+    iMessage.Complete(aError);
+    }
+
+void CIEBgpServerSession::FaceCroppingError(TInt aError)
+    {
+    DP0_IMAGIC((_L("CIEBgpServerSession::FaceCroppingError")));
+    iMessage.Complete(aError);
+    }
+
+void CIEBgpServerSession::FaceSingleFaceBrowsingComplete()
+    {
+    DP0_IMAGIC((_L("CIEBgpServerSession::FaceSingleFaceBrowsingComplete")));
+    iMessage.Complete(ESingleFaceDetectionComplete);
+    }
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/src/IEFaceBrowser.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,1424 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include <e32debug.h>
+#include <e32math.h>
+#include <exifmodify.h>
+#include <BAUTILS.H>
+#include "IEFaceBrowser.h"
+#include "IEBgpsInfo.h"
+#include "IEImageData.h"
+#include "ImagicConsts.h"
+#include "debug.h"
+#include <hal.h>
+
+// ================= MEMBER FUNCTIONS ================================ //
+CFaceBrowser* CFaceBrowser::NewLC(
+        RFs& aFileServer, 
+        MIEFaceBrowserObserver& aFaceBrowserObserver)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::NewLC ++"));
+    
+    CFaceBrowser* self = new (ELeave) CFaceBrowser(aFileServer, aFaceBrowserObserver);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    
+    DP0_IMAGIC(_L("CFaceBrowser::NewLC --"));
+    
+    return self;
+    }
+
+CFaceBrowser::CFaceBrowser(
+        RFs& aFileServer, 
+        MIEFaceBrowserObserver& aFaceBrowserObserver) :
+        iUtils(iFileServer),
+        iFileServer(aFileServer), 
+        iFaceBrowserObserver(aFaceBrowserObserver), 
+        CActive(EPriorityIdle)
+    {
+    
+    }
+
+CFaceBrowser::~CFaceBrowser()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::~CFaceBrowser ++"));
+    
+    if(iImageDecoder)
+        {
+        iImageDecoder->CancelDecoding();
+        
+        delete iImageDecoder;
+        iImageDecoder = NULL;
+        }
+    
+    if(iImageEncoder)
+        {
+        iImageEncoder->CancelEncoding();
+        
+        delete iImageEncoder;
+        iImageEncoder = NULL;
+        }
+    
+    if(iSymbianImageDecoder)
+    {
+        delete iSymbianImageDecoder;
+        iSymbianImageDecoder = NULL;   
+    }
+    
+    if(IsActive())
+        Cancel();
+    
+#ifdef IDL_BGPS
+    if(iIDLImageProcessor)
+        {
+        delete iIDLImageProcessor;
+        iIDLImageProcessor = NULL;
+        }
+#endif
+    
+    if(iInputBuffer)
+        {
+        delete iInputBuffer;
+        iInputBuffer = NULL;
+        }
+    
+    if(iOutputBuffer)
+        {
+        delete iOutputBuffer;
+        iOutputBuffer = NULL;
+        }
+    
+    if(iFaceYuvDataArray.Count() > 0)
+        {
+        TCroppedFaces croppedFace;
+        HBufC8* buffer = NULL;
+        TInt count = iFaceYuvDataArray.Count();
+        for(TInt i=0; i<count; i++)
+            {
+            croppedFace = iFaceYuvDataArray[0];
+            buffer = croppedFace.iYuvdata;
+            
+            iFaceYuvDataArray.Remove(0);
+            
+            delete buffer;
+            buffer = NULL;
+            }
+        }
+    
+    iFaceYuvDataArray.Close();
+    
+    if(iImageDataArray.Count() > 0)
+        {
+        TInt count = iImageDataArray.Count();
+        for(TInt i=0; i<count; i++)
+            iImageDataArray.Remove(0);
+        }
+
+    iImageDataArray.Close();
+    
+    iFaceCoordinates.Close();
+    if (iTempFaceCoordinates)
+        iTempFaceCoordinates->Close();
+   
+    DP0_IMAGIC(_L("CFaceBrowser::~CFaceBrowser --"));    
+    }
+
+void CFaceBrowser::ConstructL()
+    {
+    TInt error = KErrNone;
+    
+    DP0_IMAGIC(_L("CFaceBrowser::ConstructL ++"));
+    
+    CActiveScheduler::Add(this);
+    
+    iImageDecoder = CIEImageDecoder::NewL(iFileServer, *this);
+    
+    iImageEncoder = CIEImageEncoder::NewL(iFileServer, *this);
+    
+#ifdef IDLBGPS
+    iIDLImageProcessor = CIDLImageProcessing::NewL(*this);
+#endif
+    
+    iBrowsingState = EStateIdle;
+    
+    iNumberOfImages = 0;
+    iNumberOfImagesBrowsed = 0;
+    iNumberOfFacesCropped = 0;    
+    iNumberOfFaces = 0;
+    iTotalNumberOfFaces = 0;
+      
+    //RDebug::Print(_L("IDL_Engine_Create error = %d"), error);
+    
+    if(error != KErrNone)
+        User::Leave(error);
+    
+    DP0_IMAGIC(_L("CFaceBrowser::ConstructL --"));    
+    }
+
+void CFaceBrowser::RunL()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::RunL ++"));
+    
+    TInt error = KErrNone;
+    
+    switch(iBrowsingState)
+        {
+        case ECreatingBitmap:
+            {
+            DP0_IMAGIC(_L("CFaceBrowser::RunL() - ECreatingBitmap"));
+            TInt error = iStatus.Int();
+            if(iSymbianImageDecoder)
+                {
+                delete iSymbianImageDecoder;
+                iSymbianImageDecoder = NULL;   
+                }
+#ifdef IDL_BGPS
+            ContinueFBAfterImageConversionL();
+#else
+            //ExecuteFaceDetectionL();
+#endif
+            }
+            break;
+        
+        case EFaceBrowsingRunning:
+            {
+            DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingRunning"));
+            
+            TRAP(error, BrowseFacesL(iImageDataArray[iNumberOfImagesBrowsed]));
+            
+            if(error != KErrNone)
+                {
+                Cleanup();
+                iFaceBrowserObserver.FaceBrowsingError(error);
+                }                
+            }
+            break;
+        
+        case ESingleFaceBrowsingRunning:
+            {
+            DP0_IMAGIC(_L("CFaceBrowser::RunL() - ESingleFaceBrowsingRunning"));
+            
+            //TRAP(error, BrowseFacesL(iImageDataArray[iSingleFaceBrowsingIndex]));
+            TRAP(error, BrowseFacesL(iCurrentImageData));
+            
+            if(error != KErrNone)
+                {
+                Cleanup();
+                iFaceBrowserObserver.FaceBrowsingError(error);
+                }                
+            }
+            break;
+
+        case EFaceBrowsingPaused:
+            {
+            DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingPaused"));
+            }
+            break;
+            
+        case EFaceBrowsingStopped:
+            {
+            DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingStopped"));
+            
+            Cleanup();
+            }
+            break;
+            
+        case EFaceBrowsingCompleted:
+            {
+            DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingCompleted"));
+            
+            Cleanup();
+            iFaceBrowserObserver.FaceBrowsingComplete();
+            }
+            break;
+            
+        case ESingleFaceBrowsingComplete:
+            {
+            DP0_IMAGIC(_L("CFaceBrowser::RunL() - ESingleFaceBrowsingComplete"));
+            
+            Cleanup2();
+            iFaceBrowserObserver.FaceSingleFaceBrowsingComplete();
+            }
+            break;
+                               
+        default:
+            break;
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::RunL --"));    
+    }
+
+
+void CFaceBrowser::CheckCroppedFaceFileNames()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::CheckCroppedFaceFileNames"));
+    
+    TInt count = iFaceYuvDataArray.Count();
+    //Check that file was really cropped
+    for(TInt i=0; i<count; i++)
+        {
+        if(BaflUtils::FileExists(iFileServer, iFaceYuvDataArray[i].iFileName))
+            {
+            //do nothing
+            }
+        else
+            {
+            iFaceYuvDataArray.Remove(i);
+            }
+        //CImageData* data = new CImageData;
+        //data->iMGFilename = iFaceYuvDataArray[i].iFileName;
+        //iImageDataArray.Append(data);
+        }
+    }
+            
+
+void CFaceBrowser::DoCancel()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::DoCancel ++"));
+    
+    iImageDecoder->CancelDecoding();
+    iImageEncoder->CancelEncoding();
+    
+    DP0_IMAGIC(_L("CFaceBrowser::DoCancel --"));
+    }
+
+TInt CFaceBrowser::RunError(TInt aError)
+    {
+    DP1_IMAGIC(_L("CFaceBrowser::RunError - Error: %d"), aError);
+    return aError;
+    }
+
+void CFaceBrowser::BitmapReady(TInt /*aError*/)
+    {
+    
+    }
+
+// =============================== PUBLIC FUNCTIONS ============================== //
+
+void CFaceBrowser::StartFaceBrowsing(RArray<CImageData*> aImageDataArray)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::StartFaceBrowsing ++"));
+    
+    if(iBrowsingState != EStateIdle)
+        iFaceBrowserObserver.FaceBrowsingError(KErrInUse); // Better error code ?
+    
+    if(aImageDataArray.Count() == 0)
+        {
+        DP0_IMAGIC(_L("ImageDataArray is empty!!!!"));
+        iFaceBrowserObserver.FaceBrowsingError(KErrArgument);
+        }
+    else
+        {
+        iBrowsingState = EFaceBrowsingRunning;
+        //Take local copy of imagedata array
+        for(TInt i=0; i<aImageDataArray.Count(); i++)
+            {
+            if(!aImageDataArray[i]->iGridData.iCorrupted)
+                iImageDataArray.Append(aImageDataArray[i]);
+            }
+        
+        iNumberOfImages = iImageDataArray.Count();
+        
+        DP1_IMAGIC(_L("Number of images: %d"), iNumberOfImages);        
+        ContinueLoop();        
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::StartFaceBrowsing --"));    
+    }
+
+//void CFaceBrowser::StartSingleFaceDetection(TInt aIndex, RArray<TRect>* aImageCoordArray)
+//void CFaceBrowser::StartSingleFaceDetection(TInt aIndex, RArray<TRect>* aImageCoordArray, RArray<CImageData*> aImageDataArray)
+void CFaceBrowser::StartSingleFaceBrowsing(TInt aIndex, RArray<TRect>* aImageCoordArray, CImageData* aImageData)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::StartSingleFaceBrowsing ++"));
+    
+    iCurrentImageData = aImageData;
+    iSingleFaceBrowsingIndex = aIndex;
+    iTempFaceCoordinates = aImageCoordArray;
+    
+    if(iBrowsingState != EStateIdle)
+        iFaceBrowserObserver.FaceBrowsingError(KErrInUse); // Better error code ?
+    
+    iBrowsingState = ESingleFaceBrowsingRunning;
+    
+    /*//Take local copy of imagedata array
+    for(TInt i=0; i<aImageDataArray.Count(); i++)//TODO, copy only one array element, not all in alrray
+        {
+        if(!aImageDataArray[i]->iGridData.iCorrupted)
+            iImageDataArray.Append(aImageDataArray[i]);
+        }
+    */
+    iNumberOfImages = iImageDataArray.Count();
+  
+    DP0_IMAGIC(_L("CFaceBrowser::StartSingleFaceBrowsing --"));
+    ContinueLoop();        
+    }
+
+void CFaceBrowser::CancelFaceBrowsing()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::CancelFaceBrowsing ++"));
+    
+    Cleanup2();
+    
+    if(IsActive())
+        Cancel();
+    
+    //Cleanup();//TODO, check if this is needed
+    
+    DP0_IMAGIC(_L("CFaceBrowser::CancelFaceBrowsing ++"));
+    }
+
+TInt CFaceBrowser::FindFaces(const TFileName a512x512TNFileName, RArray<TRect>& aCordArray)
+    {
+    DP1_IMAGIC(_L("CFaceBrowser::FindFaces, a512x512TNFileName = %S ++"), &a512x512TNFileName);
+    
+    TInt error = KErrNone;
+    
+    TRAP(error, iUtils.ReadFaceCoordinatesL(a512x512TNFileName, aCordArray));
+    if(error != KErrNone) return error;
+    
+    DP0_IMAGIC(_L("CFaceBrowser::FindFaces --"));
+    
+    return error;    
+    }
+
+TInt CFaceBrowser::GetNumberOfFaces(const TFileName /*aFile*/)
+    {
+    return 0;
+    }
+
+//void CIEEngineImp::RemoveExifFaceCoordsL(const TDes& aFilename, TPoint aTlCoord, TPoint aBrCoord, TInt aFaceNumber)
+
+
+TInt CFaceBrowser::RemoveFaceCoordinate(const TFileName a512x512TNFileName, RArray<TRect>& aCordArray)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::RemoveFaceCoordinate++"));
+    
+     //Read first current make note
+     TInt makerNoteSize;
+     HBufC8* makerNote = ReadExifMakerNoteL(a512x512TNFileName, makerNoteSize);
+     
+     //Read first current maker note to new array from given file
+     //RArray<TRect> newCordArray;
+     //ReadFaceCoordinatesL(a512x512TNFileName, newCordArray);
+     
+     //Allocate buffer for coords to be removed
+     HBufC8* heapComment = HBufC8::NewL(100);
+     TPtr8 ptrCoords = heapComment->Des();
+     //Copy coords to be removed to descriptor
+     for(TInt i=0; i < aCordArray.Count(); i++)
+         {
+         ptrCoords.AppendNum(aCordArray[i].iTl.iX);
+         ptrCoords.Append(' ');
+         ptrCoords.AppendNum(aCordArray[i].iTl.iY);
+         ptrCoords.Append(' ');
+         ptrCoords.AppendNum(aCordArray[i].iBr.iX );
+         ptrCoords.Append(' ');
+         ptrCoords.AppendNum(aCordArray[i].iBr.iY);
+         ptrCoords.Trim();
+         }
+     
+     //Find coordinates from maker note
+     TPtr8 tmpPtr = makerNote->Des();
+     TInt res = tmpPtr.Find(ptrCoords);
+     
+     if(res == KErrNotFound)
+         return res;
+         
+     //Remove coordinates from maker note
+     TInt l = ptrCoords.Length();
+     tmpPtr.Delete(res, ptrCoords.Length()+1);
+     
+     //Find number of faces from maker note and update it
+     _LIT8(KNumberOfFace, "#");
+     res = tmpPtr.Find(KNumberOfFace);
+     
+     TLex8 lex(makerNote->Ptr());
+     lex.SkipAndMark(res+1);
+     TInt faceCount = 0;
+     lex.Val(faceCount);
+     
+     //Check lenght of number of faces string
+     TInt length = 0;
+     //TInt aFaceNumber = 1;
+     if(faceCount < 10)
+         length = 1;
+     else
+         length = 2;
+          
+     HBufC8* numberOfFaces = HBufC8::NewL(length);
+     TPtr8 FaceNroPtr = numberOfFaces->Des();
+     FaceNroPtr.AppendNum(faceCount-1);
+              
+     tmpPtr.Replace(res+1, length, FaceNroPtr);
+     //TPtr8 numberOfFaces;
+     
+     delete numberOfFaces;
+     //numberOfFaces.Copy();
+     
+     
+     // 1. Read JPEG image from the file to a buffer...
+     RFile file;
+     User::LeaveIfError( file.Open( iFileServer, a512x512TNFileName, EFileWrite ) );
+     CleanupClosePushL( file );
+     TInt size = 0;
+     file.Size(size);
+     HBufC8* jpegImage = HBufC8::NewL( size );
+     CleanupStack::PushL( jpegImage );
+     TPtr8 bufferDes( jpegImage->Des() );
+     User::LeaveIfError( file.Read( bufferDes ) );
+     CleanupStack::Pop( jpegImage );
+     CleanupStack::PopAndDestroy();
+     CleanupStack::PushL( jpegImage );
+     
+     file.Close();
+     
+     // 2. Instantiate Exif modifier in ECreate mode...
+     CExifModify* modify = CExifModify::NewL( jpegImage->Des(), CExifModify::EModify );
+     CleanupStack::PushL( modify );
+     
+     //3. Insert (Set) at least the mandatory Exif data.
+     //TInt descSize = 300;
+     //HBufC8* heapComment = HBufC8::NewL(descSize);
+     TPtr8 ptr = makerNote->Des();
+     
+     modify->SetMakerNoteL(ptr);
+     //modify->SetMakerNoteL(makerNote->Des());
+     
+     
+     // 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( jpegImage->Des() );
+     HBufC8* newExif;
+     TRAPD(err, newExif = modify->WriteDataL( jpegImage->Des() ));
+     
+     if(err != KErrNone)
+         {
+         TInt i=0;
+         }
+     
+     //TPtr8 tmp = newExif->Des();
+     
+     User::LeaveIfError( file.Replace( iFileServer, a512x512TNFileName, EFileWrite ) );
+     //Write Exif and jpeg image back to jpeg file
+     User::LeaveIfError(file.Write(*newExif));
+     
+     // Process the new Exif data
+     delete newExif;
+     newExif = NULL;
+     
+     // 5. Delete the modifier instance...
+     CleanupStack::PopAndDestroy( modify );
+     CleanupStack::PopAndDestroy( jpegImage );
+     
+     file.Close();
+    
+    DP0_IMAGIC(_L("CFaceBrowser::RemoveFaceCoordinate--"));
+    return KErrNone;
+    }
+
+
+//Writes face coordinates to Exif data if faces was found
+TInt CFaceBrowser::AddFaceCoordinate(const TFileName aFilename, RArray<TRect>& aCordArray)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::AddFaceCoordinate++"));
+    //Read first current maker note to new array from given file
+    RArray<TRect> newCordArray;
+    iUtils.ReadFaceCoordinatesL(aFilename, newCordArray);
+     
+    //Append existing coords to new coords array
+    for(TInt i=0; i<newCordArray.Count(); i++)
+        {
+        aCordArray.Append(newCordArray[i]);
+        }
+              
+     //Write all coords to file exif data manufactorer note
+    iUtils.WriteFaceCoordinatesL(aFilename, aCordArray);
+     
+    newCordArray.Close();
+    
+    DP0_IMAGIC(_L("CFaceBrowser::AddFaceCoordinate--"));
+
+    return KErrNone;
+    }
+
+
+HBufC8* CFaceBrowser::ReadExifMakerNoteL(const TDes &aFileName, TInt& aSize)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::ReadExifMakerNoteL++"));
+    HBufC8* makerNote;
+    
+    // 1. Read Exif image from the file to a buffer...
+    RFile file;
+    User::LeaveIfError( file.Open( iFileServer, aFileName , EFileRead ) );
+    CleanupClosePushL( file );
+    TInt size = 65536;
+        
+    HBufC8* exif = HBufC8::NewL( size );
+    CleanupStack::PushL( exif );
+    TPtr8 bufferDes( exif->Des() ); 
+    TInt err1 = file.Read( bufferDes );
+    TInt length = bufferDes.Length();
+    
+    if(length <= 0 )
+        {
+        CleanupStack::Pop( exif );
+        CleanupStack::PopAndDestroy();
+        //return NULL;
+        }
+    else
+        {
+        CleanupStack::Pop( exif );
+        CleanupStack::PopAndDestroy();
+        CleanupStack::PushL( exif );
+        
+        // 2. Instantiate Exif reader...
+        CExifRead* ExifRead;
+        TInt err = 0;
+        TRAP(err, ExifRead = CExifRead::NewL( exif->Des(),CExifRead::ENoJpeg ));//CExifRead::ENoTagChecking | CExifRead::ENoJpeg
+        
+        //HBufC8* comment = NULL;
+        if(err != KErrNone)
+            {
+            }
+        else
+            {
+            CleanupStack::PushL( ExifRead );
+        
+            // 3. Get required data from the Exif image...
+            TUint32  xRes;
+            TUint32  yRes;
+            ExifRead->GetPixelXDimension(xRes);
+            ExifRead->GetPixelYDimension(yRes);  
+                    
+            makerNote = ExifRead->GetMakerNoteL(); 
+            
+            // Delete the reader instance...
+            CleanupStack::PopAndDestroy( ExifRead );
+            }
+       
+        file.Close();
+        CleanupStack::PopAndDestroy( exif );
+        //DP0_IMAGIC(_L("CIEEngineImp::ReadExifData--"));
+        
+        if(makerNote == NULL)
+            {
+            User::Leave(KErrNotFound);
+            }
+        else
+            {
+            aSize = makerNote->Length();
+            //return (TUint8*)makerNote->Des().Ptr();
+            return makerNote;
+            }
+        //return comment->Des()->Ptr();
+        
+        }
+    DP0_IMAGIC(_L("CFaceBrowser::ReadExifMakerNoteL--"));
+    
+    return NULL;
+    }
+
+    
+// ================================ FACE BROWSING RELATED FUNCTIONS =============================== //
+
+//This is called from RunL when face browsing is started
+void CFaceBrowser::BrowseFacesL(CImageData* aImageData)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL++"));
+    
+    if(iBrowsingState != EFaceBrowsingRunning && iBrowsingState != ESingleFaceBrowsingRunning)
+        User::Leave(KErrNotSupported);
+    
+    TBool coordnatesExists = EFalse;
+    iCurrentImageData = aImageData;
+    
+    TFileName filename;
+    iCurrentImageData->GetFileName(filename, ESize512x512);
+    DP1_IMAGIC(_L("CFaceBrowser::BrowseFacesL 512x512TNFile = %S ++"), &filename);
+    
+    // 512x512 TN are supposed to be created in TN generation phase and should be present
+    if(!iCurrentImageData->IsImageReady(ESize512x512))
+        {
+        Cleanup();
+        User::Leave(KErrNotFound);
+        }        
+    else
+        {
+        iCurrentImageData->GetFileName(iCurrent512x512TNFileName, ESize512x512); //target file to write face coords
+        }
+    
+    //If coordinates exist we do not process image anymore
+    TRAPD(error, iUtils.ReadFaceCoordinatesL(iCurrent512x512TNFileName, iFaceCoordinates));
+    if (error == KErrNone)
+        {
+        if(iBrowsingState == ESingleFaceBrowsingRunning)
+            {
+            if(iBrowsingState == ESingleFaceBrowsingRunning)
+                 for(TInt i = 0; i<iFaceCoordinates.Count(); i++)
+                    iTempFaceCoordinates->Append(iFaceCoordinates[i]);
+            
+            iBrowsingState = ESingleFaceBrowsingComplete;
+            }
+        else
+            {
+            //Increment to the next image index
+            iNumberOfImagesBrowsed++;
+            //Check if we are at the end of image array
+            if(iNumberOfImagesBrowsed == iNumberOfImages)
+                {
+                iBrowsingState = EFaceBrowsingCompleted;
+                }
+            }
+        
+        //and continue to next image
+        ContinueLoop();
+        }
+    //Here we have image which has to be processed for face detection
+    else
+        {
+        iPrevBrowsingState = iBrowsingState;
+        iBrowsingState = ECreatingBitmap;
+        
+        TSize size;
+        if(aImageData->GetAspectRatio() > 1)
+            {
+            size.iWidth=320;
+            size.iHeight=320/aImageData->GetAspectRatio();
+            }
+        else
+            {
+            size.iWidth=320*aImageData->GetAspectRatio();
+            size.iHeight=320;
+            }
+        
+        if(size.iWidth%2 != 0)
+            size.iWidth++;
+        if(size.iHeight%2 != 0)
+            size.iHeight++;
+        
+        iBitmap = new (ELeave) CFbsBitmap();
+        iBitmap->Create(size, EColor16M);
+        
+        iSymbianImageDecoder = CImageDecoder::FileNewL(iFileServer, iCurrent512x512TNFileName, CImageDecoder::EPreferFastDecode);
+        iSymbianImageDecoder->Convert(&iStatus, *iBitmap, 0);
+        
+        if(!IsActive())
+            SetActive();
+        
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL --"));
+    }
+
+#ifdef IDLBGPS
+void CFaceBrowser::ContinueFBAfterImageConversionL()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::ContinueFBAfterImageConversionL ++"));
+    
+    iBrowsingState = iPrevBrowsingState;
+    
+    TSize size = iBitmap->SizeInPixels();
+    
+    //Init IDL
+    TInt value = 0;
+    InitializeL(EIDLFeatureFaceDetection, size, size, &value, ETrue);
+    
+    // Code for the previous face detection which needed YUV input
+    //TUint8* yuvArray;
+    //TInt yuvDataSize = size.iHeight * size.iWidth * 3 / 2;
+    //yuvArray = new TUint8 [yuvDataSize];
+    //
+    //ConvertRgb2Yuv(iBitmap, yuvArray, 3/*aBytesPerPixel*/, size);
+    // 
+    //iInputBuffer->Des().Copy(yuvArray, yuvDataSize);
+    
+    TInt bitmapSize = size.iHeight * size.iWidth * 3;
+    
+    // This is in the BGR order
+    iInputBuffer->Des().Copy((TUint8 *)iBitmap->DataAddress(), bitmapSize);
+    //delete yuvArray;
+#if 0
+    //just for testing --->
+    _LIT(KTestPath, "C:\\Images\\RGB2YUV.YUV");
+    TFileName temp;
+    temp.Copy(KTestPath);
+    
+    RFile file;
+    User::LeaveIfError(file.Replace(iFileServer, temp, EFileWrite));
+    TInt dataSize = iInputBuffer->Size();
+    file.Write(iInputBuffer->Des());
+    //file.Write(yuvArray);
+    file.Flush();
+    file.Close();    
+    //TODO, just for testing <---
+#endif
+
+#if 0
+    //just for testing ---> 
+    _LIT(KTestPath, "C:\\Images\\RawRGB.rgb");
+    TFileName temp;
+    temp.Copy(KTestPath);
+        
+    RFile file;
+    User::LeaveIfError(file.Replace(iFileServer, temp, EFileWrite));
+    TInt dataSize = iInputBuffer->Size();
+    file.Write(iInputBuffer->Des());
+    file.Flush();
+    file.Close();    
+    //just for testing <---
+#endif
+
+        
+    TInt error = KErrNone;
+    TRAP(error, BrowseFacesL(iCurrent512x512TNFileName, iFaceCoordinates));
+    
+    if(error != KErrNone)
+        {
+        Cleanup();
+        iFaceBrowserObserver.FaceBrowsingError(error);
+        }
+    
+#if 0
+    //only for debug
+    _LIT(KTestPath, "C:\\Images\\RGB2YUV.MBM");
+    TFileName temp;
+    temp.Copy(KTestPath);
+    iBitmap->Save(temp);
+#endif
+    
+    iBitmap->Reset();
+    delete iBitmap;
+    
+    if(iBrowsingState == ESingleFaceBrowsingRunning)
+        iBrowsingState = ESingleFaceDetectionComplete;
+    
+    ContinueLoop();
+    
+    DP0_IMAGIC(_L("CFaceBrowser::ContinueFBAfterImageConversionL --"));
+    }
+#endif
+
+//http://wiki.forum.nokia.com/index.php/TSS001195_-_RGB_to_YUV_conversion
+void CFaceBrowser::ConvertRgb2Yuv(CFbsBitmap* aSourceBitmap, TUint8* aYuv, TInt aBytesPerPixel, const TSize aSize)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::ConvertRgb2Yuv++"));
+    
+    // Definitions that help access each colour component in source bitmap
+    #define   sR ((TInt32)(s[2]))
+    #define   sG ((TInt32)(s[1]))
+    #define   sB ((TInt32)(s[0]))
+     
+    const TInt KImageNumPixels = aSize.iHeight*aSize.iWidth;
+     
+    // Lock source bitmap (CFbsBitmap)
+    aSourceBitmap->LockHeap(EFalse);
+    TUint8* s = (TUint8*)aSourceBitmap->DataAddress();
+        
+    TInt i = 0;
+    TInt ui = KImageNumPixels;
+    TInt vi = KImageNumPixels + KImageNumPixels/4;
+       
+    //iYuv is an array of TUint8 values, length (KImageNumPixels*3/2)
+         
+    for(TInt j=0; j < aSize.iHeight; j++)
+        {
+        for(TInt k=0; k < aSize.iWidth; k++)
+            {
+            // Y value is generated for each pixel
+            aYuv[i] = (TUint8)( (  66*sR + 129*sG +  25*sB + 128) >> 8 ) + 16;
+              
+            // U, V values are generated for every other pixel on every other scanline 
+            if(0 == j%2 && 0 == k%2)
+                {
+                aYuv[ui++] = (TUint8)( (-38*sR - 74*sG + 112*sB + 128) >> 8 ) + 128;
+                aYuv[vi++] = (TUint8)( (112*sR - 94*sG - 18*sB + 128) >> 8 ) + 128;
+                }
+            i++; 
+            s+=aBytesPerPixel; // Number of bytes representing one pixel in source
+                               // bitmap e.g. if bitmap display mode == EColor16M 
+                               // (24bits/pixel), then iBytesPerPixel == 3
+            }
+        }
+       
+    aSourceBitmap->UnlockHeap(EFalse);
+    // iYuv now contains the source frame converted to YUV420p format
+    
+    DP0_IMAGIC(_L("CFaceBrowser::ConvertRgb2Yuv--"));
+    }
+
+#ifdef IDLBGPS
+//This is called after YUV data has been completed
+void CFaceBrowser::BrowseFacesL(const TFileName a512x512TNFileName, RArray<TRect>& aFaceCoordinates)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL ++"));
+    
+       
+    TPtr8 inBuffer = iInputBuffer->Des();
+    TPtr8 outBuffer = iOutputBuffer->Des();
+    
+    iIDLImageProcessor->SetInOutDataL(inBuffer, outBuffer);
+    iIDLImageProcessor->ProcessImageL();
+    
+    TInt count = aFaceCoordinates.Count();
+    for(TInt i=0; i<count; i++)
+        aFaceCoordinates.Remove(0);
+    
+    GetFaceCoordinates(iNumberOfFaces, aFaceCoordinates);
+    
+    //Add number of faces to image data
+    iCurrentImageData->SetNumberOfFaces(iNumberOfFaces);
+    
+    if(iBrowsingState == ESingleFaceBrowsingRunning)
+         for(TInt i = 0; i<aFaceCoordinates.Count(); i++)
+            iTempFaceCoordinates->Append(aFaceCoordinates[i]);
+ 
+    iUtils.WriteFaceCoordinatesL(a512x512TNFileName, aFaceCoordinates);
+    
+    if(iBrowsingState == EFaceBrowsingRunning)
+        {
+        if(iBrowsingState == EFaceBrowsingRunning)
+            iNumberOfImagesBrowsed++;
+        
+        if(iNumberOfImagesBrowsed == iNumberOfImages)
+            iBrowsingState = EFaceBrowsingCompleted;
+        }
+    else if(iBrowsingState == ESingleFaceBrowsingRunning)
+        {
+        iBrowsingState = ESingleFaceDetectionComplete;
+        }
+    
+        
+    DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL --"));
+    }
+
+void CFaceBrowser::GetFaceCoordinates(TInt& aNumberOfFaces, RArray<TRect>& aCordArray)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::GetFaceCoordinates ++"));
+    
+    iIDLImageProcessor->GetFacesDetected(aNumberOfFaces);
+    
+    if(aNumberOfFaces <= 0)
+        DP0_IMAGIC(_L("No faces found!!!"));
+    else
+        {
+        DP1_IMAGIC(_L("Number of faces found: %d"), aNumberOfFaces);
+        
+        // Clean up the coordinate array
+        if(aCordArray.Count() > 0)
+            {
+            TInt count = aCordArray.Count();
+            for(TInt i=0; i<count; i++)
+                aCordArray.Remove(0);
+            }
+        
+        iIDLImageProcessor->GetFaceCoordinates(aCordArray);
+        aCordArray.SortSigned();
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::GetFaceCoordinates --"));
+    }
+#endif
+
+// =============================== FACE CROPPING RELATED FUNCTIONS ============================ //
+
+void CFaceBrowser::CropFacesL(CImageData* aImageData)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::CropFacesL ++"));
+    
+    TInt error = KErrNone;
+    iCurrentImageData = aImageData;
+    iNumberOfFacesCropped = 0;
+    
+    TFileName imageFileName;
+    aImageData->GetFileName(imageFileName, EFullSize);
+    error = MakeFacesDir(imageFileName);
+    
+    if(error != KErrNone && error != KErrAlreadyExists)
+        User::Leave(error);
+    
+    // 512x512 and 320x320 TN are supposed to be created in TN generation phase and should be present
+    if(!iCurrentImageData->IsImageReady(ESize512x512) || !iCurrentImageData->IsImageReady(EFullSize))
+        {
+        Cleanup();
+        User::Leave(KErrNotFound);
+        }        
+    else
+        {
+        iCurrentImageData->GetFileName(iCurrent512x512TNFileName, ESize512x512);
+        iCurrentImageData->GetFileName(iCurrentImageFileName, EFullSize);
+        }
+    
+    // We assume that all the images were searched for faces before face cropping started
+    // Hence not checking if face coordinates exists or n ot
+    iUtils.ReadFaceCoordinatesL(iCurrent512x512TNFileName, iFaceCoordinates);
+    
+    if(iFaceCoordinates.Count() == 0)
+        {
+        iNumberOfImagesBrowsed++;
+        
+        if(iNumberOfImagesBrowsed == iNumberOfImages)
+            iBrowsingState = EFaceCroppingCompleted;
+                
+        ContinueLoop();
+        }
+    else
+        {
+        iTotalNumberOfFaces +=  iFaceCoordinates.Count();
+        DP1_IMAGIC(_L("iTotalNumberOfFaces = %d"), iTotalNumberOfFaces);
+        
+        iImageDecoder->GetImageSizeL(iCurrentImageFileName, iSize);
+        
+        if(!CheckOddSize(iSize))
+            {
+            TInt size = iSize.iWidth * iSize.iHeight * 3 / 2;
+                    
+            PrepareInOutBuffersL(ETrue, size, EFalse, 0);
+            
+            iImageDecoder->ConvertJpeg2YuvL(iCurrentImageFileName, *iInputBuffer);
+            }
+        else
+            {
+            iNumberOfImagesBrowsed++;
+            
+            if(iNumberOfImagesBrowsed == iNumberOfImages)
+                iBrowsingState = EFaceCroppingCompleted;
+                            
+            ContinueLoop();
+            }        
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::CropFacesL --"));
+    }
+
+
+void CFaceBrowser::CropFacesL(const TFileName /*aImageFileName*/, RArray<TRect>& aFaceCoordinates)
+    {
+    DP1_IMAGIC(_L("CFaceBrowser::CropFacesL++, number of faces: %d"), aFaceCoordinates.Count());
+
+#ifdef IDLBGPS_CROP
+
+    TRect rect(0, 0, 0, 0);
+    TParse parser;
+    parser.Set(aImageFileName, NULL, NULL);
+        
+    iNumberOfImagesBrowsed++;
+    
+    // Clean the face data array
+    if(iFaceYuvDataArray.Count() > 0)
+        {
+        TCroppedFaces temp;
+        HBufC8* buffer = NULL;
+        TInt count  = iFaceYuvDataArray.Count();
+        
+        for(TInt i=0; i<count; i++)
+            {
+            temp = iFaceYuvDataArray[0];
+            
+            iFaceYuvDataArray.Remove(0);
+            
+            buffer = temp.iYuvdata;
+            
+            delete buffer;
+            buffer = NULL;
+            }
+        }
+    
+    for(TInt faceIndex=0; faceIndex<aFaceCoordinates.Count(); faceIndex++)
+        {
+        TSize tnSize;
+        TFileName thumbnailFileName;
+        
+        iCurrentImageData->GetFileName(thumbnailFileName, ESize32x32);
+        iImageDecoder->GetImageSizeL(thumbnailFileName, tnSize);
+        
+        rect = GetFaceRect(iSize, tnSize, aFaceCoordinates[faceIndex]);
+        
+        InitializeL(EIDLFeatureCrop, iSize, rect.Size(), &rect, EFalse);
+        
+        TPtr8 inBuffer = iInputBuffer->Des();
+        TPtr8 outBuffer = iOutputBuffer->Des();
+        
+        iIDLImageProcessor->SetInOutDataL(inBuffer, outBuffer);
+        iIDLImageProcessor->ProcessImageL();
+        
+        DP1_IMAGIC(_L("Face cropped: %d"), faceIndex);
+        
+        TCroppedFaces croppedFace;
+        croppedFace.iYuvdata = HBufC8::NewL(iOutputBuffer->Size());
+        croppedFace.iYuvdata->Des().Copy(iOutputBuffer->Des());
+        
+        croppedFace.iFileName.Append(parser.DriveAndPath());
+        croppedFace.iFileName.Append(KFaces);
+        croppedFace.iFileName.Append(parser.Name());
+        croppedFace.iFileName.Append(KUnderScr);
+        croppedFace.iFileName.AppendNum(faceIndex);
+        croppedFace.iFileName.Append(parser.Ext());
+        
+        croppedFace.iCroppedSize = rect.Size();        
+        
+        iFaceYuvDataArray.Append(croppedFace);
+        iCroppedFilenames->Append(croppedFace.iFileName);
+        }
+#endif
+    
+    iBrowsingState = EEncodingFaces;
+    
+    DP0_IMAGIC(_L("CFaceBrowser::CropFacesL --"));
+    }
+
+TRect CFaceBrowser::GetFaceRect(const TSize aOrgImageSize, const TSize aRelImageSize, const TRect aFaceRect)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::GetFaceRect ++"));
+
+    TRect faceRect(0, 0, 0, 0);
+    
+    faceRect.iTl = aFaceRect.iTl;
+    faceRect.iBr = aFaceRect.iBr;
+    
+    TReal width = 0;
+    TReal height = 0;
+    TReal aspectRatioX = 0;
+    TReal aspectRatioY = 0;
+    
+    //Converting the face rect to original image size
+    aspectRatioX = (TReal)aOrgImageSize.iWidth / (TReal)aRelImageSize.iWidth;
+    aspectRatioY = (TReal)aOrgImageSize.iHeight / (TReal)aRelImageSize.iHeight;
+    
+    //Make cropped rect bigger
+    //faceRect.Grow(faceRect.Width()/4, (faceRect.Height()/2));
+    faceRect.Grow(faceRect.Width()/2.5, (faceRect.Height()/1.5));
+    //And move ract bit higher
+    //faceRect.Move(0, -(faceRect.Height()/6));
+    faceRect.Move(0, -(faceRect.Height()/8));
+    
+    if(aspectRatioX != 1.0 || aspectRatioY != 1.0)
+        {
+        //Scale cropping rect size to original  
+        faceRect.iTl.iX *= aspectRatioX;
+        faceRect.iTl.iY *= aspectRatioY;
+        faceRect.iBr.iX *= aspectRatioX;
+        faceRect.iBr.iY *= aspectRatioY;
+        
+        // Check for extreme values and negative values
+        // Any invalid values will be made max valid values
+        if(faceRect.iTl.iX < 0) faceRect.iTl.iX = 0;
+        if(faceRect.iTl.iY < 0) faceRect.iTl.iY = 0;
+        if(faceRect.iTl.iX >= aOrgImageSize.iWidth) faceRect.iBr.iX = aOrgImageSize.iWidth-1;
+        if(faceRect.iTl.iY >= aOrgImageSize.iHeight) faceRect.iBr.iY = aOrgImageSize.iHeight-1;
+        if(faceRect.iBr.iX > aOrgImageSize.iWidth) faceRect.iBr.iX = aOrgImageSize.iWidth;
+        if(faceRect.iBr.iY > aOrgImageSize.iHeight) faceRect.iBr.iY = aOrgImageSize.iHeight;
+        
+        }    
+    
+    // Make sure that the width and height are divisible by 2, else encoder/decoder will give -10 error
+    TReal remainder = 0;
+    
+    Math::Mod(remainder, faceRect.Size().iWidth, 2);
+    
+    if(remainder != 0)
+        faceRect.iBr.iX--;
+    
+    Math::Mod(remainder, faceRect.Size().iHeight, 2);
+    
+    if(remainder != 0)
+        faceRect.iBr.iY--;
+
+    DP4_IMAGIC(_L("CFaceBrowser::GetFaceRect faceRect(%d, %d, %d, %d)--"), faceRect.iTl.iX, faceRect.iTl.iY, faceRect.iBr.iX, faceRect.iBr.iY);
+    
+    return faceRect;
+    }
+
+TInt CFaceBrowser::MakeFacesDir(const TFileName aImageName)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::MakeFacesDir ++"));
+    
+    TInt error = KErrNone;
+    
+    TParse parser;
+    parser.Set(aImageName, NULL, NULL);
+    
+    TFileName faceDir = parser.DriveAndPath();
+    faceDir.Append(KFaces);
+    
+    if(BaflUtils::PathExists(iFileServer, faceDir))
+        error = KErrAlreadyExists;
+    else
+        {
+        error = iFileServer.MkDir(faceDir);
+        
+        if(error == KErrNone)
+            error = iFileServer.SetAtt(faceDir, KEntryAttNormal, KEntryAttNormal);
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::MakeFacesDir --"));
+    
+    return error;
+    }
+
+void CFaceBrowser::EncodeFaceL(const TCroppedFaces aCroppedFace)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::EncodeFaceL ++"));
+    
+    HBufC8* buffer = aCroppedFace.iYuvdata;
+   
+    TFileName fileName = aCroppedFace.iFileName;
+    TSize size = aCroppedFace.iCroppedSize;
+    
+    DP1_IMAGIC(_L("Encoding Image: %S"), &fileName);
+    DP2_IMAGIC(_L("Size: %dx%d"), size.iWidth, size.iHeight);
+    
+    iImageEncoder->ConvertYuv2JpegL(fileName, *buffer, size);
+    
+    DP0_IMAGIC(_L("CFaceBrowser::EncodeFaceL --"));
+    }
+
+// =============================== COMMON FUNCTIONS ============================================== //
+
+#ifdef IDLBGPS
+void CFaceBrowser::InitializeL(const TIDLFeatures aIDLFeature, const TSize aInSize, const TSize aOutSize, TAny* aValue, TBool aInBufferCreate)
+    {
+    DP4_IMAGIC(_L("CFaceBrowser::InitializeL, aInsize = %dx%d, aOutSize = %dx%d ++"), aInSize.iWidth, aInSize.iHeight, aOutSize.iWidth, aOutSize.iHeight);
+    
+//    TInt value = 0;
+    TInt outputBufferSize = 0;
+    //TInt inputBufferSize = (aInSize.iWidth * aInSize.iHeight * 3 / 2);
+    TInt inputBufferSize = aInSize.iWidth * aInSize.iHeight * 3;
+    
+    iIDLImageProcessor->SetFeatureL(aIDLFeature, aValue);
+    //iIDLImageProcessor->InitializeFeatureL(aInSize, 
+    //                                        aOutSize, 
+    //                                        EIDLFormatYUV420, 
+    //                                        EIDLFormatYUV420);
+    iIDLImageProcessor->InitializeFeatureL(aInSize, 
+                                                aOutSize, 
+                                                EIDLFormatRGB, 
+                                                EIDLFormatRGB);
+    
+    iIDLImageProcessor->AllocateBuffersL(outputBufferSize);
+    
+    PrepareInOutBuffersL(aInBufferCreate, inputBufferSize, ETrue, outputBufferSize);
+    
+    DP0_IMAGIC(_L("CFaceBrowser::InitializeL --"));
+    }
+#endif
+
+void CFaceBrowser::PrepareInOutBuffersL(TBool aInBufferCreate, const TInt aInBufSize, TBool aOutBufferCreate, const TInt aOutBufSize)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::PrepareInOutBuffersL ++"));
+    
+    if(aInBufferCreate)
+        {
+        if(aInBufSize <= 0)
+            User::Leave(KErrArgument);
+        
+        if(iInputBuffer)
+            {
+            delete iInputBuffer;
+            iInputBuffer = NULL;
+            }
+        
+        iInputBuffer = HBufC8::NewL(aInBufSize);
+        }
+    
+    if(aOutBufferCreate)
+        {
+        if(aOutBufSize <= 0)
+            User::Leave(KErrArgument);
+        
+        if(iOutputBuffer)
+            {
+            delete iOutputBuffer;
+            iOutputBuffer = NULL;
+            }
+        
+        iOutputBuffer = HBufC8::NewL(aOutBufSize);
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::PrepareInOutBuffersL --"));
+    }
+
+TBool CFaceBrowser::CheckOddSize(const TSize aSize)
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::CheckOddSize ++"));
+    
+    TReal remainder = 0;
+    
+    Math::Mod(remainder, aSize.iWidth, 2);
+    
+    if(remainder != 0) return ETrue;
+    
+    Math::Mod(remainder, aSize.iHeight, 2);
+    
+    if(remainder != 0) return ETrue;
+    
+    DP0_IMAGIC(_L("CFaceBrowser::CheckOddSize --"));
+    
+    return EFalse;
+    }
+
+#if 0
+TFileName CFaceBrowser::MakeTNFileName(const TFileName aImageFileName, TBool a512TNFile, TBool /*a320TNFileName*/)
+    {
+    DP1_IMAGIC(_L("CFaceBrowser::Make512x512TNFileName, aImageFileName = %S ++"), &aImageFileName);
+    
+    TParse fileNameParser;
+    fileNameParser.Set(aImageFileName, NULL, NULL);
+    
+    TFileName tnFileName;
+    
+    tnFileName = fileNameParser.DriveAndPath();
+    
+    if(a512TNFile /*&& !a320TNFileName*/)
+        {
+        tnFileName.Append(K512x512TNFilePath);
+        tnFileName.Append(fileNameParser.Name());
+        tnFileName.Append(KTNExt);
+        }
+/*    if(!a512TNFile && a320TNFileName)
+        {
+        tnFileName.Append(K320TNFilePath);
+        tnFileName.Append(fileNameParser.Name());
+        tnFileName.Append(K320TNFileExt);
+        }*/
+    
+    DP1_IMAGIC(_L("CFaceBrowser::Make512x512TNFileName fileName512x512TN = %S --"), &tnFileName);
+    
+    return tnFileName;
+    }
+#endif    
+
+void CFaceBrowser::Cleanup()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::Cleanup ++"));
+    
+    if(iImageDecoder)
+            iImageDecoder->CancelDecoding();
+            
+    if(iImageEncoder)
+        iImageEncoder->CancelEncoding();
+        
+    if(iFaceCoordinates.Count() > 0)
+        {
+        TInt count = iFaceCoordinates.Count();
+        for(TInt i=0; i<count; i++)
+            iFaceCoordinates.Remove(0);
+        }
+    
+    if(iFaceYuvDataArray.Count() > 0)
+        {
+        TCroppedFaces croppedFaces;
+        HBufC8* buffer = NULL;
+        TInt count = iFaceYuvDataArray.Count();
+        
+        for(TInt i=0; i<count; i++)
+            {
+            croppedFaces = iFaceYuvDataArray[0];
+            iFaceYuvDataArray.Remove(0);
+            
+            buffer = croppedFaces.iYuvdata;
+            
+            delete buffer;
+            buffer = NULL;
+            }
+        }
+/*    
+    if(iImageDataArray.Count() > 0)
+        {
+        TInt count = iImageDataArray.Count();
+        for(TInt i=0; i<count; i++)
+            iImageDataArray.Remove(0);
+        }
+ */   
+    iNumberOfFaces = 0;
+    iNumberOfImages = 0;
+    iNumberOfImagesBrowsed = 0;
+    iNumberOfFacesCropped = 0;
+    
+    iCurrentImageData = NULL;
+    
+    iCurrentImageFileName = KEmptyString;
+    iCurrent512x512TNFileName = KEmptyString;
+    //iCurrent320x320TNFileName = KEmptyString;
+    
+    iBrowsingState = EStateIdle;
+    
+    DP0_IMAGIC(_L("CFaceBrowser::Cleanup --"));
+    }
+
+void CFaceBrowser::Cleanup2()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::Cleanup2 ++"));
+    
+    if(iImageDecoder)
+        iImageDecoder->CancelDecoding();
+        
+    if(iImageEncoder)
+        iImageEncoder->CancelEncoding();
+    
+    if(iFaceYuvDataArray.Count() > 0)
+        {
+        TCroppedFaces croppedFaces;
+        HBufC8* buffer = NULL;
+        TInt count = iFaceYuvDataArray.Count();
+        
+        for(TInt i=0; i<count; i++)
+            {
+            croppedFaces = iFaceYuvDataArray[0];
+            iFaceYuvDataArray.Remove(0);
+            
+            buffer = croppedFaces.iYuvdata;
+            
+            delete buffer;
+            buffer = NULL;
+            }
+        }
+
+    iBrowsingState = EStateIdle;
+    
+    DP0_IMAGIC(_L("CFaceBrowser::Cleanup2 --"));
+    }
+
+void CFaceBrowser::ContinueLoop()
+    {
+    DP0_IMAGIC(_L("CFaceBrowser::ContinueLoop++"));
+    
+    if(!IsActive())
+        {
+        SetActive();
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete(status, KErrNone);            
+        }
+    
+    DP0_IMAGIC(_L("CFaceBrowser::ContinueLoop--"));
+    }
+
+void CFaceBrowser::WriteFaceCoordToExif(TInt numOfFaces, RArray<TRect> faceCoordinates) {
+    //Add number of faces to image data
+    iCurrentImageData->SetNumberOfFaces(numOfFaces);
+    
+    if(iBrowsingState == ESingleFaceBrowsingRunning)
+         for(TInt i = 0; i<iFaceCoordinates.Count(); i++)
+            iTempFaceCoordinates->Append(iFaceCoordinates[i]);
+ 
+    iUtils.WriteFaceCoordinatesL(iCurrent512x512TNFileName, faceCoordinates);
+}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/src/IEImageDecoder.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,228 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include "IEImageDecoder.h"
+
+// ========================== MEMBER FUNCTIONS ============================= //
+
+CIEImageDecoder* CIEImageDecoder::NewL(RFs& aFileServer, MDecodingObserver& aObserver)
+{
+	CIEImageDecoder* self = new (ELeave) CIEImageDecoder(aFileServer, aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CIEImageDecoder::~CIEImageDecoder()
+{
+	if(iImageDecoder)
+	{
+		delete iImageDecoder;
+		iImageDecoder = NULL;
+	}
+	
+	if(iExtImageDecoder)
+	{
+		delete iExtImageDecoder;
+		iExtImageDecoder = NULL;
+	}
+	
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+}
+
+//EPriorityIdle, EPriorityLow, EPriorityStandard, EPriorityUserInput, EPriorityHigh
+CIEImageDecoder::CIEImageDecoder(RFs& aFileServer, MDecodingObserver& aObserver)
+: CActive(EPriorityStandard), iFileServer(aFileServer), iObserver(aObserver), iSrcPtr(NULL, 0, 0)
+{	
+}
+
+void CIEImageDecoder::ConstructL()
+{
+	CActiveScheduler::Add(this);
+	
+	iDecoderBusy = EFalse;
+	iDecode2Yuv = EFalse;
+	iDecode2Bitmap = EFalse;
+	
+	iNumOfBitmaps = 0;
+}
+
+void CIEImageDecoder::RunL()
+{
+/*	
+    TPtr8 ptr = iVisualFrame->DataPtrL();
+	TInt dataSize = ptr.Size(); 
+	TUint8* bufU = (TUint8*) ptr.Ptr();
+*/
+	if(iDecode2Yuv)
+	{
+		iDecode2Yuv = EFalse;
+		
+		if(iExtImageDecoder)
+	    {
+	        delete iExtImageDecoder;
+	        iExtImageDecoder = NULL;
+	    }
+		
+		//iObserver.YuvImageReady(iStatus.Int());
+	}
+		
+	if(iDecode2Bitmap)
+	{
+		iDecode2Bitmap = EFalse;
+		
+		if(iImageDecoder)
+	    {
+	        delete iImageDecoder;
+	        iImageDecoder = NULL;
+	    }
+		
+		iObserver.BitmapReady(iStatus.Int());
+	}		
+	
+	iDecoderBusy = EFalse;	
+}
+
+void CIEImageDecoder::DoCancel()
+{
+	
+}
+
+void CIEImageDecoder::GetImageSizeL(const TFileName aFileName, TSize& aSize)
+{
+	if(iImageDecoder)
+	{
+		delete iImageDecoder;
+		iImageDecoder = NULL;
+	}
+	
+	iImageDecoder = CImageDecoder::FileNewL(iFileServer, aFileName);
+	TFrameInfo frameInfo = iImageDecoder->FrameInfo();
+	
+	aSize.iWidth = frameInfo.iOverallSizeInPixels.iWidth;
+	aSize.iHeight = frameInfo.iOverallSizeInPixels.iHeight;
+	
+	delete iImageDecoder;
+	iImageDecoder = NULL;	
+}
+
+void CIEImageDecoder::ConvertJpeg2YuvL(const TDesC& aSourceFile, 
+								HBufC8& aBuffer)
+{
+	TInt fileSize = 0;
+	TInt blocks = 0;
+	
+	iDecoderBusy = ETrue;
+	iDecode2Yuv = ETrue;
+	
+	if(iExtImageDecoder)
+	{
+		delete iExtImageDecoder;
+		iExtImageDecoder = NULL;
+	}
+	
+	iExtImageDecoder = CExtJpegDecoder::FileNewL(iFileServer, aSourceFile);
+	
+	TFrameInfo frameInfo = iExtImageDecoder->FrameInfo();
+	
+	TInt width = frameInfo.iOverallSizeInPixels.iWidth;
+	TInt height = frameInfo.iOverallSizeInPixels.iHeight;
+
+	/*if(width%2 != 0)
+	    width++;
+    if(height%2 != 0)
+        height++;*/
+	        
+	TPtr8 bufPtr = aBuffer.Des();
+	
+	iBufU = (TUint8*)bufPtr.Ptr();
+	
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+	
+	iVisualFrame = CVisualFrame::NewL(bufPtr, 
+											TSize(width, height), 
+											CVisualFrame::EFormatYUV420Planar);
+	
+	
+	iExtImageDecoder->ConvertL(&iStatus, iVisualFrame, blocks);
+	
+	if(!IsActive())
+		SetActive();
+	
+}
+
+
+void CIEImageDecoder::ConvertJpeg2BitmapL(CFbsBitmap& aDestBitmap, TDesC8& aSourceData)
+{
+	TInt frameNumber = 0;
+	
+	iDecoderBusy = ETrue;
+	iDecode2Bitmap = ETrue;
+	
+	TInt dataSize = aSourceData.Size();
+	
+	iSrcPtr.Set((TUint8*)aSourceData.Ptr(), aSourceData.Size(), aSourceData.Size());
+	
+	if(iImageDecoder)
+	{
+		delete iImageDecoder;
+		iImageDecoder = NULL;
+	}
+	
+	iImageDecoder = CImageDecoder::DataNewL(iFileServer, iSrcPtr);
+	
+	iImageDecoder->Convert(&iStatus, aDestBitmap, frameNumber);
+	
+	iNumOfBitmaps++;
+	
+	if(!IsActive())
+		SetActive();
+}
+
+
+TPtr8 CIEImageDecoder::GetVisualFrame()
+{
+	return iVisualFrame->DataPtrL();	 
+}
+
+void CIEImageDecoder::CancelDecoding()
+{
+	if(iDecoderBusy)
+	{
+		if(iImageDecoder)
+			iImageDecoder->Cancel();
+	
+		if(iExtImageDecoder)
+			iExtImageDecoder->Cancel();
+	}
+		
+	if(IsActive())
+		Cancel();	
+}
+
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/src/IEImageEncoder.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,187 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+// Include files
+#include "IEImageEncoder.h"
+
+// ========================== MEMBER FUNCTIONS ============================= //
+
+CIEImageEncoder* CIEImageEncoder::NewL(RFs& aFileServer, MEncodingObserver& aObserver)
+{
+	CIEImageEncoder* self = new (ELeave) CIEImageEncoder(aFileServer, aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CIEImageEncoder::~CIEImageEncoder()
+{
+	if(iFrameImageData)
+	{
+		delete iFrameImageData;
+		iFrameImageData = NULL;
+	}
+	
+	if(iImageEncoder)
+	{
+		delete iImageEncoder;
+		iImageEncoder = NULL;
+	}
+	
+	if(iExtImageEncoder)
+	{
+		delete iExtImageEncoder;
+		iExtImageEncoder = NULL;
+	}
+	
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+}
+
+
+CIEImageEncoder::CIEImageEncoder(RFs& aFileServer, MEncodingObserver& aObserver)
+: CActive(EPriorityStandard), iFileServer(aFileServer), iObserver(aObserver)
+{	
+}
+
+void CIEImageEncoder::ConstructL()
+{
+	iEncoderBusy = EFalse;
+	
+	CActiveScheduler::Add(this);
+}
+
+void CIEImageEncoder::RunL()
+{
+	TInt error = iStatus.Int();
+	
+	//iObserver.JpegImageReady(iStatus.Int());
+	iEncoderBusy = EFalse;
+}
+
+void CIEImageEncoder::DoCancel()
+{
+	
+}
+
+void CIEImageEncoder::ConvertYuv2JpegL(HBufC8*& aDestBuffer, 
+								HBufC8& aSourceBuffer, 
+								const TSize aSize)
+{
+	TInt blocks = 0;
+
+	iEncoderBusy = ETrue;
+
+	if(iExtImageEncoder)
+	{
+		delete iExtImageEncoder;
+		iExtImageEncoder = NULL;
+		
+	}
+	
+	iExtImageEncoder = CExtJpegEncoder::DataNewL(aDestBuffer, _L8("image/jpeg"));
+	
+	TPtr8 ptrSrc = aSourceBuffer.Des();
+	TInt bufSize = aSourceBuffer.Size();
+		
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+	
+	iVisualFrame = CVisualFrame::NewL(ptrSrc, aSize, CVisualFrame::EFormatYUV420Planar);
+	
+	SetJpegImageDataL();
+	iExtImageEncoder->ConvertL(&iStatus, iVisualFrame, blocks, iFrameImageData);
+	
+	if(!IsActive())
+		SetActive();
+}
+
+void CIEImageEncoder::ConvertYuv2JpegL(TDesC& aFileName, 
+								HBufC8& aSourceBuffer, 
+								const TSize aSize)
+{
+	TInt blocks = 0;
+
+	iEncoderBusy = ETrue;
+
+	if(iExtImageEncoder)
+	{
+		delete iExtImageEncoder;
+		iExtImageEncoder = NULL;
+		
+	}
+	
+	iExtImageEncoder = CExtJpegEncoder::FileNewL(iFileServer, aFileName, _L8("image/jpeg"));
+	
+	TPtr8 ptrSrc = aSourceBuffer.Des();
+	TInt bufSize = aSourceBuffer.Size();
+		
+	if(iVisualFrame)
+	{
+		delete iVisualFrame;
+		iVisualFrame = NULL;
+	}
+	
+	iVisualFrame = CVisualFrame::NewL(ptrSrc, aSize, CVisualFrame::EFormatYUV420Planar);
+	
+	SetJpegImageDataL();
+	iExtImageEncoder->ConvertL(&iStatus, iVisualFrame, blocks, iFrameImageData);
+	
+	if(!IsActive())
+		SetActive();
+}
+
+void CIEImageEncoder::SetJpegImageDataL()
+{
+	TJpegImageData* jpegImageData;
+	jpegImageData = new (ELeave) TJpegImageData;
+	jpegImageData->iSampleScheme = TJpegImageData::EColor420;
+	jpegImageData->iQualityFactor = 90;	
+	
+	if(iFrameImageData)
+	{
+		delete iFrameImageData;
+		iFrameImageData = NULL;
+	}
+	
+	iFrameImageData = CFrameImageData::NewL();
+	// Ownership of jpegImageData lies with CFrameImageData
+	User::LeaveIfError(iFrameImageData->AppendImageData(jpegImageData));
+}
+
+void CIEImageEncoder::CancelEncoding()
+{
+	if(iEncoderBusy)
+	{
+		if(iImageEncoder)
+			iImageEncoder->Cancel();
+		if(iExtImageEncoder)
+			iExtImageEncoder->Cancel();
+	}
+	
+	if(IsActive())
+		Cancel();
+}
+
+// EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IEBgps/src/IETNGenerator.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,709 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors: Juha Kauppinen, Mika Hokkanen
+* 
+* Description: Photo Browser
+*
+*/
+
+#include <ImageConversion.h> //CImageDecoder
+#include <FBS.H> //CFbsBitmap
+#include <BAUTILS.H>
+//#include <IEBGPSTrace.h>
+
+#include "IETNGenerator.h"
+#include "IEBgpServerSession.h" 
+#include <hal.h> 
+#include "ImagicConsts.h"
+#include "ieengineutils.h" 
+
+_LIT8(KMimeJpeg, "image/jpeg");
+_LIT8(KMimePng, "image/png");
+
+#define DO_NOT_USE_SCALING
+
+
+
+CIETNGeneratorAO* CIETNGeneratorAO::NewL(RFs& aFileServer, MIEThumbNailObserver &aObserver)
+{
+	CIETNGeneratorAO* self = new (ELeave) CIETNGeneratorAO(aFileServer, aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+CIETNGeneratorAO::~CIETNGeneratorAO()
+{
+    DP0_IMAGIC((_L("CIETNGeneratorAO::~CIETNGeneratorAO ++")));
+ 	if(IsActive())
+		Cancel();
+ 	
+	 CancelOutStaningRequests();
+	 DeleteObjects();
+	 
+	 DP0_IMAGIC((_L("CIETNGeneratorAO::~CIETNGeneratorAO --")));
+}
+
+//EPriorityIdle, EPriorityLow, EPriorityStandard, EPriorityUserInput, EPriorityHigh
+CIETNGeneratorAO::CIETNGeneratorAO(RFs& aFileServer, MIEThumbNailObserver &aObserver)
+: iFileServer(aFileServer),
+  iThumbnailObserver(aObserver),
+  CActive(EPriorityStandard)
+{
+	
+}
+
+void CIETNGeneratorAO::ConstructL()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::ConstructL ++")));
+
+	CActiveScheduler::Add(this);
+	iError = KErrNone;
+	decoderUid = CIEEngineUtils::GetImageDecoderUid();
+	//i512x512TnBitmap = new (ELeave) CFbsBitmap();
+	
+	DP0_IMAGIC((_L("CIETNGeneratorAO::ConstructL --")));
+    }
+
+void CIETNGeneratorAO::RunL()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::RunL ++")));
+    iError = iStatus.Int();
+	
+#ifdef _IMAGIC_DEBUG
+    TInt mem = 0;
+	TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem);
+	DP1_IMAGIC(_L("CIETNGeneratorAO::RunL - mem: %d"),mem);
+#endif
+	
+	if(iError != KErrNone)
+	    {
+	    DeleteObjects();
+        
+        iConvertStatus = ENone;
+        
+        // inform to higher layer... and delete thumbnails we tried to create
+        DP1_IMAGIC(_L("CIETNGeneratorAO::RunL - Something wrong %d"), iError);      
+        iThumbnailObserver.ThumbNailGenerationCompleted(iError);
+	    }
+	
+	switch (iConvertStatus)
+	    {
+	    case EDecoding:
+	        {
+	        DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EDecoding")));
+	        TRAPD(err, DecodeL()); // TODO handle errors
+	        if (err != KErrNone) 
+	            {
+	            DP1_IMAGIC((_L("CIETNGeneratorAO::RunL - EDecoding error: %d")), err);
+	            iThumbnailObserver.ThumbNailGenerationCompleted(err); //ASSERT(0);
+	            iConvertStatus = ENone;
+	            }
+	        else
+	            {
+#ifdef DO_NOT_USE_SCALING
+	            iConvertStatus = EEncoding;
+#else
+	            iConvertStatus = EScaling;
+#endif
+                SetActive();
+	            }
+	        }
+	        break;
+		
+	    case EScaling:
+	        {
+	        DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EScaling")));
+	        TRAPD(err, ScaleL());
+            if (err != KErrNone) 
+                {
+                DP1_IMAGIC((_L("CIETNGeneratorAO::RunL - EScaling error: %d")), err);
+                iThumbnailObserver.ThumbNailGenerationCompleted(err); //ASSERT(0);
+                iConvertStatus = ENone;
+                }
+            else
+                {
+                iConvertStatus = EEncoding;
+                SetActive();
+                }
+	        }
+	        break;
+        	
+	    case EEncoding:
+	        {
+	        DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EEncoding")));
+	        TRAPD(err, EncodeL()); // TODO handle errors
+	        if (err != KErrNone)
+	            {
+	            DP1_IMAGIC((_L("CIETNGeneratorAO::RunL - EEncoding error: %d")), err);
+                iThumbnailObserver.ThumbNailGenerationCompleted(err); //ASSERT(0);
+                iConvertStatus = ENone;
+	            }
+	        else
+	            {
+	            iConvertStatus = EReady;
+
+#ifdef USE_BITMAPS_TNS
+	            if(!IsJPEG(iThumbnailSize))
+	                {
+	                //When saving TN as bitmap we need to complete request immeadtely 
+	                //because bitmap saving is handled by CFbsBitmap class instead of image encoder
+	                SetActive();
+	                TRequestStatus* status = &iStatus;
+	                User::RequestComplete( status, KErrNone );
+	                }
+	            else
+	                {
+	                SetActive();
+	                }
+#else
+	            SetActive();        
+#endif
+	            }
+	        }
+	        break;
+        
+	    case EReady:
+	        {
+	        DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EReady")));
+   		
+	        // use same image for generating smaller thumbnails
+	        if (IsLargeThumbnail(iThumbnailSize))
+	            {
+                /*DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EScaling")));
+                TRAPD(err, ScaleL());
+                if (err != KErrNone)
+                    ASSERT(0);// TODO handle errors   
+                iConvertStatus = EEncoding;
+                SetActive();*/ 
+   		    }
+   		
+	        if( iImageEncoder )
+	            {
+	            delete iImageEncoder;
+	            iImageEncoder = NULL;
+	            }
+        
+	        if( iBitmap )
+	            {
+	            iBitmap->Reset();
+	            delete iBitmap;
+	            iBitmap = NULL;
+	            }
+	        
+#ifdef DECODE_FROM_BUFFER    
+	        if(iSourceData) 
+	            {
+	            delete iSourceData;
+	            iSourceData = NULL;
+	            }
+#endif
+	        
+	        iConvertStatus = ENone;
+        
+#ifndef USE_BITMAPS_TNS
+	        WriteExifData(iThumbnailFileName, iResolutionSize);
+#else
+	        if(IsJPEG(iThumbnailSize))
+	            {
+	            TRAPD(err, WriteExifDataL(iThumbnailFileName, iThumbnailSize));
+	            }
+#endif
+            
+            iFileServer.SetModified(iThumbnailFileName, iSourceTime);
+            iThumbnailObserver.ThumbNailGenerationCompleted(KErrNone);
+            }
+	        break;
+        }
+	
+    DP0_IMAGIC(_L("CIETNGeneratorAO::RunL --"));
+    }
+
+TBool CIETNGeneratorAO::IsJPEG(const TSize& aResolution) const
+    {
+#ifdef USE_64X64_BITMAP_TN
+    return (aResolution.iWidth >= 512 || aResolution.iHeight >= 512);
+#else
+    return (aResolution.iWidth >= 128 || aResolution.iHeight >= 128);    
+#endif
+    }
+
+TBool CIETNGeneratorAO::IsLargeThumbnail(const TSize& aResolution) const
+    {
+    return (aResolution.iHeight >= 512);
+    }
+
+void CIETNGeneratorAO::ScaleL()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::Scale++")));
+   
+    if ( iImageDecoder )
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;
+        }
+    
+    if (iBitmapScaler )
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;
+        }
+   
+    iBitmapScaler = CBitmapScaler::NewL();
+    iBitmapScaler->UseLowMemoryAlgorithm(ETrue);
+   
+    TSize tgtBitmapize;
+   
+    // If we want to create high resolution thumbnail, we use 512x512 resolution
+    // for low resolution TN we use size set in iResolutionSize
+    if(IsLargeThumbnail(iThumbnailSize))
+        {
+        tgtBitmapize.iWidth = 512;
+        tgtBitmapize.iHeight = 512;
+       
+        if(iSourceSize.iWidth > iSourceSize.iHeight)
+            {
+            // If we have wide panorama, use higher resolution to width
+            if((iSourceSize.iWidth / iSourceSize.iHeight) > 1.6)
+                tgtBitmapize.iWidth = 1024;
+            }
+        else
+            {
+            // If we have wide panorama, use higher resolution to height
+            if((iSourceSize.iHeight / iSourceSize.iWidth) > 1.6)
+                tgtBitmapize.iHeight = 1024;
+            }
+        }
+    else
+        {
+        tgtBitmapize = iThumbnailSize;
+        }
+   
+    // Use max quality
+    iBitmapScaler->SetQualityAlgorithm(CBitmapScaler::EMaximumQuality);
+    //iBitmapScaler->SetQualityAlgorithm(CBitmapScaler::EMediumQuality);
+    //iBitmapScaler->SetQualityAlgorithm(CBitmapScaler::EMinimumQuality);
+   
+    DP2_IMAGIC(_L("CIETNGeneratorAO::Scale to %dx%d"), tgtBitmapize.iWidth, tgtBitmapize.iHeight);
+      
+    iBitmapScaler->Scale(&iStatus, *iBitmap, tgtBitmapize, EFalse);
+       
+    DP0_IMAGIC((_L("CIETNGeneratorAO::Scale--")));
+    }
+
+void CIETNGeneratorAO::EncodeL()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::Encode++")));
+   
+    if (iImageDecoder )
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;
+        }
+    if( iBitmapScaler )
+        {
+        delete iBitmapScaler;
+        iBitmapScaler = NULL;
+        }
+    if( iImageEncoder )
+        {
+        delete iImageEncoder;
+        iImageEncoder = NULL;
+        }
+
+    TParse parser;
+    parser.Set(iThumbnailFileName, NULL, NULL );
+    TFileName tnPath = parser.DriveAndPath();
+    CIEEngineUtils::CreateTNFolder(iFileServer, tnPath);
+      
+#ifdef USE_BITMAPS_TNS
+    // Save Bitmap thumbnails if resolution is 128x128 or smaller
+    if(!IsJPEG(iThumbnailSize))
+        {
+        iBitmap->Save(iThumbnailFileName);
+        }
+    else //if bigger than then save jpg thumbnails
+#endif
+        {
+#if 0
+        //If we had 512x512 resolution bitmap we make copy of it
+        if(iBitmap->SizeInPixels().iWidth == 512 && iBitmap->SizeInPixels().iHeight == 512)
+            {
+            i512x512TnBitmap->Reset();
+            TInt error = i512x512TnBitmap->Create(iBitmap->SizeInPixels(), EColor16M);
+            
+            TUint8* dstData = (TUint8 *)i512x512TnBitmap->DataAddress();
+            TUint8* srcData = (TUint8 *)iBitmap->DataAddress();
+            TInt dataSize = iBitmap->SizeInPixels().iWidth * iBitmap->SizeInPixels().iHeight;
+            dataSize*=3;
+            
+            //Copy bitmap
+            for(TInt i=0; i<dataSize; i++)
+                {
+                dstData[i] = srcData[i];
+                }
+            }
+#endif       
+        
+        SetJpegImageDataL();
+        DP1_IMAGIC(_L("CIETNGeneratorAO::Encode - iThumbnailFileName: %S"), &iThumbnailFileName);
+        iMimeString = KMimeJpeg;
+        iImageEncoder = CImageEncoder::FileNewL( iFileServer, iThumbnailFileName, iMimeString );
+        iImageEncoder->Convert(&iStatus, *iBitmap, iFrameImageData);
+        }
+   
+    TEntry entry;
+    User::LeaveIfError(iFileServer.Entry(iThumbnailFileName, entry));
+    // Remember the modified time of the source file
+    iSourceTime = entry.iModified;
+   
+    DP0_IMAGIC((_L("CIETNGeneratorAO::Encode--")));
+    }
+
+void CIETNGeneratorAO::DecodeL()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::Decode++")));
+    
+    if(iImageDecoder)
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;   
+        }
+    
+    DP1_IMAGIC((_L("CIETNGeneratorAO::Decode - Creating decoder... with filename: %S")),&iSourceFileName);
+#ifdef USE_EXT_JPEG_DEC
+    iImageDecoder = CExtJpegDecoder::FileNewL(iFileServer, iSourceFileName);
+#else
+    
+#ifdef DECODE_FROM_BUFFER    
+    if(iSourceData) {
+        delete iSourceData;
+        iSourceData = NULL;
+    }
+    
+    RFile jpgFile;
+    TInt fileSize;
+    
+    User::LeaveIfError(jpgFile.Open(iFileServer, iSourceFileName, EFileRead));
+    jpgFile.Size(fileSize);
+    iSourceData = HBufC8::NewL(fileSize);
+    
+    TPtr8 buffer = iSourceData->Des();
+    
+    jpgFile.Read(buffer, fileSize);
+    
+    jpgFile.Close();
+    
+    iImageDecoder = CImageDecoder::DataNewL(
+            iFileServer, 
+            *iSourceData, 
+            CImageDecoder::EOptionNone, 
+            KNullUid, 
+            KNullUid, 
+            decoderUid);
+    
+    
+#else    
+    iImageDecoder = CImageDecoder::FileNewL(
+                                        iFileServer, 
+                                        iSourceFileName, 
+                                        CImageDecoder::EOptionNone, 
+                                        KNullUid, 
+                                        KNullUid, 
+                                        decoderUid);
+#endif
+
+#endif
+    
+    
+    iMimeString = KMimeJpeg;
+#ifdef DECODE_FROM_BUFFER
+    CImageDecoder::GetMimeTypeDataL( *iSourceData, iMimeString );    
+#else
+    CImageDecoder::GetMimeTypeFileL( iFileServer, iSourceFileName, iMimeString );
+#endif
+    
+    iSourceSize = iImageDecoder->FrameInfo().iOverallSizeInPixels;
+    
+    DP2_IMAGIC((_L("CIETNGeneratorAO::Decode - image %dx%d")), iSourceSize.iWidth, iSourceSize.iHeight );
+        
+    iBitmap = new (ELeave) CFbsBitmap();
+    
+    TargetDecodingSize(iThumbnailSize, iSourceSize);
+   
+#ifdef DO_NOT_USE_SCALING
+    if(IsLargeThumbnail(iThumbnailSize))
+        {
+        iSourceSize.iHeight=512;
+        iSourceSize.iWidth=512;
+        }
+#endif
+  
+    TInt error = iBitmap->Create(iSourceSize, EColor16M);
+    
+    iImageDecoder->Convert(&iStatus, *iBitmap, 0);
+    
+    DP0_IMAGIC((_L("CIETNGeneratorAO::Decode - convert bitmap... OK")));
+    DP0_IMAGIC((_L("CIETNGeneratorAO::Decode--")));
+    }
+
+void CIETNGeneratorAO::TargetDecodingSize(const TSize aTgtSize, TSize& aSrcSize)
+    {
+    DP0_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize++"));
+    
+    DP2_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize - Tgt %dx%d"),aTgtSize.iHeight, aTgtSize.iWidth);
+    DP2_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize - Src %dx%d"),aSrcSize.iHeight, aSrcSize.iWidth);
+    
+    // up to 32 times downscale in scaler
+    for (TInt i = 0;i < 5;i++)
+        {
+        if (aSrcSize.iWidth < aTgtSize.iWidth * 2 ||
+            aSrcSize.iHeight < aTgtSize.iHeight * 2) 
+            {
+            break;
+            }
+            
+            aSrcSize.iWidth >>= 1;
+            aSrcSize.iHeight >>= 1;
+        }
+    
+    // Check that we do not create odd resolution size thumbnail
+    if(aSrcSize.iHeight & 1)
+        aSrcSize.iHeight++;
+    if(aSrcSize.iWidth & 1)
+        aSrcSize.iWidth++;
+    
+    DP2_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize - New Src %dx%d"), aSrcSize.iHeight, aSrcSize.iWidth);
+    DP0_IMAGIC((_L("CIETNGeneratorAO::TargetDecodingSize--")));
+    }
+
+void CIETNGeneratorAO::WriteExifDataL(const TDes &aFilename, TSize aSize)
+     {
+     DP0_IMAGIC(_L("CIETNGeneratorAO::WriteExifData++"));
+     
+     // 1. Read JPEG image from the file to a buffer...
+     RFile file;
+     User::LeaveIfError( file.Open( iFileServer, aFilename, EFileWrite ) );
+     CleanupClosePushL( file );
+     TInt size = 0;
+     file.Size(size);
+     HBufC8* jpegImage = HBufC8::NewL( size );
+     CleanupStack::PushL( jpegImage );
+     TPtr8 bufferDes( jpegImage->Des() );
+     User::LeaveIfError( file.Read( bufferDes ) );
+     CleanupStack::Pop( jpegImage );
+     CleanupStack::PopAndDestroy();
+     CleanupStack::PushL( jpegImage );
+     
+     file.Close();
+     
+     // 2. Instantiate Exif modifier in ECreate mode...
+     CExifModify* modify = CExifModify::NewL( jpegImage->Des(), CExifModify::ECreate );
+     CleanupStack::PushL( modify );
+     
+     // 3. Insert (Set) at least the mandatory Exif data...
+     modify->SetXResolutionL( aSize.iWidth, 1 ); 
+     modify->SetYResolutionL( aSize.iHeight, 1 ); 
+     modify->SetResolutionUnitL( 2 );
+     modify->SetYCbCrPositioningL( 1 );
+     modify->SetComponentsConfigurationL( 1, 2, 3, 0 );
+     modify->SetColorSpaceL( 1 );
+     modify->SetPixelXDimensionL( aSize.iWidth );
+     modify->SetPixelYDimensionL( aSize.iHeight );
+     
+     // 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( jpegImage->Des() );
+     TPtr8 tmp = newExif->Des();
+     
+     User::LeaveIfError( file.Replace( iFileServer, aFilename, EFileWrite ) );
+     //Write Exif and jpeg image back to jpeg file
+     User::LeaveIfError(file.Write(*newExif));
+     
+     /* Process the new Exif data */
+     delete newExif;
+     newExif = NULL;
+     
+     // 5. Delete the modifier instance...
+     CleanupStack::PopAndDestroy( modify );
+     CleanupStack::PopAndDestroy( jpegImage );
+     
+     file.Close();
+     
+     DP0_IMAGIC(_L("CIETNGeneratorAO::WriteExifData--"));
+     }
+
+
+//Set JPEG image quality for encoding
+void CIETNGeneratorAO::SetJpegImageDataL()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::SetJpegImageDataL++")));
+    
+    TJpegImageData* jpegImageData;
+    jpegImageData = new (ELeave) TJpegImageData;
+    jpegImageData->iSampleScheme = TJpegImageData::EColor420;
+    jpegImageData->iQualityFactor = 80;
+    
+    if (iFrameImageData)
+        {
+        delete iFrameImageData;
+        iFrameImageData = NULL;
+        }
+    
+    iFrameImageData = CFrameImageData::NewL();
+    
+    //Ownership of jpegImageData lies with CFrameImageData
+    User::LeaveIfError(iFrameImageData->AppendImageData(jpegImageData));
+    
+    DP0_IMAGIC((_L("CIETNGeneratorAO::SetJpegImageDataL--")));
+    }
+
+void CIETNGeneratorAO::DoCancel()
+    {	
+    }
+
+TInt CIETNGeneratorAO::RunError(TInt /*aError*/)
+    {
+	return KErrNone;
+    }
+ 
+/* Set Image arrary received from Client.*/ 
+void CIETNGeneratorAO::SetImageArray(RArray<CImageData*> aImageArray)
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::SetImageArray ++")));
+    
+    iImageArray = aImageArray;
+    
+    DP0_IMAGIC((_L("CIETNGeneratorAO::SetImageArray --")));
+    }
+ 
+void CIETNGeneratorAO::CreateThumbnailL(
+        const TDes& aSourceFile, 
+        const TDes& aThumbnailFile, 
+        const TSize &aSize)
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL ++")));
+
+	iSourceFileName.Copy(aSourceFile);
+	iThumbnailFileName.Copy(aThumbnailFile);
+	iThumbnailSize = aSize;
+ 
+ 	iConvertStatus = EDecoding;
+ 	if(!IsActive())
+ 	    {
+ 	    SetActive();
+ 	    TRequestStatus* status = &iStatus;
+ 	    User::RequestComplete( status, KErrNone );
+ 	    }
+ 	
+ 	DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL --")));
+    }
+	
+
+void CIETNGeneratorAO::CreateThumbnailL(
+        const TDes& aSourceFile, 
+        const TDes& aThumbnailFile, 
+        const TSize &aSize,
+        CFbsBitmap* /*a512x512TnBitmap*/)
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL ++")));
+
+    iSourceFileName.Copy(aSourceFile);
+    iThumbnailFileName.Copy(aThumbnailFile);
+    iThumbnailSize = aSize;
+ 
+    iConvertStatus = EDecoding;
+    if(!IsActive())
+        {
+        SetActive();
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        }
+    
+    DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL --")));
+    }
+
+void CIETNGeneratorAO::CancelOutStaningRequests()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::CancelOutStaningRequests ++")));
+    
+    if(iError != KErrNone)
+        {
+        if(BaflUtils::FileExists(iFileServer, iThumbnailFileName))
+            {
+            TInt err = BaflUtils::DeleteFile(iFileServer, iThumbnailFileName);
+            DP2_IMAGIC(_L("CIETNGeneratorAO::CancelOutStaningRequests - DeleteCorruptedThumbNailFile - file found: %S, err:%d"), &iThumbnailFileName, err);
+            }
+        }
+        
+    DeleteObjects();
+    
+    DP0_IMAGIC((_L("CIETNGeneratorAO::CancelOutStaningRequests --")));
+    }
+ 
+void CIETNGeneratorAO::DeleteObjects()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::DeleteObjects ++")));
+	
+    if(iImageDecoder)
+		{
+		delete iImageDecoder;
+		iImageDecoder = NULL;	
+		}
+
+	if( iBitmapScaler )
+		{
+		delete iBitmapScaler;
+		iBitmapScaler = NULL;
+		}
+	
+	if( iBitmap )
+		{
+		delete iBitmap;
+		iBitmap = NULL;
+		}
+	
+	if( iImageEncoder )
+		{
+		delete iImageEncoder;
+		iImageEncoder = NULL;
+		}	
+	
+    if (iFrameImageData)
+        {
+        delete iFrameImageData;
+        iFrameImageData = NULL;
+        }
+	
+#ifdef DECODE_FROM_BUFFER    
+    if(iSourceData) 
+        {
+        delete iSourceData;
+        iSourceData = NULL;
+        }
+#endif
+    //delete i512x512TnBitmap;
+    
+	DP0_IMAGIC((_L("CIETNGeneratorAO::DeleteObjects --")));
+    }
+
+void CIETNGeneratorAO::CancelRequestsAndDeleteObjects()
+    {
+    DP0_IMAGIC((_L("CIETNGeneratorAO::CancelRequestsAndDeleteObjects ++")));
+    
+	CancelOutStaningRequests();
+	DeleteObjects();
+	
+	DP0_IMAGIC((_L("CIETNGeneratorAO::CancelRequestsAndDeleteObjects --")));
+    }
--- a/group/IEEngine.mmp	Thu Oct 14 12:11:19 2010 +0900
+++ b/group/IEEngine.mmp	Fri Oct 15 10:18:29 2010 +0900
@@ -82,8 +82,8 @@
 LIBRARY       	  efsrv.lib
 LIBRARY			  fbscli.lib
 LIBRARY			  imageconversion.lib
-//LIBRARY			  IclExtJpegApi.lib
-//LIBRARY			  exifutility.lib
+LIBRARY			  IclExtJpegApi.lib
+LIBRARY			  exifutility.lib
 LIBRARY			  jpegexifplugin.lib 
 LIBRARY				cone.lib 
 
--- a/group/IEUtils.mmp	Thu Oct 14 12:11:19 2010 +0900
+++ b/group/IEUtils.mmp	Fri Oct 15 10:18:29 2010 +0900
@@ -50,14 +50,11 @@
 LIBRARY       efsrv.lib
 LIBRARY			  fbscli.lib
 LIBRARY			  imageconversion.lib
-//LIBRARY			  IclExtJpegApi.lib
-//LIBRARY			  exifutility.lib
-//LIBRARY			  jpegexifplugin.lib 
+LIBRARY			  IclExtJpegApi.lib
+LIBRARY			  exifutility.lib
+LIBRARY			  jpegexifplugin.lib 
 LIBRARY				cone.lib 
 
-//STATICLIBRARY     idlimageprocessing.lib
-//LIBRARY         	libc.lib
-
 LIBRARY 			PlatformEnv.lib // platform environment, paths
 LIBRARY 			bitgdi.lib
 LIBRARY 			CommonEngine.lib