--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/thumbnailengine/TneAPISrc/HXTNEVideoClipInfoImp.cpp Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,747 @@
+/*
+* Copyright (c) 2006 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:
+*
+* Description: TNE Video Clip Implementation
+*
+*/
+
+
+
+
+#include "HXTNEVideoClipInfoImp.h"
+#include <e32base.h>
+
+
+#include <fbs.h>
+#include <coemain.h>
+#include <ecom/ecom.h>
+
+
+#include "yuv2rgb12.h"
+#include "yuv2rgb16.h"
+#include "yuv2rgb24.h"
+
+#include <flogger.h>
+
+// PRINT macro
+#ifdef _DEBUG
+#include <e32svr.h>
+#define PRINT(x) RDebug::Print x
+#else
+#define PRINT(x)
+#endif
+
+#ifdef _DEBUG
+#define ENABLE_S60_TNE_LOGGING 1
+#endif
+
+//implementation
+#ifdef ENABLE_S60_TNE_LOGGING
+#define FLOG FileLog
+inline static void FileLog(TRefByValue<const TDesC16> aFmt,...)
+{
+ VA_LIST args;
+ VA_START (args, aFmt);
+ RFileLogger::WriteFormat(_L("tne"), _L("S60tne.log"),
+ EFileLoggingModeAppend, aFmt, args);
+}
+
+#else // logging is disabled
+#define FLOG LogFNull
+inline static void LogFNull(TRefByValue<const TDesC16> aFmt,...){}
+
+#endif // enable logging
+
+//server details
+const TUint kDefaultMessageSlots=4;
+
+
+
+// -----------------------------------------------------------------------------
+// CTNEVideoClipInfo::NewL
+// API exposed by TNE to
+// TNEVideoClipInfo using RFile handle
+// -----------------------------------------------------------------------------
+EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewL(const RFile& aFileHandle,
+ MTNEVideoClipInfoObserver& aObserver)
+{
+ FLOG(_L("CTNEVideoClipInfo::NewL"));
+
+ CHXTNEVideoClipInfoImp* self = ( CHXTNEVideoClipInfoImp*)NewLC(aFileHandle, aObserver);
+
+
+ FLOG(_L("CTNEVideoClipInfo::NewL out"));
+ return self;
+}
+
+// -----------------------------------------------------------------------------
+// CTNEVideoClipInfo::NewL
+// API exposed by TNE to create TNEVideoClipInfo using file name
+// -----------------------------------------------------------------------------
+EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewL(const TDesC& aFileName,
+ MTNEVideoClipInfoObserver& aObserver)
+{
+ FLOG(_L("CTNEVideoClipInfo::NewL"));
+
+ CHXTNEVideoClipInfoImp* self = ( CHXTNEVideoClipInfoImp*)NewLC(aFileName, aObserver);
+
+
+ FLOG(_L("CTNEVideoClipInfo::NewL out"));
+ return self;
+}
+
+EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewLC(const RFile& aFileHandle,
+ MTNEVideoClipInfoObserver& aObserver)
+{
+
+ CHXTNEVideoClipInfoImp* self = new (ELeave) CHXTNEVideoClipInfoImp();
+ CleanupStack::PushL(self);
+ self->ConstructL(aFileHandle, aObserver);
+ CleanupStack::Pop();
+ return self;
+}
+
+
+EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewLC(const TDesC& aFileName,
+ MTNEVideoClipInfoObserver& aObserver)
+{
+
+ CHXTNEVideoClipInfoImp* self = new (ELeave) CHXTNEVideoClipInfoImp();
+ CleanupStack::PushL(self);
+ self->ConstructL(aFileName, aObserver);
+ CleanupStack::Pop();
+ return self;
+}
+
+
+
+
+CTNEVideoClipInfo* CHXTNEVideoClipInfoImp::NewL(const RFile& aFileHandle,
+ MTNEVideoClipInfoObserver& aObserver)
+{
+ CHXTNEVideoClipInfoImp* self = new (ELeave) CHXTNEVideoClipInfoImp();
+ CleanupStack::PushL(self);
+ self->ConstructL(aFileHandle, aObserver);
+ CleanupStack::Pop(self);
+ return self;
+}
+
+//constructor
+
+ CHXTNEVideoClipInfoImp::CHXTNEVideoClipInfoImp()
+ {
+ //empty constructor
+
+ }
+
+
+//destructor
+
+
+ CHXTNEVideoClipInfoImp::~CHXTNEVideoClipInfoImp()
+{
+ FLOG(_L("CTNEVideoClipInfo::~ CHXTNEVideoClipInfoImp in"));
+
+
+
+ RSessionBase::Close();
+ iServerThread.Close();
+
+ if (iServerName)
+ {
+ delete iServerName;
+ iServerName = NULL;
+ }
+ if (iObserver)
+ {
+ delete iObserver;
+ iObserver = NULL;
+ }
+
+ if (iCloseHandle)
+ {
+ iCloseHandle = EFalse;
+ iFileHandle.Close();
+ }
+
+ if (iOutBitmap)
+ {
+ delete iOutBitmap;
+ iOutBitmap = 0;
+ }
+
+
+ if(iFs)
+ {
+ iFs->Close();
+ delete iFs;
+ iFs = NULL;
+ }
+
+ if (iEnhancer)
+ {
+ delete iEnhancer;
+ iEnhancer = NULL;
+ }
+
+ FLOG(_L("CTNEVideoClipInfo::~ CHXTNEVideoClipInfoImp out"));
+}
+
+void CHXTNEVideoClipInfoImp::ConstructL(const RFile& aFileHandle,
+ MTNEVideoClipInfoObserver& aObserver)
+{
+ FLOG(_L("CTNEVideoClipInfo::ConstructL in this=%x"), this);
+ iObserver = CTNEClientObserver::NewL(this);
+ iClipInfoObserver = &aObserver;
+
+
+ User::LeaveIfError(CreateServer());
+ iFileHandle.Duplicate(aFileHandle);
+ iCloseHandle = ETrue;
+ User::LeaveIfError(OpenFile(iFileHandle, 0));
+
+ FLOG(_L("CTNEVideoClipInfo::ConstructL out this=%x"), this);
+
+ }
+
+void CHXTNEVideoClipInfoImp::ConstructL(const TDesC& aFileName,
+ MTNEVideoClipInfoObserver& aObserver)
+{
+ FLOG(_L("CTNEVideoClipInfo::ConstructL in this=%x"), this);
+ iObserver = CTNEClientObserver::NewL(this);
+ iClipInfoObserver = &aObserver;
+ iFileName.Copy(aFileName);
+
+ User::LeaveIfError(CreateServer());
+
+ User::LeaveIfError(OpenFile(0));
+
+
+ FLOG(_L("CTNEVideoClipInfo::ConstructL out this=%x"), this);
+}
+
+TInt CHXTNEVideoClipInfoImp::CreateServer()
+{
+ TInt err = KErrNoMemory;
+ FLOG(_L("CHXTNEVideoClipInfoImp::CreateServer in"));
+ TRAP(err,iServerName = HBufC::NewL(KMaxFileName));
+
+ if (iServerName && err == KErrNone)
+ {
+ TPtr ptr = iServerName->Des();
+ ptr.Copy(KTneServerName);
+ ptr.AppendNum(Math::Random(), EHex);
+
+ err = StartThread(iServerThread, iServerName);
+ }
+
+ if ( err == KErrNone)
+ {
+ //server name FIXME
+ err = CreateSession(*iServerName, Version(), kDefaultMessageSlots);
+ }
+
+ FLOG(_L("CHXTNEVideoClipInfoImp::CreateServer out err=%d"), err);
+ return(err);
+
+}
+
+TVersion CHXTNEVideoClipInfoImp::Version(void) const
+ {
+ return(TVersion(KTNEServMajorVersionNumber,KTNEServMinorVersionNumber,KTNEServBuildVersionNumber));
+ }
+
+
+//SendRecieve() commands to server
+
+TInt CHXTNEVideoClipInfoImp::OpenFile(const RFile& aFileHandle, TInt aPosition)
+
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile in"));
+ c_State = EStartGettingMetadata;
+ iObserver->Activate();
+ SendReceive(EOpenFileRFmsg,TIpcArgs(&aFileHandle,aPosition), iObserver->iStatus);
+ FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile out"));
+ return KErrNone;
+ }
+
+TInt CHXTNEVideoClipInfoImp::OpenFile(TInt aPosition)
+
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile in"));
+ c_State = EStartGettingMetadata;
+ iObserver->Activate();
+ SendReceive(EOpenFIleNamemsg,TIpcArgs(&iFileName,aPosition), iObserver->iStatus);
+ FLOG(_L("CHXTNEVideoClipInfoImp::OpenFile out"));
+ return KErrNone;
+ }
+
+void CHXTNEVideoClipInfoImp::GetThumbL(MTNEVideoClipThumbObserver& aObserver,
+ TInt aIndex,
+ TSize* const aResolution,
+ TDisplayMode aDisplayMode,
+ TBool aEnhance,
+ TInt aPriority)
+
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::GetThumbL in"));
+
+ iThumbObserver = &aObserver;
+ iThumbIndex = aIndex;
+ iThumbEnhance = aEnhance;
+ iThumbDisplayMode = aDisplayMode;
+ iPriority = aPriority;
+ iThumbRequestData.iIndex = aIndex;
+
+ if (aResolution)
+ {
+ iOutputThumbResolution = *aResolution;
+ }
+ else
+ {
+ iOutputThumbResolution.iHeight = iMetaData.iHeight;
+ iOutputThumbResolution.iWidth = iMetaData.iWidth;
+ }
+
+ iThumbRequestData.iYUVBuffer = NULL;
+ c_State = EStartGettingThumbNail;
+ iObserver->Activate();
+ SendReceive(EGetThumbmsg, TIpcArgs(&iThumbRequestData), iObserver->iStatus);
+ FLOG(_L("CHXTNEVideoClipInfoImp::GetThumbL out"));
+ }
+
+
+void CHXTNEVideoClipInfoImp::CancelThumb()
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::CancelThumb in"));
+ c_State = ECancelling;
+ SendReceive(ECancelThumbmsg);
+ FLOG(_L("CHXTNEVideoClipInfoImp::CancelThumb out"));
+}
+
+ TPtrC CHXTNEVideoClipInfoImp::FileName() const
+{
+ TFileName fileName;
+ if (iCloseHandle)
+ {
+ iFileHandle.FullName(fileName);
+ }
+
+ return fileName;
+}
+
+TInt CHXTNEVideoClipInfoImp::VideoFrameCount() const
+{
+ return (TInt)iMetaData.iFrameCount ;
+
+}
+
+
+// Called from Observer after a Complete() from Server
+
+void CHXTNEVideoClipInfoImp::ServiceCompleted(TInt aError)
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::ServiceCompleted in aError=%d c_State=%d"),
+ aError, c_State);
+ switch(c_State)
+ {
+ case EStartGettingMetadata:
+ FetchAndSendMetaData(aError);
+ break;
+ case EStartGettingThumbNail:
+ if (aError == KErrNone)
+ {
+ GenerateThumbNail();
+ }
+ else
+ {
+ if (iOutBitmap)
+ {
+ delete iOutBitmap;
+ iOutBitmap = NULL;
+ }
+ m_LastError = aError;
+ }
+
+ NotifyIfGetThumbPending(m_LastError, iOutBitmap);
+ break;
+ case ECancelling:
+ default:
+ break;
+ }
+
+ FLOG(_L("CHXTNEVideoClipInfoImp::ServiceCompleted out"));
+
+}
+
+void CHXTNEVideoClipInfoImp::FetchAndSendMetaData(TInt aError)
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::FetchAndSendMetaData in"));
+ if (aError == KErrNone)
+ {
+ aError = SendReceive(EGetMetaDatamsg, TIpcArgs(&iMetaData));
+ }
+ if(c_State== EStartGettingMetadata)
+ {
+ CTNEVideoClipInfo *pInfo = (CTNEVideoClipInfo *) this;
+ iClipInfoObserver->NotifyVideoClipInfoReady(*pInfo, aError);
+ }
+ FLOG(_L("CHXTNEVideoClipInfoImp::FetchAndSendMetaData out and state = %d"), c_State);
+
+}
+
+// ownership of pBitMap will be passed to Observer
+void CHXTNEVideoClipInfoImp::NotifyIfGetThumbPending(TInt aError, CFbsBitmap *&pBitMap)
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::NotifyIfGetThumbPending in"));
+ if (iThumbObserver)
+ {
+ CFbsBitmap* pTmpBitmap = pBitMap;
+ pBitMap = NULL;
+ iThumbObserver->NotifyVideoClipThumbCompleted(*this, aError, pTmpBitmap);
+ }
+ FLOG(_L("CHXTNEVideoClipInfoImp::NotifyIfGetThumbPending out"));
+}
+
+void CHXTNEVideoClipInfoImp::GenerateThumbNail()
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::GenerateThumbNail in"));
+ TInt bytesPerPixel = 0;
+ TInt error = KErrNone;
+
+ if ( !iRgbBuf )
+ {
+ TSize inputFrameResolution(iMetaData.iWidth,iMetaData.iHeight);
+
+ // rgb specs
+ TUint thumbLength = iMetaData.iWidth * iMetaData.iHeight;
+ TUint thumbUVLength = thumbLength>>2;
+
+ // VPASSERT(iYuvBuf);
+ // assign yuv pointers
+ TUint8* yBuf = iThumbRequestData.iYUVBuffer;
+ TUint8* uBuf = yBuf + thumbLength;
+ TUint8* vBuf = uBuf + thumbUVLength;
+
+ // convert to no enhabnce if 64K is selected as thumb display mode
+ if(iThumbDisplayMode == EColor64K)
+ iThumbEnhance = EFalse;
+
+ // check validity of thumbnail and associated operation
+ if(iThumbEnhance) // for saving to file
+ {
+ iThumbDisplayMode = EColor16M; // 24-bit color image for enhancement
+
+ // no enhancements if clip is too small.
+ if (iOutputThumbResolution.iWidth < 16 || iOutputThumbResolution.iHeight < 16)
+ {
+ iThumbEnhance = EFalse;
+ }
+ }
+ else // for screen display
+ {
+ if(iThumbDisplayMode == ENone) // if no preference
+ iThumbDisplayMode = EColor64K; // 16-bit image
+ }
+
+ // determine proper bit depth for the bitmap
+ if(iThumbDisplayMode == EColor16M)
+ bytesPerPixel = 3; // 24-bit rgb takes 3 bytes, stored as bbbbbbbb gggggggg rrrrrrrr
+ else if(iThumbDisplayMode == EColor64K || iThumbDisplayMode == EColor4K)
+ bytesPerPixel = 2; // 12-bit rgb takes 2 bytes, stored as ggggbbbb xxxxrrrr
+ else
+ {
+ HandleThumbnailError(KErrNotSupported);
+ return; // support for 12-, 16- and 24-bit color images only
+ }
+
+ // create output rgb buffer
+ TRAP(error, iRgbBuf = (TUint8*) User::AllocL(thumbLength * bytesPerPixel));
+ if (HandleThumbnailError(error))
+ return;
+
+ TInt scanLineLength;
+
+ // convert yuv to rgb
+ switch (iThumbDisplayMode)
+ {
+
+ case EColor4K:
+ {
+ TInt error;
+ CYuv2Rgb12* yuvConverter = NULL;
+ TRAP(error, yuvConverter = new(ELeave) CYuv2Rgb12);
+ if (HandleThumbnailError(error))
+ return;
+ scanLineLength = inputFrameResolution.iWidth * bytesPerPixel;
+ TRAP(error, yuvConverter->ConstructL(inputFrameResolution.iWidth, inputFrameResolution.iHeight, inputFrameResolution.iWidth, inputFrameResolution.iHeight));
+ if (HandleThumbnailError(error))
+ return;
+ yuvConverter->Convert(yBuf, uBuf, vBuf, inputFrameResolution.iWidth, inputFrameResolution.iHeight, iRgbBuf, scanLineLength);
+ delete yuvConverter;
+ yuvConverter=0;
+ }
+ break;
+
+ default:
+ case EColor64K:
+ {
+ TInt error;
+ CYuv2Rgb16* yuvConverter = NULL;
+ TRAP(error, yuvConverter = new(ELeave) CYuv2Rgb16);
+ if (HandleThumbnailError(error))
+ return;
+ scanLineLength = inputFrameResolution.iWidth * bytesPerPixel;
+ TRAP(error, yuvConverter->ConstructL(inputFrameResolution.iWidth, inputFrameResolution.iHeight, inputFrameResolution.iWidth, inputFrameResolution.iHeight);)
+ if (HandleThumbnailError(error))
+ return;
+ yuvConverter->Convert(yBuf, uBuf, vBuf, inputFrameResolution.iWidth, inputFrameResolution.iHeight, iRgbBuf, scanLineLength);
+ delete yuvConverter;
+ yuvConverter=0;
+ }
+ break;
+
+ case EColor16M:
+ {
+ TInt error;
+ CYuv2Rgb24* yuvConverter = NULL;
+ TRAP(error, yuvConverter = new(ELeave) CYuv2Rgb24);
+ if (HandleThumbnailError(error))
+ return;
+ scanLineLength = inputFrameResolution.iWidth * bytesPerPixel;
+ TRAP(error, yuvConverter->ConstructL(inputFrameResolution.iWidth, inputFrameResolution.iHeight, inputFrameResolution.iWidth, inputFrameResolution.iHeight))
+ if (HandleThumbnailError(error))
+ return;
+ yuvConverter->Convert(yBuf, uBuf, vBuf, inputFrameResolution.iWidth, inputFrameResolution.iHeight, iRgbBuf, scanLineLength);
+ delete yuvConverter;
+ yuvConverter=0;
+ }
+ break;
+ }
+ }
+
+ if(!iThumbEnhance)
+ {
+ TSize inputFrameResolution(iMetaData.iWidth,iMetaData.iHeight);
+
+ /* Pre-calculate pixel indices for horizontal scaling. */
+ // inputFrameResolution is the resolution of the image read from video clip.
+ // iOutputThumbResolution is the final resolution desired by the caller.
+
+ TInt OutW = (iOutputThumbResolution.iWidth + 3 )/4 * 4;
+ TInt OutH = (iOutputThumbResolution.iHeight + 3 )/4 * 4;
+
+ TSize roundedsize = TSize (OutW,OutH);
+
+ TInt xIncrement = inputFrameResolution.iWidth * OutW;
+ TInt xBoundary = OutW * OutW;
+
+ TInt* xIndices = 0;
+ TRAPD(xIndicesErr, xIndices = new (ELeave) TInt[OutW]);
+ if (xIndicesErr == KErrNone)
+ {
+ TInt xDecision = xIncrement / bytesPerPixel; // looks like they changed here - orig was /2
+ TInt sourceIndex = 0;
+ for (TInt x = 0; x < OutW; x++)
+ {
+ while (xDecision > xBoundary)
+ {
+ xDecision -= xBoundary;
+ sourceIndex += bytesPerPixel;
+ }
+
+ xIndices[x] = sourceIndex;
+ xDecision += xIncrement;
+ }
+ }
+ else
+ {
+ HandleThumbnailError(xIndicesErr);
+ return;
+ }
+
+ /* Initialize bitmap. */
+ TRAPD(bitmapErr, iOutBitmap = new (ELeave) CFbsBitmap);
+ if ((xIndicesErr == KErrNone) && (bitmapErr == KErrNone))
+ {
+ bitmapErr = iOutBitmap->Create(roundedsize, iThumbDisplayMode/*EColor64K*/);
+ if (bitmapErr == KErrNone)
+ {
+ // Lock the heap to prevent the FBS server from invalidating the address
+ iOutBitmap->LockHeap();
+
+ /* Scale to desired iOutputThumbResolution and copy to bitmap. */
+ TUint8* dataAddress = (TUint8*)iOutBitmap->DataAddress(); // fix
+
+ TInt yIncrement = inputFrameResolution.iHeight * OutH;
+ TInt yBoundary = OutH * OutH;
+
+ TInt targetIndex = 0;
+ TInt sourceRowIndex = 0;
+ TInt yDecision = yIncrement / 2;
+ for (TInt y = 0; y < OutH; y++)
+ {
+ while (yDecision > yBoundary)
+ {
+ yDecision -= yBoundary;
+ sourceRowIndex += (inputFrameResolution.iWidth * bytesPerPixel);
+ }
+ yDecision += yIncrement;
+
+
+ for (TInt x = 0; x < OutW; x++)
+ {
+ for (TInt i = 0; i < bytesPerPixel; ++i)
+ {
+ const TInt firstPixelSourceIndex = sourceRowIndex + xIndices[x] + i;
+ dataAddress[targetIndex] = iRgbBuf[firstPixelSourceIndex];
+ targetIndex++;
+ }
+ }
+ }
+ iOutBitmap->UnlockHeap();
+
+ // resing to original if odd values were input
+ if(roundedsize != iOutputThumbResolution)
+ {
+
+ TInt err ;
+ err = iOutBitmap->Resize(iOutputThumbResolution);
+ if(err!= KErrNone)
+ HandleThumbnailError(err);
+
+ }
+
+ }
+
+ else
+ {
+ delete iOutBitmap; iOutBitmap = 0;
+ HandleThumbnailError(bitmapErr);
+ return;
+ }
+ }
+ else
+ {
+ HandleThumbnailError(bitmapErr);
+ delete[] xIndices; xIndices = 0;
+ return;
+ }
+
+ delete[] xIndices;
+ xIndices = 0;
+ }
+ else // enhance
+ {
+ TInt i,j;
+ // create input bitmap and buffer
+ CFbsBitmap* inBitmap = 0;
+ TRAPD(inBitmapErr, inBitmap = new (ELeave) CFbsBitmap);
+ if( inBitmapErr == KErrNone )
+ {
+ // create bitmaps
+ TSize originalResolution(iMetaData.iWidth, iMetaData.iHeight);
+ inBitmapErr = inBitmap->Create(originalResolution, iThumbDisplayMode/*EColor16M*/);
+
+ if( inBitmapErr == KErrNone )
+ {
+ // fill image from rgb buffer to input bitmap buffer
+ TPtr8 linePtr(0,0);
+ TInt lineLength = inBitmap->ScanLineLength(originalResolution.iWidth, iThumbDisplayMode);
+ for(j=0, i=0; j<originalResolution.iHeight; j++, i+=lineLength)
+ {
+ linePtr.Set(iRgbBuf+i, lineLength, lineLength);
+ inBitmap->SetScanLine((TDes8&)linePtr,j);
+ }
+
+ // create output bitmap
+ TRAPD(outBitmapErr, iOutBitmap = new (ELeave) CFbsBitmap);
+ if( outBitmapErr == KErrNone )
+ {
+ outBitmapErr = iOutBitmap->Create(iOutputThumbResolution, iThumbDisplayMode/*EColor16M*/); // same size as input frame
+
+ if( outBitmapErr == KErrNone )
+ {
+ // post-processing enhancement
+ TRAP(outBitmapErr, EnhanceThumbnailL((const CFbsBitmap*)inBitmap, (CFbsBitmap*)iOutBitmap));
+
+ }
+ else
+ {
+ delete inBitmap; inBitmap = 0;
+ delete iOutBitmap; iOutBitmap = 0;
+ HandleThumbnailError(outBitmapErr);
+ return;
+ }
+ }
+ else
+ {
+ delete inBitmap; inBitmap = 0;
+ HandleThumbnailError(outBitmapErr);
+ return;
+ }
+ }
+ else
+ {
+ delete inBitmap; inBitmap = 0;
+ HandleThumbnailError(inBitmapErr);
+ return;
+ }
+
+ // delete input bitmap
+ delete inBitmap;
+ inBitmap = 0;
+ }
+ else
+ {
+ HandleThumbnailError(inBitmapErr);
+ return;
+ }
+ }
+
+ delete iRgbBuf;
+ iRgbBuf = 0;
+ FLOG(_L("CHXTNEVideoClipInfoImp::GenerateThumbNail out"));
+}
+
+
+TBool CHXTNEVideoClipInfoImp::HandleThumbnailError(TInt aError)
+{
+ if (aError != KErrNone)
+ {
+ m_LastError = aError;
+
+ return ETrue;
+ }
+
+ return EFalse;
+}
+
+
+void CHXTNEVideoClipInfoImp::EnhanceThumbnailL(const CFbsBitmap* aInBitmap,
+ CFbsBitmap* aTargetBitmap)
+{
+ FLOG(_L("CHXTNEVideoClipInfoImp::EnhanceThumbnailL in"));
+ // create enhancement object
+ if(!iEnhancer)
+ iEnhancer = (CDisplayChain*) CDisplayChain::NewL();
+
+ // enhance image
+ iEnhancer->ProcessL(aInBitmap, aTargetBitmap);
+
+ // clear enhancement object
+ delete iEnhancer;
+ iEnhancer=0;
+ FLOG(_L("CHXTNEVideoClipInfoImp::EnhanceThumbnailL out"));
+
+}