diff -r 57d4cdd99204 -r edfc90759b9f imageeditorengine/filters/FilterIclSource/Src/CFilterIclSource.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imageeditorengine/filters/FilterIclSource/Src/CFilterIclSource.cpp Fri Jan 29 13:53:17 2010 +0200 @@ -0,0 +1,633 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "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: +* Ixonos Plc +* +* Description: +* +*/ + + +#include +#include +#include +#include +#include + +#include "CFilterIclSource.h" + +const TInt KScaleBits = 12; +const TInt KBlockSize = 16; +const TInt KDestBufferMaxDim = 352; + +//============================================================================= +EXPORT_C TInt CFilterIclSource::Create() +{ + CFilterIclSource * ptr = NULL; + TRAPD (error, ptr = NewL(); ); + if (error != KErrNone) + { + ptr = NULL; + } + return (TInt)((MImageFilter*)ptr); +} + +//============================================================================= +CFilterIclSource* CFilterIclSource::NewL() +{ + CFilterIclSource * self = new (ELeave) CFilterIclSource(); + CleanupStack::PushL (self); + self->ConstructL(); + CleanupStack::Pop (self); + return self; +} + +//============================================================================= +CFilterIclSource::~CFilterIclSource() +{ + delete iBitmap; + delete[] iDestBuffer; + if (iLoader) + { + iLoader->Cancel(); + } + delete iLoader; + delete[] iIndexMap; + for (TInt i = 0; i < iBlockBufferSize; ++i) + { + delete iBlockBuffer[i]; + iBlockBuffer[i] = NULL; + } + delete[] iBlockBuffer; + iBlockBuffer = NULL; +} + +//============================================================================= +CFilterIclSource::CFilterIclSource() +{ + +} + +//============================================================================= +void CFilterIclSource::ConstructL() +{ + +} + +//============================================================================= +TRect CFilterIclSource::Rect() +{ + if (iOutputState == EDirect) + { + return iRect; + } + else + { + return iScaledRect; + } +} + +//============================================================================= +TReal CFilterIclSource::Scale() +{ + if (iOutputState == EDirect) + { + return 1.0; + } + else + { + return iRelScale; + } +} + +//============================================================================= +TSize CFilterIclSource::ViewPortSize() +{ + return iSize; +} + +//============================================================================= +TBlock * CFilterIclSource::GetBlockL ( const TRect & aRect ) +{ + if (iOutputState == EBuffer) + { + if ( !aRect.Intersects(iScaledRect) ) + { + return NULL; + } + TRect rect = aRect; + rect.Intersection(iScaledRect); + + TBlock * pB = new (ELeave) TBlock (rect); + + TUint32 * pS = iDestBuffer + (rect.iTl.iY - iScaledRect.iTl.iY) * iDestSize.iWidth + + (rect.iTl.iX - iScaledRect.iTl.iX); + TUint32 * pD = pB->iData; + + for (TInt i = rect.iTl.iY; i < rect.iBr.iY; ++i) + { + Mem::Copy(pD, pS, pB->iWidth * sizeof(TUint32)); + pD += pB->iWidth; + pS += iDestSize.iWidth; + } + return pB; + } + else + { + + if (!aRect.Intersects(iRect)) + { + return NULL; + } + + // Clip rectangle to image + TRect rect = aRect; + rect.Intersection(iRect); + + // Create block for pixel data + TBlock * pB = new (ELeave) TBlock; + pB->iRect = rect; + pB->iWidth = (pB->iRect.iBr.iX - pB->iRect.iTl.iX); + pB->iHeight = (pB->iRect.iBr.iY - pB->iRect.iTl.iY); + pB->iDataLength = pB->iWidth * pB->iHeight; + pB->iData = new (ELeave) TUint32 [pB->iDataLength]; + + // Store pixel data to block + TBitmapUtil bm (iBitmap); + bm.Begin(TPoint(0,0)); + + TUint8 * psos = (TUint8*)(iBitmap->DataAddress()); + psos += pB->iRect.iTl.iY * iWStep + pB->iRect.iTl.iX * 3; + TUint32 * pd = pB->iData; + for (TInt i = rect.iTl.iY; i < rect.iBr.iY; ++i) + { + + TUint8 * ps = psos; + psos += iWStep; + + for (TInt j = rect.iTl.iX; j < rect.iBr.iX; ++j) + { + TUint8 b = *ps++; + TUint8 g = *ps++; + TUint8 r = *ps++; + *pd++ = (r << 16) | (g << 8) | b; + } + } + + bm.End(); + + return pB; + } +} + +//============================================================================= +void CFilterIclSource::SetParent (MImageFilter * aParent) +{ + iParent = aParent; +} + +//============================================================================= +void CFilterIclSource::SetChild (MImageFilter * aChild) +{ + iChild = aChild; +} + +//============================================================================= +TInt CFilterIclSource::CmdL (const TDesC16 & aCmd) +{ + + TLex lex (aCmd); + + while ( !lex.Eos() ) + { + TPtrC token = lex.NextToken(); + if (token.Compare( _L("file") ) == 0) + { + + iFileName.Zero(); + + // Find the start of the string + while (!lex.Eos()) + { + if (lex.Get() == '"') break; + } + + // Get the text data + while (!lex.Eos()) + { + TChar c= lex.Get(); + if (c == '"') + { + break; + } + else + { + iFileName.Append(c); + } + } + + if (iBitmap) + { + delete iBitmap; + iBitmap = NULL; + } + + if(iLoader) + { + delete iLoader; + iLoader = NULL; + } + + iSize.iWidth = 0; + iSize.iHeight = 0; + + iRect.iTl.iX = 0; + iRect.iTl.iY = 0; + iRect.iBr.iX = 0; + iRect.iBr.iY = 0; + + iWStep = 0; + } + else if( token.Compare( _L("loadimage") ) == 0 ) + { + + if ( !iBitmap ) + { + // Delete old bitmap and create new + iBitmap = new (ELeave) CFbsBitmap; + + // Create new loader and start loading image + if (iLoader) + { + delete iLoader; + iLoader = NULL; + } + + iLoader = new (ELeave) CImageLoader (this); + iLoader->LoadBitmapL (iFileName, iBitmap); + + // Wait here until loading is finished + CActiveScheduler::Start(); + + // Delete loader, not needed anymore + delete iLoader; + iLoader = NULL; + + // Get image size + iSize = iBitmap->SizeInPixels(); + + // Update region of interest + iRect.iTl.iX = 0; + iRect.iTl.iY = 0; + iRect.iBr.iX = iSize.iWidth; + iRect.iBr.iY = iSize.iHeight; + + // Compute row offset in bytes + iWStep = CFbsBitmap::ScanLineLength(iSize.iWidth, EColor16M); + + // Initialize block buffer size to 2 x row size in blocks + iBlockBufferSize = iSize.iWidth / KBlockSize; + if (iSize.iWidth % KBlockSize > 0) + { + iBlockBufferSize++; + } + iBlockBufferSize *= 2; + + // Compute image size in 16 x 16 blocks + iSizeInBlocks.iWidth = iSize.iHeight / KBlockSize; + if (iSize.iHeight % KBlockSize > 0) + { + iSizeInBlocks.iWidth++; + } + iSizeInBlocks.iHeight = iSize.iHeight / KBlockSize; + if (iSizeInBlocks.iHeight % KBlockSize > 0) + { + iSizeInBlocks.iHeight++; + } + + // Crate new block buffer, init to zero + iBlockBuffer = new (ELeave) TBlockEntry * [iBlockBufferSize]; + Mem::FillZ (iBlockBuffer, iBlockBufferSize * sizeof(TBlockEntry *)); + + // Reset oldest block index to zero + iOldestBlock = 0; + + // Create index map, init to -1 + TInt blocks = iSizeInBlocks.iWidth * iSizeInBlocks.iHeight; + delete[] iIndexMap; + iIndexMap = NULL; + iIndexMap = new (ELeave) TInt [blocks]; + for (TInt i = 0; i < blocks; ++i) iIndexMap[i] = -1; + + } + + + iOutputState = EBuffer; + + // set crop rectangle to full image size + if (iRect.Size() == TSize(0,0)) + { + iRect.iTl.iX = 0; + iRect.iTl.iY = 0; + iRect.iBr.iX = iSize.iWidth; + iRect.iBr.iY = iSize.iHeight; + } + + // load rectangle + LoadRectL(); + } + else if( token.Compare( _L("ulc") ) == 0 ) + { + lex.Inc(); + lex.Val( iRect.iTl.iX ); + } + else if( token.Compare( _L("ulr") ) == 0 ) + { + lex.Inc(); + lex.Val( iRect.iTl.iY ); + } + else if( token.Compare( _L("lrc") ) == 0 ) + { + lex.Inc(); + lex.Val( iRect.iBr.iX ); + } + else if( token.Compare( _L("lrr") ) == 0 ) + { + lex.Inc(); + lex.Val( iRect.iBr.iY ); + } + else if( token.Compare( _L("fileoutput") ) == 0 ) + { + iRect.iTl.iX = 0; + iRect.iTl.iY = 0; + iRect.iBr.iX = iSize.iWidth; + iRect.iBr.iY = iSize.iHeight; + iOutputState = EDirect; + } + else if( token.Compare( _L("bufferoutput") ) == 0 ) + { + iOutputState = EBuffer; + } + } + return 0; +} + +//============================================================================= +const char * CFilterIclSource::Type() +{ + return "iclsource"; +} + +//============================================================================= +void CFilterIclSource::OperationReady (const TInt /* aError */) +{ + CActiveScheduler::Stop(); +} + +//============================================================================= +void CFilterIclSource::LoadRectL() + { + + // compute destination buffer size + TInt width = iRect.iBr.iX - iRect.iTl.iX; + TInt height = iRect.iBr.iY - iRect.iTl.iY; + + if (width >= height) + { + TReal scale = (TReal)KDestBufferMaxDim / width; + iDestSize.iWidth = KDestBufferMaxDim; + iDestSize.iHeight = (TInt)(height * scale + 0.5); + } + else + { + TReal scale = (TReal)KDestBufferMaxDim / height; + iDestSize.iHeight = KDestBufferMaxDim; + iDestSize.iWidth = (TInt)(width * scale + 0.5); + } + + // create new destination buffer + delete[] iDestBuffer; + iDestBuffer = new (ELeave) TUint32 [iDestSize.iWidth * iDestSize.iHeight]; + + // scale buffer + + TBitmapUtil bmtl (iBitmap); + bmtl.Begin(TPoint(0,0)); + + TInt scale = (height << KScaleBits) / iDestSize.iHeight; + TUint32 * pD = iDestBuffer; + TUint8 * pS = (TUint8 *)iBitmap->DataAddress() + + iRect.iTl.iY * iWStep + iRect.iTl.iX * 3; + + for (TInt i = 0; i < iDestSize.iHeight; ++i) + { + TInt y = (i * scale) >> KScaleBits; + + for (TInt j = 0; j < iDestSize.iWidth; ++j) + { + TInt x = (j * scale) >> KScaleBits; + TUint8 * pSS = pS + y * iWStep + x * 3; + TUint32 c = (*(pSS + 2) << 16) | (*(pSS + 1) << 8) | *pSS; + *pD++ = c; + } + } + + bmtl.End(); + + iRelScale = (TReal)(iDestSize.iHeight) / (TReal) height; + + iScaledRect.iTl.iX = (TInt)(iRect.iTl.iX * iRelScale + 0.5); + iScaledRect.iTl.iY = (TInt)(iRect.iTl.iY * iRelScale + 0.5); + iScaledRect.iBr.iX = (TInt)(iRect.iBr.iX * iRelScale + 0.5); + iScaledRect.iBr.iY = (TInt)(iRect.iBr.iY * iRelScale + 0.5); + + // check that iScaledRect is inside buffer + TInt tmp = iScaledRect.iBr.iX - iScaledRect.iTl.iX - iDestSize.iWidth; + if ( tmp > 0 ) + { + iScaledRect.iBr.iX -= tmp; + } + + tmp = iScaledRect.iBr.iY - iScaledRect.iTl.iY - iDestSize.iHeight; + if (tmp > 0 ) + { + iScaledRect.iBr.iY -= tmp; + } + +/* + CFbsBitmap * bitmap = new (ELeave) CFbsBitmap; + CleanupStack::PushL(bitmap); + User::LeaveIfError(bitmap->Create(iDestSize, EColor16M)); + TBitmapUtil bm (bitmap); + bm.Begin(TPoint(0,0)); + TUint8 * pDOS = (TUint8 *)bitmap->DataAddress(); + TUint32 * ps = iDestBuffer; + TInt ws = CFbsBitmap::ScanLineLength(iDestSize.iWidth, EColor16M); + for (TInt ii = 0; ii < iDestSize.iHeight; ++ii) + { + TUint8 * pD = pDOS; + pDOS += ws; + for (TInt j = 0; j < iDestSize.iWidth; ++j) + { + TUint32 c = *ps++; + *pD++ = c & 0xFF; + c >>= 8; + *pD++ = c & 0xFF; + c >>= 8; + *pD++ = c & 0xFF; + } + } + bm.End(); + + TFileName filename; + filename.Copy (_L("c:\\nokia\\images\\sf_")); + filename.AppendNum((TInt)iDestBuffer); + filename.Append(_L(".mbm")); + bitmap->Save(filename); + + CleanupStack::PopAndDestroy(); // bitmap +*/ + } + + + + + + + +//============================================================================= +CImageLoader::CImageLoader(MLoaderObserver * aObserver) : +CActive (EPriorityStandard), +iObserver (aObserver) +{ + CActiveScheduler::Add (this); +} + +//============================================================================= +CImageLoader::~CImageLoader() +{ + if (iDecoder) + { + iDecoder->Cancel(); + } + delete iDecoder; +} + +//============================================================================= +void CImageLoader::LoadBitmapL (TDesC & aFileName, CFbsBitmap * iBitmap) +{ + + // Delete old decoder + if (iDecoder) + { + iDecoder->Cancel(); + } + delete iDecoder; + iDecoder = NULL; + + //Get the MIME type of the file to be decoded: + TBuf8 mimeType; + + RFs vFs; + User::LeaveIfError(vFs.Connect()); + CleanupClosePushL(vFs); + + TRAPD( getMimeErr, CImageDecoder::GetMimeTypeFileL( + vFs, + aFileName, + mimeType ) ); + if ( getMimeErr != KErrNone ) { } + + CleanupStack::PopAndDestroy(); // vFs + + // If MIME type contains "jpeg", then it would make sense to check + // for HW Codec possibility + TUid implementationUid = KNullUid; // default value that can be used + + TInt vStartIndLocation = mimeType.Find( _L8( "jpeg" ) ); + if( vStartIndLocation != KErrNotFound ) + { + RUidDataArray implArray; + const TUid properties[] = { KUidHwCodec }; + + // Request existing plugins with the desired properties + TRAPD( getIntErr, CImageDecoder::GetInterfaceImplementationsL( + properties, + 1, + implArray ) ); + + if ( implArray.Count() != 0 && getIntErr == KErrNone ) + { + // use the first HW codec from the list + implementationUid = implArray[0]; + // HW Codec found + } + } + + // if HW codec not found implementationUid == KNullUid -> + // ICL selects proper codec + TRAPD( decErr, iDecoder = CImageDecoder::FileNewL( + vFs, + aFileName, + CImageDecoder::EOptionNone, + KNullUid, + KNullUid, + implementationUid ) ); + if ( decErr != KErrNone ) + { + User::Leave( decErr ); + } + + // Create new bitmap + User::LeaveIfError ( iBitmap->Create (iDecoder->FrameInfo().iOverallSizeInPixels, EColor16M)); + + // Start decoding + iDecoder->Convert (&iStatus, *iBitmap); + + if (iStatus != KRequestPending) + { + User::Leave(iStatus.Int()); + } + + SetActive(); + +} + +//============================================================================= +void CImageLoader::RunL() +{ + if (iStatus.Int() == KRequestPending) + { + iDecoder->ContinueConvert (&iStatus); + } + else + { + iObserver->OperationReady ( iStatus.Int() ); + } +} + +//============================================================================= +void CImageLoader::DoCancel() +{ + if (iDecoder) + { + iDecoder->Cancel(); + } +} + + +#if !defined(EKA2) +GLDEF_C TInt E32Dll( TDllReason ) + { + return KErrNone; + } +#endif