photosgallery/viewframework/tvout/src/glxhdmisurfaceupdater.cpp
branchRCL_3
changeset 15 191387a8b767
parent 14 2dac0fdba72b
child 19 420f6808bf21
--- a/photosgallery/viewframework/tvout/src/glxhdmisurfaceupdater.cpp	Wed Apr 14 15:57:24 2010 +0300
+++ b/photosgallery/viewframework/tvout/src/glxhdmisurfaceupdater.cpp	Tue Apr 27 16:37:53 2010 +0300
@@ -19,6 +19,7 @@
 #include <graphics/surfacemanager.h>
 #include <graphics/surfaceupdateclient.h>
 #include <e32math.h>
+#include <apgcli.h>
 
 #include <imageconversion.h> 
 #include <fbs.h>
@@ -29,27 +30,29 @@
 #include "glxactivecallback.h"
 #include "glxhdmisurfaceupdater.h"
 #include "glxactivedecoder.h"
+#include <bitdev.h> 
 
-// 720p image size
-const TInt KHdTvWidth = 1280;
-const TInt KHdTvHeight = 720;
 const TInt KMulFactorToCreateBitmap = 4;
 const TInt KZoomDelay = 10000;
 //100 , is decide for 20 steps of zooming , with each step being 5 pixels.
 const TInt KMaxZoomLimit = 100;
 //evey time we zoom , there is a increase in the ht amd width by 10 pixels.
 const TInt KSingleStepForZoom = 10;
+
+_LIT(KMimeJpeg,"image/jpeg");
+_LIT(KMimeJpg,"image/jpg");
+
 // -----------------------------------------------------------------------------
 // NewLC
 // -----------------------------------------------------------------------------
 CGlxHdmiSurfaceUpdater* CGlxHdmiSurfaceUpdater::NewL(RWindow* aWindow, const TDesC& aImageFile, 
+                                                      CFbsBitmap* aFsBitmap, 
                                                       MGlxGenCallback* aCallBack)
     {
     TRACER("CGlxHdmiSurfaceUpdater* CGlxHdmiSurfaceUpdater::NewL()");
-    CGlxHdmiSurfaceUpdater* self = new (ELeave) CGlxHdmiSurfaceUpdater(aWindow, aImageFile,
-                                                                    aCallBack);
+    CGlxHdmiSurfaceUpdater* self = new (ELeave) CGlxHdmiSurfaceUpdater(aWindow, aCallBack);
     CleanupStack::PushL(self);
-    self->ConstructL();
+    self->ConstructL(aFsBitmap,aImageFile);
     CleanupStack::Pop(self);
     return self;
     }
@@ -106,39 +109,52 @@
     TRACER("void CGlxHdmiSurfaceUpdater::ReleaseContent()"); 
     if ( iGlxDecoderAO )
         {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -1");
         iGlxDecoderAO->Cancel();
         }
-    
-    if ( iDecodedBitmap )
+    if (iFsBitmap)
         {
-        delete iDecodedBitmap;
-        iDecodedBitmap= NULL;
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -2");
+        delete iFsBitmap;
+        iFsBitmap = NULL;
         }
-    
+    for (TInt i=0; i<=2 ; i++)
+        {
+        GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ReleaseContent() -3, %d", i);
+        delete iDecodedBitmap[i];
+        iDecodedBitmap[i]= NULL;
+        }
+    GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -4");
     if(iSurfBufferAO && iSurfBufferAO->IsActive())
         {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -5");
 		iSurfBufferAO->Cancel();
         }
-    
     if ( iImageDecoder )
         {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -6");
         delete iImageDecoder;
         iImageDecoder = NULL;    
         }
-    
     if (iSurfSessionConnected &&  iSurfManager)
         {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -7");
         iSurfUpdateSession.CancelAllUpdateNotifications();
         }
+    if (iImagePath)
+        {
+        delete iImagePath;
+        iImagePath = NULL;
+        }
     }
 
 // -----------------------------------------------------------------------------
 // CTor 
 // -----------------------------------------------------------------------------
-CGlxHdmiSurfaceUpdater::CGlxHdmiSurfaceUpdater(RWindow* aWindow, 
-                          const TDesC& aImageFile, MGlxGenCallback* aCallBack): 
-                          iWindow(aWindow), iImagePath(aImageFile), 
-                          iCallBack(aCallBack)
+CGlxHdmiSurfaceUpdater::CGlxHdmiSurfaceUpdater(RWindow* aWindow,
+                          MGlxGenCallback* aCallBack): 
+                          iWindow(aWindow), iCallBack(aCallBack), 
+                          iShwFsThumbnail(ETrue), iIsNonJpeg(EFalse)
     {
     TRACER("CGlxHdmiSurfaceUpdater::CGlxHdmiSurfaceUpdater()");
     // Implement nothing here
@@ -147,74 +163,105 @@
 // -----------------------------------------------------------------------------
 // ConstructL 
 // -----------------------------------------------------------------------------
-void CGlxHdmiSurfaceUpdater::ConstructL()
+void CGlxHdmiSurfaceUpdater::ConstructL(CFbsBitmap* aFsBitmap, const TDesC& aImageFile)
     {
     TRACER("CGlxHdmiSurfaceUpdater::ConstructL()");
+    // Initiate the HDMI by assigning the necessary values
+    InitiateHdmiL(aFsBitmap,aImageFile);
+    
     TInt error = iFsSession.Connect ();
     GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ConstructL() FsSession Connect error = %d", error);
     User::LeaveIfError(error);
-    
-    iBitmapReady = EFalse;
     iShiftToCloning = EFalse;
     // Create the active object
     iGlxDecoderAO = CGlxHdmiDecoderAO::NewL(this);
-    CreateImageDecoderL(iImagePath);
+
+    // Create the HDMI Decoder
+    CreateImageDecoderL();
+
+    // Create the Bitmap
     CreateBitmapL();
+
+    // Create the surface and AO for updating the surface
     TRAP_IGNORE(CreateHdmiL());
+
     if(iSurfManager)
-    	{
-		error = iSurfUpdateSession.Connect();
-		GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ConstructL() Surface update Session Connect error = %d", error);
-		User::LeaveIfError(error);
-		iSurfSessionConnected = ETrue;
-		
+        {
+        error = iSurfUpdateSession.Connect();
+        GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ConstructL() Surface update Session Connect error = %d", error);
+        User::LeaveIfError(error);
+        iSurfSessionConnected = ETrue;
+
+        ShowFsThumbnailL();
 #ifdef _DEBUG
-		iStartTime.HomeTime();
+        iStartTime.HomeTime();
 #endif
-		//start decoding the image    
-		iGlxDecoderAO->ConvertImageL(*iDecodedBitmap,iImageDecoder);    
-    	}
-    iLeftCornerForZoom.iX = 0; 
-    iLeftCornerForZoom.iY = 0;
+        //start decoding the image    
+        iGlxDecoderAO->ConvertImageL(*iDecodedBitmap[EJpgDecodedBitmapIndex],iImageDecoder);   
+        }
     iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
-    iZoom = ETrue;
     }
 
 // -----------------------------------------------------------------------------
 // UpdateNewImageL 
 // -----------------------------------------------------------------------------
-void CGlxHdmiSurfaceUpdater::UpdateNewImageL(const TDesC& aImageFile)
+void CGlxHdmiSurfaceUpdater::UpdateNewImageL(const TDesC& aImageFile,CFbsBitmap* aFsBitmap)
     {
     TRACER("CGlxHdmiSurfaceUpdater::UpdateNewImageL()");
-	//Cancel the zoom timers if any
-	if(iTimer->IsActive())
+    ReleaseContent();   
+    // Initiate the HDMI by assigning the necessary values
+    InitiateHdmiL(aFsBitmap,aImageFile);
+    //Cancel the zoom timers if any
+    if(iTimer->IsActive())
         {
-		GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::UpdateNewImageL() - Cancel Timer");
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::UpdateNewImageL() - Cancel Timer");
         iTimer->Cancel();
         }
-    
-	iBitmapReady = EFalse;
-	iLeftCornerForZoom.iX = 0; 
-	iLeftCornerForZoom.iY = 0;
-    ReleaseContent();   
-    CreateImageDecoderL(aImageFile);    
+
+    // Create the HDMI Decoder
+    CreateImageDecoderL();
+
+    // Create the Bitmap
     CreateBitmapL();
     if(iSurfManager)
-    	{
-    	CreateHdmiL(EFalse);
-    	}
+        {
+        // Create the surface and AO for updating the surface
+        CreateHdmiL(EFalse);
+        }
     else
-    	{
-    	TRAP_IGNORE(CreateHdmiL(ETrue));
-    	}
+        {
+        TRAP_IGNORE(CreateHdmiL(ETrue));
+        }
+
 #ifdef _DEBUG
     iStartTime.HomeTime();
 #endif
     if(iSurfManager)
-    	{
-		//start decoding the image
-		iGlxDecoderAO->ConvertImageL(*iDecodedBitmap,iImageDecoder);
-    	}
+        {
+        // Show FS Thumbnail
+        ShowFsThumbnailL();
+        //start decoding the image
+        iGlxDecoderAO->ConvertImageL(*iDecodedBitmap[EJpgDecodedBitmapIndex],iImageDecoder);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// InitiateHdmiL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::InitiateHdmiL(CFbsBitmap* aFsBitmap,const TDesC& aImageFile)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::InitiateHdmiL()");
+    iImagePath = aImageFile.Alloc();
+    iFsBitmap = new (ELeave) CFbsBitmap;
+    iFsBitmap->Duplicate(aFsBitmap->Handle());
+    iIsNonJpeg = EFalse;
+    iTvScreenSize = iWindow->Size();
+
+    iBitmapReady = EFalse;
+    iLeftCornerForZoom.iX = 0; 
+    iLeftCornerForZoom.iY = 0;
+
+    iZoom = ETrue;
     }
 
 // -----------------------------------------------------------------------------
@@ -245,7 +292,6 @@
 void CGlxHdmiSurfaceUpdater::CreateSurfaceL()
     {
     TRACER("CGlxHdmiSurfaceUpdater::CreateSurfaceL()");
-    TSize surfaceSize = iWindow->Size();   // create surface of the screen size, i.e 1280x720
     iSurfManager = new(ELeave) RSurfaceManager();
     TInt error = iSurfManager->Open();
     GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::CreateSurfaceL Open Surface manager error = %d", error);
@@ -253,10 +299,10 @@
     
     RSurfaceManager::TSurfaceCreationAttributesBuf attributes;
     attributes().iPixelFormat           = EUidPixelFormatARGB_8888;// EUidPixelFormatYUV_420Planar;
-    attributes().iSize                  = surfaceSize;
+    attributes().iSize                  = iTvScreenSize;
     
     attributes().iBuffers               = 1;
-    attributes().iStride                = surfaceSize.iWidth * KMulFactorToCreateBitmap;  
+    attributes().iStride                = iTvScreenSize.iWidth * KMulFactorToCreateBitmap;  
     attributes().iAlignment             = KMulFactorToCreateBitmap;
     attributes().iContiguous            = EFalse;
     attributes().iMappable              = ETrue;
@@ -327,10 +373,9 @@
     {
     TRACER("CGlxHdmiSurfaceUpdater::Refresh()");
     // copy the decoded bitmap on to the surface
-    SwapBuffers();   
-    // Modify the surface position with respect to the buffer size 
-	ModifySurfacePostion();
-	// refresh the window
+    SwapBuffers();     
+
+    // refresh the window
     iCallBack->DoGenCallback();       
     }
 
@@ -342,69 +387,137 @@
 void CGlxHdmiSurfaceUpdater::SwapBuffers()
     {
     TRACER("CGlxHdmiSurfaceUpdater::SwapBuffers()"); 
-      
+    TInt bitmapIndex = KErrNotFound;
+    
+    if (iShwFsThumbnail) // show FS thumbnail
+        {
+        bitmapIndex = EFSBitmapIndex;
+        }
+    else if(iIsNonJpeg && !iShwFsThumbnail) // this indicates it is non jpeg image and decoding finished
+        {
+        bitmapIndex = ENonJpgDecodedBitmapIndex;
+        }
+    else                // if none of the above state means it is jpeg image and decoding finished
+        {
+        bitmapIndex = EJpgDecodedBitmapIndex;
+        }
+        
     // Lock the heap so that subsequent call to dataaddress doesnt happen
-    iDecodedBitmap->LockHeap();    
-    
+    iDecodedBitmap[bitmapIndex]->LockHeap();    
+
     // Data stride
-    TUint fs = iDecodedBitmap->DataStride();    
-    
+    TUint fs = iDecodedBitmap[bitmapIndex]->DataStride();    
+
     //Bitmap address from where the data has to be copied.
-    TUint8* from = (TUint8*)iDecodedBitmap->DataAddress();
-    
+    TUint8* from = (TUint8*)iDecodedBitmap[bitmapIndex]->DataAddress();
+
     //surface chunk address to where the bitmap data has to be copied.
     TUint8* to = (TUint8*)iSurfBuffer;    
-    
+
     // To buffer (32 bit colors)
     TUint ts = iSurfaceStride;
     //No of bytes to be copied on to the surface.
-    TUint bytes = iDecodedBitmap->SizeInPixels().iWidth * KMulFactorToCreateBitmap;
-    
+    TUint bytes = iDecodedBitmap[bitmapIndex]->SizeInPixels().iWidth * KMulFactorToCreateBitmap;
+
     GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::SwapBuffers() - decodeSize width = %d and height %d",
-            iDecodedBitmap->SizeInPixels().iWidth, iDecodedBitmap->SizeInPixels().iHeight );
-    
+            iDecodedBitmap[bitmapIndex]->SizeInPixels().iWidth, 
+            iDecodedBitmap[bitmapIndex]->SizeInPixels().iHeight );
+
     // Copy the bitmap on to the surface.
-    for (TInt y = iDecodedBitmap->SizeInPixels().iHeight; y >0; y--)
+    for (TInt y = iDecodedBitmap[bitmapIndex]->SizeInPixels().iHeight; y >0; y--)
         {
         Mem::Copy(to, from, bytes);        
         to += ts;        
         from += fs;        
         }            
-    iDecodedBitmap->UnlockHeap();
+    iDecodedBitmap[bitmapIndex]->UnlockHeap();
     }
 
 // -----------------------------------------------------------------------------
-// StartImageDecodeL 
+// CreateBitmapL 
 // -----------------------------------------------------------------------------
 void CGlxHdmiSurfaceUpdater::CreateBitmapL()
     {
-    TRACER("CGlxHdmiSurfaceUpdater::StartImageDecodeL()");
-    TSize scrnSize = iWindow->Size();
-    TSize targetBitmapSize;
+    TRACER("CGlxHdmiSurfaceUpdater::CreateBitmapL()");
     TSize imageSize = iImageDecoder->FrameInfo().iOverallSizeInPixels;
-    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - bitmapsize=%d, %d",imageSize.iWidth,imageSize.iHeight);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - bitmapsize=%d, %d",
+            imageSize.iWidth,imageSize.iHeight);
     TReal32 scaleFactor = 0.0f;
-    if (scrnSize.iWidth * imageSize.iHeight > scrnSize.iHeight
+    if (iTvScreenSize.iWidth * imageSize.iHeight > iTvScreenSize.iHeight
             * imageSize.iWidth)
         {
-        scaleFactor = (TReal32) scrnSize.iHeight
+        scaleFactor = (TReal32) iTvScreenSize.iHeight
                 / (TReal32) imageSize.iHeight;
         }
     else
         {
-        scaleFactor = (TReal32) scrnSize.iWidth
+        scaleFactor = (TReal32) iTvScreenSize.iWidth
                 / (TReal32) imageSize.iWidth;
         }
     GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - scaleFactor=%f",scaleFactor);
-    targetBitmapSize.iHeight = imageSize.iHeight * scaleFactor;
-    targetBitmapSize.iWidth = imageSize.iWidth * scaleFactor;
-
-    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - targetBitmapSize=%d, %d",targetBitmapSize.iWidth,targetBitmapSize.iHeight);
+    iTargetBitmapSize.iHeight = imageSize.iHeight * scaleFactor;
+    iTargetBitmapSize.iWidth = imageSize.iWidth * scaleFactor;
+	GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - targetBitmapSize=%d, %d",
+	        iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
     //create the bitmap for the required size
-    iDecodedBitmap = new (ELeave) CFbsBitmap();
+    iDecodedBitmap[EJpgDecodedBitmapIndex] = new (ELeave) CFbsBitmap();
+    // to check if the Mimetype is supported by the decoder to to arbitary scaling
+    // if not then we recalculate the size
+    TInt err = iDecodedBitmap[EJpgDecodedBitmapIndex]->Create(ReCalculateSizeL(), EColor16MU);
+    User::LeaveIfNull(iDecodedBitmap[EJpgDecodedBitmapIndex]);
+    }
 
-    TInt err = iDecodedBitmap->Create(targetBitmapSize, EColor16MU);
-    User::LeaveIfNull(iDecodedBitmap);
+// -----------------------------------------------------------------------------
+// DoesMimeTypeNeedsRecalculateL()
+// -----------------------------------------------------------------------------
+//
+TBool CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL");
+    RApaLsSession session;
+    TDataType mimeType;
+    TUid uid;
+    
+    User::LeaveIfError( session.Connect() );
+    CleanupClosePushL( session );
+    User::LeaveIfError( session.AppForDocument( iImagePath->Des(), uid, mimeType ) );
+    CleanupStack::PopAndDestroy(&session);
+    
+    if (mimeType.Des().Compare(KMimeJpeg)==0 ||
+            mimeType.Des().Compare(KMimeJpg)==0)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL - jpeg");
+        return EFalse;
+        }
+    else
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL - non jpeg");
+        return ETrue; 
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// ReCalculateSize 
+// -----------------------------------------------------------------------------
+TSize CGlxHdmiSurfaceUpdater::ReCalculateSizeL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ReCalculateSizeL()");
+    if(DoesMimeTypeNeedsRecalculateL())
+        {
+        iIsNonJpeg = ETrue;
+        TSize fullFrameSize = iImageDecoder->FrameInfo().iOverallSizeInPixels;
+        // calculate the reduction factor on what size we need
+        TInt reductionFactor = iImageDecoder->ReductionFactor(fullFrameSize, iTargetBitmapSize);
+        // get the reduced size onto destination size
+        TSize destSize;
+        User::LeaveIfError(iImageDecoder->ReducedSize(fullFrameSize, reductionFactor, destSize));
+        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ReCalculateSizeL() - destSize=%d, %d",destSize.iWidth,destSize.iHeight);
+        return destSize;
+        }
+    else
+        {
+        return iTargetBitmapSize;
+        }
     }
 
 // -----------------------------------------------------------------------------
@@ -426,16 +539,13 @@
         }
     else if(iSurfManager)
         {        
-        iZoomRectSz = iDecodedBitmap->SizeInPixels();
-        if (iSurfBufferAO->iStatus != KRequestPending
-                && !iSurfBufferAO->IsActive())
+        iShwFsThumbnail = EFalse;
+        if (iIsNonJpeg)
             {
-            Refresh();
-            iSurfBufferAO->iStatus = KRequestPending;
-            iSurfBufferAO->SetActive();
-            iSurfUpdateSession.NotifyWhenAvailable(iSurfBufferAO->iStatus);
-            TInt err = iSurfUpdateSession.SubmitUpdate(1, iSurfId, 0, NULL);
+            // if this is non jpeg image, make sure we scale the bitmap
+            ScaleDecodedBitmapL(ENonJpgDecodedBitmapIndex);
             }
+        ProcessTvImage();
 		iBitmapReady = ETrue;
         }
 	//release imagedecoder after the conversion is over		
@@ -449,15 +559,14 @@
 // -----------------------------------------------------------------------------
 // CreateImageDecoderL 
 // -----------------------------------------------------------------------------
-void CGlxHdmiSurfaceUpdater::CreateImageDecoderL(const TDesC& aImageFile)
+void CGlxHdmiSurfaceUpdater::CreateImageDecoderL()
     {
     TRACER("CGlxHdmiController::CreateImageDecoderL()");
      // Create a decoder for the image in the named file
     TRAPD(error,iImageDecoder = CImageDecoder::FileNewL(iFsSession, 
-            aImageFile, CImageDecoder::EOptionNone, KNullUid));
+            iImagePath->Des(), CImageDecoder::EOptionNone, KNullUid));
     GLX_LOG_INFO1("CreateImageDecoderL CImageDecoder:FileNewL error %d",error);
     User::LeaveIfError(error);
-    
     }
 
 // -----------------------------------------------------------------------------
@@ -543,18 +652,18 @@
         }    
     if(aZoom && iZoom)
         {
-        iZoomRectSz.iWidth = TInt(iZoomRectSz.iWidth-KSingleStepForZoom);
-        iZoomRectSz.iHeight = TInt(iZoomRectSz.iHeight-KSingleStepForZoom);
+        iTargetBitmapSize.iWidth = TInt(iTargetBitmapSize.iWidth-KSingleStepForZoom);
+        iTargetBitmapSize.iHeight = TInt(iTargetBitmapSize.iHeight-KSingleStepForZoom);
         iLeftCornerForZoom.iX =iLeftCornerForZoom.iX+KSingleStepForZoom/2;
         iLeftCornerForZoom.iY =iLeftCornerForZoom.iY+KSingleStepForZoom/2;           
-        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::Zoom()--- 2,iZoomRectSz.iWidth = %d, iZoomRectSz.iHeight = %d", iZoomRectSz.iWidth,iZoomRectSz.iHeight);
+        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::Zoom()--- 2,iTargetBitmapSize.iWidth = %d, iTargetBitmapSize.iHeight = %d", iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
         iConfig.SetViewport(TRect(iLeftCornerForZoom.iX,iLeftCornerForZoom.iY,
-                iZoomRectSz.iWidth,iZoomRectSz.iHeight));
+                iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight));
         }
     else
         {
-        iZoomRectSz.iWidth = TInt(iZoomRectSz.iWidth+KSingleStepForZoom);
-        iZoomRectSz.iHeight = TInt(iZoomRectSz.iHeight+KSingleStepForZoom);
+        iTargetBitmapSize.iWidth = TInt(iTargetBitmapSize.iWidth+KSingleStepForZoom);
+        iTargetBitmapSize.iHeight = TInt(iTargetBitmapSize.iHeight+KSingleStepForZoom);
         iLeftCornerForZoom.iX =iLeftCornerForZoom.iX-KSingleStepForZoom/2;
         iLeftCornerForZoom.iY =iLeftCornerForZoom.iY-KSingleStepForZoom/2; 
         if(iLeftCornerForZoom.iX == 0)
@@ -562,9 +671,9 @@
             iTimer->Cancel();
             iZoom = ETrue;
             }
-        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::Zoom()--- 4,iZoomRectSz.iWidth = %d, iZoomRectSz.iHeight = %d", iZoomRectSz.iWidth,iZoomRectSz.iHeight);
+        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::Zoom()--- 4,iTargetBitmapSize.iWidth = %d, iTargetBitmapSize.iHeight = %d", iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
         iConfig.SetViewport(TRect(iLeftCornerForZoom.iX,iLeftCornerForZoom.iY,
-                iZoomRectSz.iWidth,iZoomRectSz.iHeight));
+                iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight));
         }
     iWindow->SetBackgroundSurface(iConfig, ETrue);   
     }
@@ -575,24 +684,26 @@
 void CGlxHdmiSurfaceUpdater::ModifySurfacePostion()
 	{
 	TRACER("CGlxHdmiSurfaceUpdater::ModifySurfacePostion()");
-	TSize bitmapSize = iDecodedBitmap->SizeInPixels();
 	TPoint startPoint(0,0);
-	if (bitmapSize.iWidth <KHdTvWidth)
+	if (iTargetBitmapSize.iWidth <iTvScreenSize.iWidth)
 	    {
-	    startPoint.iX = (KHdTvWidth - bitmapSize.iWidth)/2; 
+	    startPoint.iX = (iTvScreenSize.iWidth - iTargetBitmapSize.iWidth)/2; 
 	    }
-	if (bitmapSize.iHeight <KHdTvHeight)
+	if (iTargetBitmapSize.iHeight <iTvScreenSize.iHeight)
 	    {
-	    startPoint.iY = (KHdTvHeight - bitmapSize.iHeight)/2;
+	    startPoint.iY = (iTvScreenSize.iHeight - iTargetBitmapSize.iHeight)/2;
 	    }
-    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - target bitmapsize=%d, %d",bitmapSize.iWidth,bitmapSize.iHeight);
-    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - startPoint =%d, %d",startPoint.iX,startPoint.iY);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - target iTargetBitmapSize=%d, %d",
+            iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - startPoint =%d, %d",
+            startPoint.iX,startPoint.iY);
 
     // target
-    iConfig.SetExtent(TRect(startPoint.iX,startPoint.iY,(KHdTvWidth-startPoint.iX),
-            (KHdTvHeight-startPoint.iY)));
+    iConfig.SetExtent(TRect(startPoint.iX,startPoint.iY,(iTvScreenSize.iWidth-startPoint.iX),
+            (iTvScreenSize.iHeight-startPoint.iY)));
     // source
-    iConfig.SetViewport(TRect(TPoint(0,0),TSize(bitmapSize.iWidth,bitmapSize.iHeight)));
+    iConfig.SetViewport(TRect(TPoint(0,0),TSize(iTargetBitmapSize.iWidth,
+            iTargetBitmapSize.iHeight)));
 #ifdef _DEBUG
     TRect ex, vp;
     iConfig.GetExtent(ex);
@@ -602,7 +713,6 @@
     GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - ex - TL=%d, %d",ex.iTl.iX,ex.iTl.iY);
     GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - ex - BR=%d, %d",ex.iBr.iX,ex.iBr.iY);
 #endif
-    iWindow->SetBackgroundSurface(iConfig, ETrue);   
     }
 
 // -----------------------------------------------------------------------------
@@ -635,3 +745,86 @@
 		iShiftToCloning = EFalse;
 		}
 	}
+
+// -----------------------------------------------------------------------------
+// ShowFsThumbnailL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ShowFsThumbnailL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ShowFsThumbnailL()");
+    iShwFsThumbnail = ETrue;
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ShowFsThumbnailL() iTargetBitmapSize Width=%d, Height=%d",
+            iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+    // Modify the surface position with respect to the buffer size 
+    ModifySurfacePostion();
+    // this is for FS thumbnail stored in array pointer 0
+    ScaleDecodedBitmapL(EFSBitmapIndex);
+    // Process the Image to TV
+    ProcessTvImage();
+    // set the surface onto background
+    iWindow->SetBackgroundSurface(iConfig, ETrue); 
+    }
+
+// -----------------------------------------------------------------------------
+// ScaleDecodedBitmapL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL(TInt aBitmapIndex)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL()");
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL() iTargetBitmapSize Width=%d, Height=%d",
+            iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+
+    if (iDecodedBitmap[aBitmapIndex])
+        {
+        delete iDecodedBitmap[aBitmapIndex];
+        iDecodedBitmap[aBitmapIndex] = NULL;
+        }
+    iDecodedBitmap[aBitmapIndex] = new (ELeave) CFbsBitmap();
+    // create destination with size
+    TInt err = iDecodedBitmap[aBitmapIndex]->Create(iTargetBitmapSize, EColor16MU);
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL() creating bitmap error, err=%d",err);
+    User::LeaveIfNull(iDecodedBitmap[aBitmapIndex]);
+
+    // Create bitmap device for destination bitmap
+    CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(iDecodedBitmap[aBitmapIndex]);
+    CleanupStack::PushL(bitmapDevice);
+    
+    CFbsBitGc* bitmapGc = CFbsBitGc::NewL();
+    CleanupStack::PushL(bitmapGc);
+    bitmapGc->Activate(bitmapDevice);
+    if (aBitmapIndex==EFSBitmapIndex)
+        {
+        // scale the source bitmap which is a FS bitmap
+        bitmapGc->DrawBitmap(TRect(iTargetBitmapSize), iFsBitmap);
+        }
+    else
+        {
+        // scale the source bitmap which is a decoded bitmap
+        bitmapGc->DrawBitmap(TRect(iTargetBitmapSize), iDecodedBitmap[EJpgDecodedBitmapIndex]);
+        }
+    
+    CleanupStack::PopAndDestroy(bitmapGc);
+    CleanupStack::PopAndDestroy(bitmapDevice);
+
+    }
+
+// -----------------------------------------------------------------------------
+// ProcessTvImage 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ProcessTvImage()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ProcessTvImage()");
+    if (iSurfBufferAO->iStatus != KRequestPending
+            && !iSurfBufferAO->IsActive())
+        {
+        Refresh();
+        iSurfBufferAO->iStatus = KRequestPending;
+        iSurfBufferAO->SetActive();
+        iSurfUpdateSession.NotifyWhenAvailable(iSurfBufferAO->iStatus);
+        TInt err = iSurfUpdateSession.SubmitUpdate(1, iSurfId, 0, NULL);
+        GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ProcessTvImage() Surfaceupdatesession error %d",err);
+        }
+    }
+
+
+