imageeditorengine/filters/FilterJpegTarget/Src/CFilterJpegTarget.cpp
author Mikael Laine <mikael.laine@ixonos.com>
Fri, 29 Jan 2010 13:53:17 +0200
changeset 1 edfc90759b9f
permissions -rw-r--r--
Committing the Image Editor package under the Eclipse Public License

/*
* 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 <fbs.h>
#include "CFilterJpegTarget.h"
#include "MJpegSave.h"
#include "JpegSaveFactory.h"

const TInt KSaveBufferLength = 0x40000; // 256 kilobytes

EXPORT_C TInt CFilterJpegTarget::Create()
	{
	CFilterJpegTarget* ptr = NULL;
	TRAPD( error, ptr = NewL(); );
	if( error != KErrNone )
		{
		ptr = NULL;
		}
	return (TInt)((MImageFilter*)ptr);
	}



CFilterJpegTarget* CFilterJpegTarget::NewL()
	{
	CFilterJpegTarget* self = new( ELeave )CFilterJpegTarget();
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	return self;
	}



CFilterJpegTarget::~CFilterJpegTarget()
	{
	delete iJpegSave;
	iFile.Close();
	iFs.Close();
	}



CFilterJpegTarget::CFilterJpegTarget()
	{
	}



void CFilterJpegTarget::ConstructL()
	{
	User::LeaveIfError( iFs.Connect() );
	}



TRect CFilterJpegTarget::Rect()
    {
	TRect rect;
	
	rect.iTl.iX = 0;			
	rect.iTl.iY = 0;			
	rect.iBr.iX = iSize.iWidth;			
	rect.iBr.iY = iSize.iHeight;			

	return rect;
    }

TReal CFilterJpegTarget::Scale()
    {
    return iChild->Scale();
    }

TSize CFilterJpegTarget::ViewPortSize()
{
    return iChild->ViewPortSize();
}

TBlock * CFilterJpegTarget::GetBlockL ( const TRect & /*aRect*/ )
{
    return NULL;
}

void CFilterJpegTarget::SetParent( MImageFilter* aParent )
	{
	iParent = aParent;
	}




void CFilterJpegTarget::SetChild( MImageFilter* aChild )
	{
	iChild = aChild;
	}



TInt CFilterJpegTarget::CmdL( const TDesC16& aCmd )
	{

	TInt exifData = 0;
	TInt exifLength = 0;

	TLex lex( aCmd );
	while( ! lex.Eos() )
		{
		TPtrC token = lex.NextToken();
		if( token.Compare( _L("width") ) == 0 )
			{
			lex.Inc();
			lex.Val( iSize.iWidth );
			}
		else if( token.Compare( _L("height") ) == 0 )
			{
			lex.Inc();
			lex.Val( iSize.iHeight );
			}
		else if( token.Compare( _L("exifdata") ) == 0 )
			{
			lex.Inc();
			lex.Val( exifData );
			}
		else if( token.Compare( _L("exiflen") ) == 0 )
			{
			lex.Inc();
			lex.Val( exifLength );
			}
		else if( token.Compare( _L("file") ) == 0 )
			{
			//
			// Starts saving, gets filename in parenthesis: file "file.jpg"
			// !! lexer cuts with space in filename
			//
			
			if ( iSize.iWidth == 0 || iSize.iHeight == 0 )
				{
				iRect = iChild->Rect();
				iSize.iWidth = iRect.iBr.iX - iRect.iTl.iX;
		        iSize.iHeight = iRect.iBr.iY - iRect.iTl.iY;
				}
			else
				{
				iRect.iTl.iX = 0;			
				iRect.iTl.iY = 0;			
				iRect.iBr.iX = iSize.iWidth;			
				iRect.iBr.iY = iSize.iHeight;			
				}
			
			TPtrC filec = lex.NextToken();
			TPtrC file( filec.Ptr()+1, filec.Length()-2 );
			iFileName.Copy( file );
			iFile.Replace( iFs, iFileName, EFileWrite | EFileShareAny );

			iJpegSave = JpegSaveFactory::CreateJpegSaveL( &iFs, &iFile );
			
			TPtr8 exifPtr( (TUint8*)exifData, exifLength );
			exifPtr.SetLength( exifLength );

			iJpegSave->StartSaveL( iSize, exifPtr, KSaveBufferLength, 90 );
			
			iBm.iData = new( ELeave )TUint32[ 128 ];
			iBm.iSize = TSize (16,8);
            iBm.iDrawRect = iBm.iSize;
			iBm.iType = E16MColor;
			
			
			iBlockWidth = 16;
			iBlockHeight = 8;
			iBlockY = 0;
			}
		else if( token.Compare( _L("store") ) == 0 )
			{

            TInt height = iRect.iBr.iY - iRect.iTl.iY;
			TInt progress = (iBlockY * 100) / height;
			if( iBlockY >= height)
            	{
				iJpegSave->FinalizeSave();
				delete iBm.iData;
				progress = 100;
				iFile.Close();
				}
            else
            	{
                TPoint tl (iRect.iTl.iX, iBlockY + iRect.iTl.iY);
                TPoint br = tl + TPoint (iBlockWidth, iBlockHeight);

                while ( tl.iX < iRect.iBr.iX )
                	{
                    //  Get block
                    TBlock * pB = iChild->GetBlockL ( TRect(tl, br) );

                    if (pB)
                    	{
                        TUint32 * ps = 
                            pB->iData + 
                            (tl.iY - pB->iRect.iTl.iY) * pB->iWidth +
                            (tl.iX - pB->iRect.iTl.iX);
                        TUint32 * pd = (TUint32*)iBm.iData;
                        TInt datalength = iBlockWidth * sizeof(TUint32);
                        for (TInt i = 0; i < iBlockHeight; ++i)
                        	{
                            Mem::Copy (pd, ps, datalength);
                            ps += pB->iWidth;
                            pd += iBlockWidth;
                        	}
                        
                        delete pB;
                        pB = NULL;

                    	}
                    else
                    	{
                        Mem::FillZ ((TUint8 *)iBm.iData, iBlockWidth * iBlockHeight * sizeof(TUint32));
                    	}
/*
            CFbsBitmap * bitmap = new (ELeave) CFbsBitmap;
            CleanupStack::PushL(bitmap);
            TSize blocksize (iBm.iSize);
            User::LeaveIfError(bitmap->Create(blocksize, EColor16M));
            TBitmapUtil bm (bitmap);
            bm.Begin(TPoint(0,0));
            TUint8 * pDOS = (TUint8 *)bitmap->DataAddress();
            TUint32 * pS = (TUint32 *)iBm.iData;
            TInt ws = CFbsBitmap::ScanLineLength(blocksize.iWidth, EColor16M);
            for (TInt ii = 0; ii < blocksize.iHeight; ++ii)
            {
                TUint8 * pD = pDOS;
                pDOS += ws;
                for (TInt j = 0; j < blocksize.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(tl.iY);
            filename.Append(_L("_"));
            filename.AppendNum(tl.iX);
            filename.Append(_L(".mbm"));
            bitmap->Save(filename);

            CleanupStack::PopAndDestroy(); // bitmap
*/

                    iJpegSave->SaveBlock( iBm );


                    tl.iX  += iBlockWidth;
                    br.iX  += iBlockWidth;

                	}
			    iBlockY += iBlockHeight;

            	}
			return progress;
			}
		
		else if( token.Compare( _L("abort") ) == 0 )
			{
			if (iBm.iData)
				{
				delete iBm.iData;	
				iBm.iData = NULL;
				}
			
			iFile.Close();
			}
		}
		
	return 0;
	}



const char* CFilterJpegTarget::Type()
	{
	return "jpegtarget";
	}
	
	
#if !defined(EKA2)
GLDEF_C TInt E32Dll( TDllReason )
    {
    return KErrNone;
    }	
#endif