scrsaver/scrsaverplugins/SlideshowPlugin/src/SlideshowSlideLoader.cpp
branchRCL_3
changeset 26 e8d784ac1a4b
parent 0 040fcad49f44
equal deleted inserted replaced
25:aaeeca1f15af 26:e8d784ac1a4b
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Loads a slide from file
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //  INCLUDES
       
    21 #include "SlideshowPluginUtils.h"
       
    22 #include "SlideshowSlideLoader.h"
       
    23 
       
    24 // ---------------------------------------------------------------------------
       
    25 // DivAndRoundUp
       
    26 // ---------------------------------------------------------------------------
       
    27 //
       
    28 TInt DivAndRoundUp(const TInt aNumber, const TInt aDivider)
       
    29     {
       
    30     TInt result = aNumber / aDivider;
       
    31 
       
    32     if (aNumber % aDivider)
       
    33         {
       
    34         result += 1;
       
    35         }
       
    36     
       
    37     return result;
       
    38     }
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // CSlideshowSlideLoader::NewL
       
    42 // ---------------------------------------------------------------------------
       
    43 //
       
    44 CSlideshowSlideLoader* CSlideshowSlideLoader::NewL(CSlideshowSlide *aSlide)
       
    45 	{
       
    46 	CSlideshowSlideLoader * self = new (ELeave)CSlideshowSlideLoader(aSlide);
       
    47 	CleanupStack::PushL(self);
       
    48 	self->ConstructL();
       
    49 	CleanupStack::Pop(self);
       
    50 	return self;
       
    51 	}
       
    52 
       
    53 // ---------------------------------------------------------------------------
       
    54 // CSlideshowSlideLoader::ConstructL
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 void CSlideshowSlideLoader::ConstructL()
       
    58 	{
       
    59 	// Add this object to active scheduler
       
    60 	CActiveScheduler::Add(this);
       
    61 	}
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // CSlideshowSlideLoader::CSlideshowSlideLoader
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CSlideshowSlideLoader::CSlideshowSlideLoader(CSlideshowSlide *aSlide)
       
    68 	: CActive(CActive::EPriorityStandard),iSlide(aSlide)
       
    69 	{
       
    70 	// Empty
       
    71 	}
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // CSlideshowSlideLoader::~CSlideshowSlideLoader
       
    75 // ---------------------------------------------------------------------------
       
    76 //
       
    77 CSlideshowSlideLoader::~CSlideshowSlideLoader()
       
    78 	{
       
    79 	if(IsActive())
       
    80 		{
       
    81 		Cancel();
       
    82 		}
       
    83 	
       
    84 	}
       
    85 
       
    86 // ---------------------------------------------------------------------------
       
    87 // CSlideshowSlideLoader::DeleteDecoder
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 void CSlideshowSlideLoader::DeleteDecoder()
       
    91 	{
       
    92 	if(iDecoder)
       
    93 		{
       
    94 		delete iDecoder;
       
    95 		iDecoder = NULL;
       
    96 		}
       
    97 	
       
    98 	}
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // CSlideshowSlideLoader::DoCancel
       
   102 // ---------------------------------------------------------------------------
       
   103 //
       
   104 void CSlideshowSlideLoader::DoCancel()
       
   105 	{
       
   106 	iDecoder->Cancel();
       
   107 	DeleteDecoder();
       
   108 	// delete the image
       
   109 	if(iSlide->iImage)
       
   110 		{
       
   111 		delete iSlide->iImage;
       
   112 		iSlide->iImage = NULL;
       
   113 		}
       
   114 	}
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 // CSlideshowSlideLoader::RunL
       
   118 // ---------------------------------------------------------------------------
       
   119 //
       
   120 void CSlideshowSlideLoader::RunL()
       
   121 	{
       
   122 	// delete the decoder to save some memory.
       
   123 	DeleteDecoder();
       
   124 	if(iStatus != KErrNone)
       
   125 		{
       
   126 		iSlide->ReleaseImage();
       
   127 		// SSS_DECODEFAILED says that Image could not be decoded. Corrupted image.
       
   128 		(iSlide->iFlags) |= SSS_DECODEFAILED;
       
   129 		return;
       
   130 		}
       
   131 	
       
   132 	// Image loaded, size scaled down while loading. Find out, if the
       
   133     // image still needs to be scaled smaller to fit the screen
       
   134 	
       
   135     TReal aspectRatio = (TReal) iBitmapsize.iWidth / (TReal) iBitmapsize.iHeight;
       
   136 
       
   137     if ((iBitmapsize.iWidth <= iTargetSize.iWidth) &&
       
   138         (iBitmapsize.iHeight <= iTargetSize.iHeight))
       
   139         {
       
   140         // Fits completely - finish
       
   141         SSPLOGGER_WRITE("No resize needed");
       
   142         
       
   143         // Compress the heap after imageconversion as
       
   144         // imagedecoder seems to leave heap uncompressed
       
   145         User::Heap().Compress();
       
   146         (iSlide->iFlags) |= SSS_IMAGELOADED;
       
   147     	return;
       
   148         }
       
   149 
       
   150     // Figure out which dimension needs most scaling
       
   151     TReal xFactor = (TReal) iTargetSize.iWidth / (TReal) iBitmapsize.iWidth;
       
   152     TReal yFactor = (TReal) iTargetSize.iHeight / (TReal) iBitmapsize.iHeight;
       
   153 
       
   154     // Start with target (screen) size
       
   155     TSize finalSize = iTargetSize;
       
   156             
       
   157     if (xFactor <= yFactor)
       
   158         {
       
   159         // X-dimension needs most scaling - fit to x, re-calc y
       
   160         finalSize.iHeight = (TInt) ((TReal) finalSize.iWidth / aspectRatio);
       
   161         }
       
   162     else
       
   163         {
       
   164         // Y-dimension needs most scaling - fit to y, re-calc x
       
   165         finalSize.iWidth = (TInt) ((TReal) finalSize.iHeight * aspectRatio);
       
   166         }
       
   167 
       
   168     SSPLOGGER_WRITEF(_L("SSP: Final size (%d, %d)"),
       
   169                      finalSize.iWidth, finalSize.iHeight);
       
   170     
       
   171     // Create a final bitmap with the final size, and draw to it
       
   172     CFbsBitmap* finalBmp = new (ELeave) CFbsBitmap;
       
   173     CleanupStack::PushL(finalBmp);
       
   174     User::LeaveIfError(finalBmp->Create(finalSize, (iSlide->iImage)->DisplayMode()));
       
   175     
       
   176     CFbsBitmapDevice* bmpDev = CFbsBitmapDevice::NewL(finalBmp);
       
   177     CleanupStack::PushL(bmpDev);
       
   178     
       
   179     CFbsBitGc* bmpCxt;
       
   180     User::LeaveIfError(bmpDev->CreateContext(bmpCxt));
       
   181     CleanupStack::PushL(bmpCxt);
       
   182     bmpCxt->DrawBitmap(TRect(0, 0, finalSize.iWidth, finalSize.iHeight),
       
   183     					(iSlide->iImage),
       
   184     					TRect(0, 0, iBitmapsize.iWidth, iBitmapsize.iHeight));
       
   185     
       
   186     CleanupStack::PopAndDestroy(2); // bmpDev, bmpCxt
       
   187     // Return the result in the original bitmap parameter
       
   188     (iSlide->iImage)->Reset();
       
   189     
       
   190     User::LeaveIfError((iSlide->iImage)->Duplicate(finalBmp->Handle()));
       
   191     CleanupStack::PopAndDestroy(finalBmp);
       
   192     // Compress the heap after imageconversion as
       
   193     // imagedecoder seems to leave heap uncompressed
       
   194     User::Heap().Compress();
       
   195     (iSlide->iFlags) |= SSS_IMAGELOADED;
       
   196 	return;
       
   197 	}
       
   198 
       
   199 // ---------------------------------------------------------------------------
       
   200 // CSlideshowSlideLoader::LoadSlideL
       
   201 // ---------------------------------------------------------------------------
       
   202 //
       
   203 void CSlideshowSlideLoader::LoadSlideL(
       
   204     const TDesC& aFilename, const TSize& aTargetSize)
       
   205     {
       
   206    
       
   207     iTargetSize = aTargetSize;
       
   208     RFs filesys;
       
   209     User::LeaveIfError(filesys.Connect());
       
   210     CleanupClosePushL(filesys);
       
   211     // this line can leave if decoder is not found..need to cacth this.
       
   212     iDecoder = CImageDecoder::FileNewL(filesys, aFilename, ContentAccess::EView,CImageDecoder::EOptionAlwaysThread);
       
   213     if (aTargetSize == TSize(-1,-1))
       
   214         {
       
   215         CleanupStack::PopAndDestroy(&filesys); 
       
   216         iDecoder = NULL;
       
   217         return;
       
   218         }
       
   219 
       
   220     // Get image information
       
   221     TFrameInfo frameinfo = iDecoder->FrameInfo();
       
   222     TDisplayMode mode;
       
   223 
       
   224     // Tone down colors if possible (saves memory)
       
   225     if (frameinfo.iFlags & TFrameInfo::ECanDither)
       
   226         {
       
   227         mode = EColor64K;
       
   228         }
       
   229     else
       
   230         {
       
   231         mode = frameinfo.iFrameDisplayMode;
       
   232         }
       
   233     
       
   234     // Find out if the image can be downscaled during loading
       
   235     iBitmapsize = frameinfo.iOverallSizeInPixels;
       
   236 
       
   237       
       
   238     if ((iBitmapsize.iWidth  >= aTargetSize.iWidth * 2) &&
       
   239         (iBitmapsize.iHeight >= aTargetSize.iHeight * 2))
       
   240         {
       
   241         // 1/2 size
       
   242         iBitmapsize.iWidth = DivAndRoundUp(frameinfo.iOverallSizeInPixels.iWidth, 2);
       
   243         iBitmapsize.iHeight = DivAndRoundUp(frameinfo.iOverallSizeInPixels.iHeight, 2);
       
   244         
       
   245         if ((iBitmapsize.iWidth  >= aTargetSize.iWidth * 2) &&
       
   246             (iBitmapsize.iHeight >= aTargetSize.iHeight * 2))
       
   247             {
       
   248             // 1/4 size
       
   249             iBitmapsize.iWidth = DivAndRoundUp(frameinfo.iOverallSizeInPixels.iWidth, 4);
       
   250             iBitmapsize.iHeight = DivAndRoundUp(frameinfo.iOverallSizeInPixels.iHeight, 4);
       
   251             
       
   252             if ((iBitmapsize.iWidth  >= aTargetSize.iWidth * 2) &&
       
   253                 (iBitmapsize.iHeight >= aTargetSize.iHeight * 2))
       
   254                 {
       
   255                 // 1/8 size
       
   256                 iBitmapsize.iWidth = DivAndRoundUp(frameinfo.iOverallSizeInPixels.iWidth, 8);
       
   257                 iBitmapsize.iHeight = DivAndRoundUp(frameinfo.iOverallSizeInPixels.iHeight, 8);
       
   258                 }
       
   259             }
       
   260         }
       
   261 
       
   262     // Create a target bitmap
       
   263     iSlide->iImage = new (ELeave) CFbsBitmap;
       
   264     User::LeaveIfError((iSlide->iImage)->Create(iBitmapsize, mode));
       
   265     // for filesys
       
   266     CleanupStack::PopAndDestroy(&filesys);
       
   267     
       
   268     //Start decoding the image ...
       
   269     // RunL method is called when decoding is done.
       
   270     iDecoder->Convert(&iStatus, *(iSlide->iImage),0);  
       
   271     SetActive();
       
   272  }
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // CSlideshowSlideLoader::RunError
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 TInt CSlideshowSlideLoader::RunError(TInt aError)
       
   279 	{
       
   280 	if (NULL != iSlide->iImage)
       
   281 		{
       
   282 		delete iSlide->iImage;
       
   283 		iSlide->iImage = NULL;
       
   284 		}
       
   285 	return aError;
       
   286 	}