imageeditorengine/EngineWrapper/src/ImageEditorEngineWrapper.cpp
changeset 1 edfc90759b9f
child 12 18b321db4884
equal deleted inserted replaced
0:57d4cdd99204 1:edfc90759b9f
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "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 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 //	INCLUDES
       
    22 #include <bautils.h>
       
    23 #include <eikenv.h>
       
    24 #include <aknutils.h>
       
    25 #include <e32math.h>
       
    26 
       
    27 //#include "ImageEditorPluginBase.hrh"
       
    28 #include "platform_security_literals.hrh"
       
    29 
       
    30 #include "ImageEditorEngineWrapper.h"
       
    31 #include "CFilterStack.h"
       
    32 #include "MImageFilter.h"
       
    33 #include "SystemParameters.h"
       
    34 #include "ImageEditorError.h"
       
    35 #include "ImageEditorUtils.h"
       
    36 #include "EditorVersion.h"
       
    37 
       
    38 
       
    39 #include "CExifParser.h"
       
    40 #include "TBitmapHandle.h"
       
    41 #include "MJpegSave.h"
       
    42 #include "JpegSaveFactory.h"
       
    43 
       
    44 
       
    45 //  Debug logger definitions
       
    46 #include "imageeditordebugutils.h"
       
    47 _LIT( KEngineWrapperLogFile,"EngineWrapper.log" );
       
    48 
       
    49 
       
    50 // CONSTANTS
       
    51 
       
    52 // 	Minimum source image x-y value that the engine is able to render
       
    53 const TInt KObMinSourceDimension    		= 16; 
       
    54 
       
    55 //	EXIF thumbnail quality
       
    56 const TInt KThumbnailJpegQuality    		= 60; 		// [0,100]
       
    57 const TInt KThumbnailMaxDimension			= 160;
       
    58 
       
    59 //  Used fixed point resolution for scales
       
    60 const TInt KScaleBits						= 12;
       
    61 
       
    62 const TReal KZoomScaleFactor                 = 0.5; 
       
    63 
       
    64 // Comment tag to be written to the EXIF data of JPEG file.
       
    65 _LIT8( KImageEditorExifComment, "Edited with Nokia Image Editor %d.%d.%d" );
       
    66 
       
    67 
       
    68 // 	Filter paths
       
    69 _LIT(KFilterJpegSource, "FilterJpegSource.dll");
       
    70 _LIT(KFilterIclSource, "FilterIclSource.dll");
       
    71 _LIT(KFilterTarget, "FilterJpegTarget.dll");
       
    72 _LIT(KFilterBuffer, "FilterBuffer.dll");
       
    73 _LIT(KFilterScale, 	"FilterScale.dll");
       
    74 _LIT(KFilterRotate, "FilterRotate.dll");
       
    75 
       
    76 //=============================================================================
       
    77 EXPORT_C CEngineWrapper * CEngineWrapper::NewL ()
       
    78 {
       
    79     LOG_INIT ( KEngineWrapperLogFile );
       
    80 
       
    81 	CEngineWrapper * self = new (ELeave) CEngineWrapper;
       
    82 	CleanupStack::PushL (self);
       
    83 	self->ConstructL();
       
    84 	CleanupStack::Pop(); // self
       
    85 	return self;
       
    86 }
       
    87 
       
    88 //=============================================================================
       
    89 EXPORT_C CEngineWrapper::~CEngineWrapper ()
       
    90 {
       
    91     LOG( KEngineWrapperLogFile, "CEngineWrapper::~CEngineWrapper");
       
    92     Cleanup();
       
    93 
       
    94 	delete iExifParser;
       
    95 	iExifParser = NULL;
       
    96 	
       
    97 }
       
    98 
       
    99 //=============================================================================
       
   100 EXPORT_C void CEngineWrapper::CreateJpegSourceL (const TDesC & aFileName)
       
   101 {
       
   102     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL" );
       
   103 #ifdef VERBOSE
       
   104     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL\taFileName: %S", &aFileName );
       
   105 #endif // VERBOSE
       
   106 
       
   107     //  SANITY CHECKS
       
   108     if ( !iMainEngine )
       
   109     {
       
   110         LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL: iMainEngine not created!" );
       
   111         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   112     }
       
   113 
       
   114 	//	Add JPEG source to engine
       
   115 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL --- Add jpeg source" );
       
   116 	if ( iMainEngine->NumFilters() == 0 )
       
   117 	{
       
   118 		iMainEngine->AddFilterL ( KFilterJpegSource );
       
   119 	}
       
   120 	else if  ( IsSameString ( (TUint8*)iMainEngine->Filter(0)->Type(), (TUint8*)"iclsource" ) )
       
   121 	{
       
   122 		iMainEngine->RemoveFilter (0);
       
   123 		iMainEngine->AddFilterL (KFilterJpegSource, 0);
       
   124 	}
       
   125 	else if  ( !IsSameString ( (TUint8*)iMainEngine->Filter(0)->Type(), (TUint8*)"jpegsource" ) )
       
   126 	{
       
   127 		iMainEngine->AddFilterL (KFilterJpegSource, 0);
       
   128 	}
       
   129 	iCmd.Copy ( _L("file \""));
       
   130 	iCmd.Append ( aFileName );
       
   131 	iCmd.Append ( _L("\""));
       
   132 	LOGFMT ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL: Cmd: %S", &aFileName );
       
   133 	iMainEngine->FunctionL ( 0, iCmd );
       
   134 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL --- Jpeg source added" );
       
   135 	iMainEngine->FunctionL ( 0, _L("loadimage"));
       
   136 
       
   137 	//	Get source image size
       
   138 	TRect rect = iMainEngine->Filter (0)->Rect(); 
       
   139 	iSourceSize = iMainEngine->Filter (0)->ViewPortSize(); 
       
   140 	LOGFMT ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL: source width: %d", iSourceSize.iWidth);
       
   141 	LOGFMT ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL: source height: %d", iSourceSize.iHeight);
       
   142 
       
   143     //  Check that the source image is of minimum size
       
   144     if (iSourceSize.iWidth < KObMinSourceDimension || iSourceSize.iHeight < KObMinSourceDimension)
       
   145     {
       
   146         User::Leave (KSIEEOpenFile);
       
   147     }
       
   148 
       
   149 	//	Initialize crop parameters
       
   150 	iBoundingRect.iTl.iX = 0;    
       
   151 	iBoundingRect.iTl.iY = 0;    
       
   152 	iBoundingRect.iBr.iX = iSourceSize.iWidth;    
       
   153 	iBoundingRect.iBr.iY = iSourceSize.iHeight;    
       
   154     iScale = 1.0;
       
   155     iMaxScale = 1.0;
       
   156     iMinScale = (TReal)iScreenSize.iWidth / iSourceSize.iWidth; 
       
   157     iPanX = iSourceSize.iWidth * 0.5;
       
   158     iPanY = iSourceSize.iHeight * 0.5;
       
   159     iPanStep = 128.0;
       
   160     iZoomMode = EZoomNormal;
       
   161     
       
   162 	//	Initialize system parameters
       
   163     iSysPars->SourceSize() = iSourceSize;
       
   164     iSysPars->Scale() = 1.0;
       
   165 
       
   166 
       
   167 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL ---  Read EXIF data" );
       
   168 
       
   169 	//	Read EXIF data pointer
       
   170 	iCmd.Copy ( _L("exifdata"));
       
   171 	TUint8 * exifptr = (TUint8 *)iMainEngine->FunctionL ( 0, iCmd );
       
   172 	
       
   173 	//	Read EXIF data length
       
   174 	iCmd.Copy ( _L("exiflength"));
       
   175 	TInt exiflen = (TInt)iMainEngine->FunctionL ( 0, iCmd );
       
   176 
       
   177 	//	Create and initialize EXIF parser
       
   178 	TPtrC8 exifdata (exifptr, exiflen);
       
   179 	if (iExifParser)
       
   180 	{
       
   181 		delete iExifParser;
       
   182 		iExifParser = NULL;		
       
   183 	}
       
   184 	
       
   185 	iExifParser = CExifParser::NewL ();
       
   186 	TRAPD( err, iExifParser->ParseL (exifdata) );
       
   187 	if (KErrNone == err)
       
   188 	{
       
   189 		LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL --- EXIF data read." );
       
   190 	}
       
   191 	else
       
   192 	{
       
   193 		LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL --- FAILED to parse EXIF data. Ignored." );
       
   194 	}
       
   195 
       
   196 
       
   197 }
       
   198 
       
   199 //=============================================================================
       
   200 EXPORT_C void CEngineWrapper::CreateJpegTargetL (
       
   201 	const TDesC & aFileName,
       
   202     const TInt      aQuality,
       
   203     const TSize *   aSize 
       
   204     )
       
   205 {
       
   206     LOG( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL" );
       
   207 #ifdef VERBOSE
       
   208     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL\taFileName: %S", &aFileName );
       
   209     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL\taQuality: %d", aQuality );
       
   210     if (aSize)
       
   211     {
       
   212         LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL\taSize->iWidth: %d", aSize->iWidth);
       
   213         LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL\taSize->iHeight: %d", aSize->iHeight);
       
   214     }
       
   215     else
       
   216     {
       
   217 		LOG( KEngineWrapperLogFile, "aSize == NULL" );
       
   218     }
       
   219 
       
   220 #endif // VERBOSE
       
   221 
       
   222     //  SANITY CHECKS
       
   223     if ( !iMainEngine )
       
   224     {
       
   225         LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL: iMainEngine not created!" );
       
   226         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   227     }
       
   228     if ( aQuality < 0 || aQuality > 100)
       
   229     {
       
   230         LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL: Invalid parameter aQuality!" );
       
   231         User::Panic (KEnginePanic, KEnginePanicParameter);
       
   232     }
       
   233     if ( aSize && ( (aSize->iWidth < 0 || aSize->iHeight < 0) ) )
       
   234     {
       
   235         LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL: Invalid parameter aSize!" );
       
   236         User::Panic (KEnginePanic, KEnginePanicParameter);
       
   237     }
       
   238 
       
   239 	//	Remove source buffer
       
   240 	iMainEngine->FunctionL (0, _L("fileoutput"));
       
   241 
       
   242 	//	Remove screen buffer
       
   243 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL --- Remove screen buffer" );
       
   244 	if ( IsSameString ( (TUint8*)iMainEngine->Filter(iMainEngine->NumFilters() - 1)->Type(), (TUint8*)"buffer" ) )
       
   245 	{
       
   246 		iMainEngine->RemoveFilter(iMainEngine->NumFilters() - 1);	
       
   247 	}
       
   248 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL --- Screen buffer removed" );
       
   249 
       
   250 	//	Remove jpeg target buffer
       
   251 	if ( IsSameString ( (TUint8*)iMainEngine->Filter(iMainEngine->NumFilters() - 1)->Type(), (TUint8*)"jpegtarget" ) )
       
   252 	{
       
   253 		iMainEngine->RemoveFilter(iMainEngine->NumFilters() - 1);	
       
   254 	}
       
   255 
       
   256 	//	Remove scale buffer, if image is not scaled
       
   257 	if ( iSysPars->Scale() == 1.0 )
       
   258 	{
       
   259 		LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL --- Remove screen scale filter." );
       
   260 		if ( IsSameString ( (TUint8*)iMainEngine->Filter(iMainEngine->NumFilters() - 1)->Type(), (TUint8*)"scale" ) )
       
   261 		{
       
   262 			iMainEngine->RemoveFilter(iMainEngine->NumFilters() - 1);	
       
   263 		}
       
   264 		LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL --- Screen scale filter removed." );
       
   265 	}
       
   266 
       
   267 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL --- Add jpeg target filter." );
       
   268 	iMainEngine->AddFilterL ( KFilterTarget );
       
   269 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegTargetL --- Jpeg target filter added." );
       
   270 
       
   271 	//	If external target size is given, set it to target.
       
   272 	if ( aSize )
       
   273 	{
       
   274 		iCmd.Format( _L("width %d height %d"), aSize->iWidth, aSize->iHeight );
       
   275 		iMainEngine->FunctionL ( iMainEngine->NumFilters() - 1, iCmd );
       
   276 	}
       
   277 
       
   278 	//	Set the scaled source size to target
       
   279 	if ( iSysPars->Scale() != 1.0 )
       
   280 	{
       
   281 		TReal scale = iSysPars->Scale();
       
   282 		TSize tgtsize = iMainEngine->Filter ( iMainEngine->NumFilters() - 3 )->ViewPortSize();
       
   283 		tgtsize.iWidth = (TInt)(tgtsize.iWidth * scale + 0.5);
       
   284 		tgtsize.iHeight = (TInt)(tgtsize.iHeight * scale + 0.5);
       
   285 		iCmd.Format( _L("width %d height %d"), tgtsize.iWidth, tgtsize.iHeight);
       
   286 		iMainEngine->FunctionL ( iMainEngine->NumFilters() - 1, iCmd );
       
   287 		iMainEngine->FunctionL ( iMainEngine->NumFilters() - 2, _L("nop"));
       
   288 	}
       
   289 	
       
   290 	//	Store save file name
       
   291 	iTargetFile.Copy ( aFileName );
       
   292 	
       
   293     LOG ( KEngineWrapperLogFile, "CreateJpegTargetL: Sink created" );
       
   294 }
       
   295 
       
   296 //=============================================================================
       
   297 EXPORT_C void CEngineWrapper::CreateIclSourceL (const TDesC & aFileName)
       
   298 {
       
   299 
       
   300     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateIclSourceL" );
       
   301 #ifdef VERBOSE
       
   302     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::CreateIclSourceL\taFileName: %S", &aFileName );
       
   303 #endif // VERBOSE
       
   304 
       
   305     //  SANITY CHECKS
       
   306     if ( !iMainEngine )
       
   307     {
       
   308         LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateIclSourceL: iMainEngine not created!" );
       
   309         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   310     }
       
   311 
       
   312 	//	Add JPEG source to engine
       
   313 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateIclSourceL --- Add icl source" );
       
   314 	if ( iMainEngine->NumFilters() == 0 )
       
   315 	{
       
   316 		iMainEngine->AddFilterL ( KFilterIclSource );
       
   317 	}
       
   318 	else if  ( IsSameString ( (TUint8*)iMainEngine->Filter(0)->Type(), (TUint8*)"jpegsource" ) )
       
   319 	{
       
   320 		iMainEngine->RemoveFilter(0);
       
   321 		iMainEngine->AddFilterL ( KFilterIclSource, 0);
       
   322 	}
       
   323 	else if  ( !IsSameString ( (TUint8*)iMainEngine->Filter(0)->Type(), (TUint8*)"iclsource" ) )
       
   324 	{
       
   325 		iMainEngine->AddFilterL ( KFilterIclSource, 0);
       
   326 	}
       
   327 	iCmd.Copy (_L("file \""));
       
   328 	iCmd.Append ( aFileName );
       
   329 	iCmd.Append (_L("\""));
       
   330 	LOGFMT ( KEngineWrapperLogFile, "CEngineWrapper::CreateIclSourceL: Cmd: %S", &iCmd );
       
   331 	iMainEngine->FunctionL ( 0, iCmd );
       
   332 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateIclSourceL --- Icl source added" );
       
   333 	iMainEngine->FunctionL ( 0, _L("loadimage"));
       
   334 
       
   335 	//	Get source image size
       
   336 	TRect rect = iMainEngine->Filter (0)->Rect(); 
       
   337 	iSourceSize = iMainEngine->Filter (0)->ViewPortSize(); 
       
   338 	LOGFMT ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL: source width: %d", iSourceSize.iWidth);
       
   339 	LOGFMT ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL: source height: %d", iSourceSize.iHeight);
       
   340 
       
   341     //  Check that the source image is of minimum size
       
   342     if (iSourceSize.iWidth < KObMinSourceDimension || iSourceSize.iHeight < KObMinSourceDimension)
       
   343     {
       
   344         User::Leave (KSIEEOpenFile);
       
   345     }
       
   346 
       
   347 	//	Initialize crop parameters
       
   348     iScale = 1.0;
       
   349     iMaxScale = 1.0;
       
   350     iMinScale = (TReal)iScreenSize.iWidth / iSourceSize.iWidth; 
       
   351     iPanX = iSourceSize.iWidth * 0.5;
       
   352     iPanY = iSourceSize.iHeight * 0.5;
       
   353     iPanStep = 128.0;
       
   354     iZoomMode = EZoomNormal;
       
   355     
       
   356 	//	Initialize system parameters
       
   357     iSysPars->SourceSize() = iSourceSize;
       
   358     iSysPars->Scale() = 1.0;
       
   359     
       
   360 
       
   361 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateIclSourceL ---  Create EXIF parser" );
       
   362 
       
   363 	if (iExifParser)
       
   364 	{
       
   365 		delete iExifParser;
       
   366 		iExifParser = NULL;		
       
   367 	}
       
   368 
       
   369 	iExifParser = CExifParser::NewL ();
       
   370 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateJpegSourceL --- EXIF parser created." );
       
   371 
       
   372     
       
   373 }
       
   374 
       
   375 //=============================================================================
       
   376 EXPORT_C void CEngineWrapper::CreateRGB888TargetL ()
       
   377 {
       
   378 
       
   379     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL " );
       
   380 
       
   381     //  SANITY CHECKS
       
   382     if ( !iMainEngine )
       
   383     {
       
   384         LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL: iMainEngine not created!" );
       
   385         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   386     }
       
   387 
       
   388 #ifdef VERBOSE
       
   389     LOGFMT( KEngineWrapperLogFile, "\tiScreenSize.w: %d", iScreenSize.iWidth);
       
   390     LOGFMT( KEngineWrapperLogFile, "\tiScreenSize.h: %d", iScreenSize.iHeight);
       
   391 #endif
       
   392 	
       
   393 	//	Create source buffer
       
   394 	iMainEngine->FunctionL (0, _L("bufferoutput"));
       
   395 	
       
   396 	//	Remove target filter and add screen buffer
       
   397     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL --- Add buffer target." );
       
   398     TInt n = iMainEngine->NumFilters();
       
   399 	if ( IsSameString ( (TUint8*)iMainEngine->Filter(n - 1)->Type(), (TUint8*)"jpegtarget") ) 
       
   400 	{
       
   401 		iMainEngine->RemoveFilter(n - 1);	
       
   402 		iMainEngine->AddFilterL ( KFilterBuffer );
       
   403 	}
       
   404 	else if ( !IsSameString ( (TUint8*)iMainEngine->Filter(n - 1)->Type(), (TUint8*)"buffer" ) )
       
   405 	{
       
   406 		iMainEngine->AddFilterL ( KFilterBuffer );
       
   407 	}
       
   408     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL --- Buffer target added." );
       
   409 	
       
   410 	//	Set buffer size
       
   411     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL --- Set buffer size ");
       
   412 	iCmd.Format( _L("width %d height %d"), iScreenSize.iWidth, iScreenSize.iHeight );
       
   413 	LOGDES (KEngineWrapperLogFile, iCmd);
       
   414 	iMainEngine->FunctionL ( iMainEngine->NumFilters() - 1, iCmd );
       
   415     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL --- Buffer size set." );
       
   416 
       
   417 	//	Set scale buffer before screen buffer
       
   418     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL --- Add screen buffer scale filter");
       
   419 	if ( !IsSameString ( (TUint8*)iMainEngine->Filter(iMainEngine->NumFilters() - 2)->Type(), (TUint8*)"scale") ) 
       
   420 	{
       
   421 		iMainEngine->AddFilterL ( KFilterScale, iMainEngine->NumFilters() - 1);
       
   422 	}
       
   423 	iMainEngine->FunctionL ( iMainEngine->NumFilters() - 2, iCmd );
       
   424     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL --- Screen buffer scale filter added.");
       
   425 
       
   426     LOG ( KEngineWrapperLogFile, "CEngineWrapper::CreateRGB888TargetL: Sink created" );
       
   427 }
       
   428 
       
   429 //=============================================================================
       
   430 EXPORT_C void CEngineWrapper::SetScreenSizeL (const TSize & aSize)
       
   431 {
       
   432 
       
   433     LOG ( KEngineWrapperLogFile, "CEngineWrapper::SetScreenSizeL" );
       
   434 #ifdef VERBOSE
       
   435     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::SetScreenSizeL\taSize.iWidth: %d", aSize.iWidth );
       
   436     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::SetScreenSizeL\taSize.iHeight: %d", aSize.iHeight );
       
   437 #endif // VERBOSE
       
   438 
       
   439     //  SANITY CHECKS
       
   440     if ( aSize.iWidth < 0 || aSize.iHeight < 0)
       
   441     {
       
   442         LOG ( KEngineWrapperLogFile, "CEngineWrapper::SetScreenSizeL: Invalid parameter aSize!" );
       
   443         User::Panic (KEnginePanic, KEnginePanicParameter);
       
   444     }
       
   445 
       
   446 	if ( aSize != iScreenSize )
       
   447 	{
       
   448 		iScreenSize = aSize;
       
   449 
       
   450 		//	Set buffer size
       
   451 		TInt n = iMainEngine->NumFilters();
       
   452 		if (n > 2)
       
   453 		{
       
   454 			if ( IsSameString ((TUint8*)iMainEngine->Filter(n - 1)->Type(), (TUint8*) "buffer" ) )
       
   455 			{
       
   456 				iCmd.Format( _L("width %d height %d"), iScreenSize.iWidth, iScreenSize.iHeight);
       
   457 				iMainEngine->FunctionL ( n - 1, iCmd );
       
   458 				iMainEngine->FunctionL ( n - 2, _L("nop"));
       
   459 				UpdateCropRectL();
       
   460 			}
       
   461 		}
       
   462 	}
       
   463 }
       
   464 
       
   465 //=============================================================================
       
   466 EXPORT_C void CEngineWrapper::AddFilterL (const TDesC & aFilterName) 
       
   467 {
       
   468     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::AddFilterL (TDes & aFilterName: %S)", &aFilterName );
       
   469 
       
   470     //  SANITY CHECKS
       
   471     if ( !iMainEngine )
       
   472     {
       
   473         LOG ( KEngineWrapperLogFile, "CEngineWrapper::AddFilterL: iMainEngine not created!" );
       
   474         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   475     }
       
   476 
       
   477 	//  Check whether the filter is found
       
   478 	TFileName filtername;
       
   479 	filtername.Copy (aFilterName);
       
   480     
       
   481     /*
       
   482     // no need for this as AddFilterL will leave if there is an error
       
   483     if (FileExists (filtername) )
       
   484     {
       
   485            TParse parse;
       
   486            User::LeaveIfError( parse.Set( aFilterName ,NULL, NULL ) );
       
   487            filtername = parse.NameAndExt();
       
   488     };
       
   489     */
       
   490 
       
   491 	TInt n = iMainEngine->NumFilters();
       
   492 	if (n >= 2)
       
   493 	{
       
   494 		iMainEngine->AddFilterL ( filtername, n - 2 );
       
   495 	}
       
   496     LOG ( KEngineWrapperLogFile, "CEngineWrapper::AddFilterL: Filter added" );
       
   497 }
       
   498 
       
   499 //=============================================================================
       
   500 EXPORT_C void CEngineWrapper::SetParamsL (const TDesC & aParam)
       
   501 {
       
   502     LOG( KEngineWrapperLogFile, "CEngineWrapper::SetParamsL " );
       
   503 
       
   504     //  SANITY CHECKS
       
   505     if ( !iMainEngine )
       
   506     {
       
   507         LOG ( KEngineWrapperLogFile, "CEngineWrapper::SetParamsL: iMainEngine not created!" );
       
   508         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   509     }
       
   510 
       
   511     //  Initialize error value
       
   512 	TInt n = iMainEngine->NumFilters();
       
   513 	if ( n > 2 )
       
   514 	{
       
   515     	LOGDES( KEngineWrapperLogFile, aParam );
       
   516 		iMainEngine->FunctionL ( n - 3, aParam );
       
   517 	}
       
   518 
       
   519 
       
   520 	if ( IsSameString ( (TUint8*)iMainEngine->Filter(n - 3)->Type(), (TUint8*) "rotate" ) )
       
   521 	{
       
   522 		if (iScale == 1.0)
       
   523 		{
       
   524 			ComputeBoundingRectL();	
       
   525 		}
       
   526 		UpdateCropRectL();
       
   527 	}
       
   528     
       
   529     
       
   530     LOG( KEngineWrapperLogFile, "CEngineWrapper::SetParamsL: Parameters set " );
       
   531 }
       
   532 
       
   533 //=============================================================================
       
   534 EXPORT_C void CEngineWrapper::RenderL (TInt* /*aMultiSessionBlockCount*/)
       
   535 {
       
   536     LOG( KEngineWrapperLogFile, "CEngineWrapper::RenderL" );
       
   537 
       
   538     //  SANITY CHECKS
       
   539     if ( !iMainEngine )
       
   540     {
       
   541         LOG ( KEngineWrapperLogFile, "CEngineWrapper::RenderL: iMainEngine not created!" );
       
   542         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   543     }
       
   544 
       
   545 	TInt n = iMainEngine->NumFilters();
       
   546 	for ( TInt i = 0; i < iMainEngine->NumFilters(); ++i)
       
   547 	{
       
   548 		iMainEngine->FunctionL (i, _L("nop"));
       
   549 		TBuf<100> buf;
       
   550 		buf.Copy(TPtrC8 ( (TUint8 *)iMainEngine->Filter(i)->Type() ));
       
   551 		LOGDES (KEngineWrapperLogFile,  buf) ;
       
   552 		TRect rect = iMainEngine->Filter(i)->Rect();
       
   553 		buf.Format( _L("%d %d %d %d"), rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);
       
   554 		LOGDES (KEngineWrapperLogFile,  buf) ;
       
   555 	}
       
   556 
       
   557 	//	Render to buffer target
       
   558 	if ( IsSameString ( (TUint8*)iMainEngine->Filter(n - 1)->Type(), (TUint8*) "buffer" ) )
       
   559 	{
       
   560 		iCmd.Copy (_L("getbitmap"));
       
   561 		if ( iRenderScaleBuffer )
       
   562 		{
       
   563 			iMainEngine->FunctionL ( 0, _L("loadimage"));
       
   564 			iRenderScaleBuffer = EFalse;
       
   565 			for ( TInt i = 0; i < iMainEngine->NumFilters(); ++i)
       
   566 			{
       
   567 				iMainEngine->FunctionL (i, _L("nop"));
       
   568 			}
       
   569 		}
       
   570 
       
   571 
       
   572 		LOG ( KEngineWrapperLogFile, "CEngineWrapper::RenderL -- Render screen buffer." );
       
   573 		TUint32 * buffer = (TUint32 *)iMainEngine->FunctionL ( n - 1, iCmd );
       
   574 		CopyBufferL (buffer);
       
   575 	}
       
   576 
       
   577 	//	Render to JPEG target
       
   578 	else if ( IsSameString ( (TUint8*)iMainEngine->Filter(n - 1)->Type(), (TUint8*)"jpegtarget" ) )
       
   579 	{
       
   580 		iCmd.Zero();
       
   581 		
       
   582 
       
   583 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::RenderL: Set EXIF data" );
       
   584 		
       
   585 		//	Update EXIF tags
       
   586 		UpdateExifTagsL();
       
   587 
       
   588 		//	Update EXIF thumbnail 
       
   589 		TPtrC8 savedexifdata = UpdateExifThumbnailL();
       
   590 
       
   591 		//	Set EXIF data to target
       
   592 		iCmd.Format (_L("exifdata %d exiflen %d"), (TInt)(savedexifdata.Ptr()), savedexifdata.Length());
       
   593 
       
   594 	LOG ( KEngineWrapperLogFile, "CEngineWrapper::RenderL: EXIF data set." );
       
   595 
       
   596 		
       
   597 		iCmd.Append (_L(" file \""));
       
   598 		iCmd.Append ( iTargetFile );
       
   599 		iCmd.Append (_L("\""));
       
   600 		iMainEngine->FunctionL ( n - 1, iCmd );
       
   601 	}
       
   602 
       
   603     LOG( KEngineWrapperLogFile, "CEngineWrapper::RenderL: Rendered" );
       
   604 }
       
   605 
       
   606 //=============================================================================
       
   607 EXPORT_C TInt CEngineWrapper::RenderBlockL()
       
   608 {
       
   609 #ifdef VERBOSE_2
       
   610     LOG( KEngineWrapperLogFile, "CEngineWrapper::RenderBlockL" );
       
   611 
       
   612     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::RenderBlockL\tiBlock: %d", iBlock);
       
   613     if (iTestBitmap)
       
   614     {
       
   615         LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::RenderBlock\tiTestBitmap->DataAddress(): %d", (TInt)iTestBitmap->DataAddress());
       
   616         LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::RenderBlock\tiTestBitmap->Handle(): %d", iTestBitmap->Handle());
       
   617     }
       
   618     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::RenderBlockL\tiBuffer: %d", (TInt)iBuffer);
       
   619 #endif
       
   620 
       
   621 
       
   622     //  Check that the model is found
       
   623     if ( !iMainEngine )
       
   624     {
       
   625         LOG ( KEngineWrapperLogFile, "RenderBlockL: iMainEngine not created!" );
       
   626         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   627     }
       
   628 
       
   629 	iCmd.Copy ( _L("store") );
       
   630 	TInt percentage = iMainEngine->FunctionL ( iMainEngine->NumFilters() - 1, iCmd );
       
   631 	if (percentage == 100)
       
   632 	{
       
   633 		iChangeCount = 0;
       
   634 	}
       
   635 	return percentage;
       
   636 }
       
   637 
       
   638 //=============================================================================
       
   639 EXPORT_C void CEngineWrapper::RenderAbortL()
       
   640 {
       
   641 	LOG( KEngineWrapperLogFile, "CEngineWrapper::RenderAbortL" );
       
   642 
       
   643     //  Check that the model is found
       
   644     if ( !iMainEngine )
       
   645     {
       
   646         LOG ( KEngineWrapperLogFile, "RenderAbort: iMainEngine not created!" );
       
   647         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   648     }
       
   649     
       
   650     iCmd.Copy ( _L("abort"));
       
   651 	iMainEngine->FunctionL ( iMainEngine->NumFilters() - 1, iCmd );
       
   652 }
       
   653 
       
   654 //=============================================================================
       
   655 EXPORT_C void CEngineWrapper::InitUndoRedo()
       
   656 {
       
   657     LOG( KEngineWrapperLogFile, "CEngineWrapper::InitUndoRedo" );
       
   658 
       
   659     //  Check that the model is found
       
   660     if ( !iMainEngine )
       
   661     {
       
   662         LOG ( KEngineWrapperLogFile, "InitUndoRedo: iMainEngine not created!" );
       
   663         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   664     }
       
   665 
       
   666 	//	Purge undo stack
       
   667 	iUndoPoints.Reset();
       
   668 
       
   669 	//	Undo
       
   670 	iPrevChangeCount = 0;
       
   671     iChangeCount = 0;
       
   672 }
       
   673 
       
   674 //=============================================================================
       
   675 EXPORT_C void CEngineWrapper::AddUndoRedoStepL()
       
   676 {
       
   677     LOG( KEngineWrapperLogFile, "CEngineWrapper::AddUndoRedoStepL" );
       
   678 
       
   679     //  Check that the model is found
       
   680     if ( !iMainEngine )
       
   681     {
       
   682         LOG ( KEngineWrapperLogFile, "AddUndoRedoStepL: iMainEngine not created!" );
       
   683         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   684     }
       
   685 
       
   686 	//	Store undo point
       
   687 	TInt n = iMainEngine->NumFilters();
       
   688 	if (n > 2)
       
   689 	{
       
   690 		//	Set undo point before target filter
       
   691 		iUndoPoints.Append ( n - 3 );
       
   692 	}
       
   693 	
       
   694 	iPrevChangeCount = iChangeCount;
       
   695     iChangeCount++;
       
   696 
       
   697     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::AddUndoRedoStepL: iChangeCount = %d", iChangeCount);
       
   698     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::AddUndoRedoStepL: iPrevChangeCount = %d", iPrevChangeCount);
       
   699 
       
   700     //  Store rotation and scale
       
   701     User::LeaveIfError( iScaleUndoBuf.Append ( iSysPars->Scale() ) );
       
   702 }
       
   703 
       
   704 //=============================================================================
       
   705 EXPORT_C void CEngineWrapper::UndoL()
       
   706 {
       
   707     LOG( KEngineWrapperLogFile, "CEngineWrapper::UndoL" );
       
   708 
       
   709     //  Check that the model is found
       
   710     if ( !iMainEngine )
       
   711     {
       
   712         LOG ( KEngineWrapperLogFile, "UndoL: iMainEngine not created!" );
       
   713         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   714     }
       
   715 
       
   716 	TBool computeBoundingRect = EFalse;
       
   717 	TBool reloadImage = EFalse;
       
   718 
       
   719 	if (iMainEngine->NumFilters() > 2)
       
   720 	{
       
   721 		TInt m = iUndoPoints.Count();
       
   722 		TInt undoindex = iUndoPoints[m-1];
       
   723 		while (iMainEngine->NumFilters() - 3 > undoindex)
       
   724 		{
       
   725 			TInt index = iMainEngine->NumFilters() - 3;
       
   726 			if ( IsSameString ( (TUint8*)iMainEngine->Filter(index)->Type(), (TUint8*) "rotate" ) )
       
   727 				{
       
   728 				computeBoundingRect = ETrue;
       
   729 				}
       
   730 			else if ( IsSameString ( (TUint8*)iMainEngine->Filter(index)->Type(), (TUint8*) "crop" ) )
       
   731 				{
       
   732 				reloadImage = ETrue;
       
   733 				}
       
   734 		
       
   735 			iMainEngine->RemoveFilter (index);
       
   736 		}
       
   737 		iUndoPoints.Remove (iUndoPoints.Count() - 1);
       
   738 	}
       
   739 
       
   740     iPrevChangeCount = iChangeCount;
       
   741     iChangeCount--;
       
   742 
       
   743     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::UndoL: iChangeCount = %d", iChangeCount);
       
   744     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::UndoL: iPrevChangeCount = %d", iPrevChangeCount);
       
   745 
       
   746     TInt count = iScaleUndoBuf.Count();
       
   747     if ( count > 0 )
       
   748     {
       
   749         iSysPars->Scale() = iScaleUndoBuf[count - 1];
       
   750         iScaleUndoBuf.Remove (count - 1);
       
   751     }
       
   752 	
       
   753 	if (reloadImage)
       
   754 	{
       
   755 		iCmd.Format( _L("ulc %d ulr %d lrc %d lrr %d"), 0,0,0,0);
       
   756 		iMainEngine->FunctionL ( 0, iCmd);
       
   757 		iMainEngine->FunctionL ( 0, _L("loadimage"));
       
   758 		for (TInt i = 0; i < iMainEngine->NumFilters(); ++i)
       
   759 		{
       
   760 			iMainEngine->FunctionL (i, _L("nop"));
       
   761 		}
       
   762     	ComputeBoundingRectL();
       
   763 	}
       
   764 
       
   765     if (  iMainEngine->NumFilters() > 3 && computeBoundingRect && iScale == 1.0 )
       
   766     {
       
   767     	ComputeBoundingRectL();
       
   768     }
       
   769     else if ( iMainEngine->NumFilters() <= 3 )
       
   770     {
       
   771     	iBoundingRect.iTl.iX = 0;    
       
   772     	iBoundingRect.iTl.iY = 0;    
       
   773     	iBoundingRect.iBr.iX = iSourceSize.iWidth;    
       
   774     	iBoundingRect.iBr.iY = iSourceSize.iHeight;   
       
   775     }
       
   776     UpdateCropRectL();
       
   777 }
       
   778 
       
   779 //=============================================================================
       
   780 EXPORT_C TBool CEngineWrapper::CanUndo ()
       
   781 {
       
   782     LOG( KEngineWrapperLogFile, "CEngineWrapper::CanUndo" );
       
   783 
       
   784     //  Check that the model is found
       
   785     if ( !iMainEngine )
       
   786     {
       
   787         LOG ( KEngineWrapperLogFile, "CanUndo: iMainEngine not created!" );
       
   788         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   789     }
       
   790 
       
   791 	if ( iUndoPoints.Count() > 0 )
       
   792 	{
       
   793 		return ETrue;
       
   794 	}
       
   795 	else
       
   796 	{
       
   797 		return EFalse;
       
   798 	}
       
   799 }
       
   800 
       
   801 //=============================================================================
       
   802 EXPORT_C TBool CEngineWrapper::IsImageChanged()
       
   803 {
       
   804     LOGFMT2( KEngineWrapperLogFile, "CEngineWrapper::IsImageChanged: iChangeCount = %d, iPrevChangeCount = %d", iChangeCount, iPrevChangeCount );
       
   805 
       
   806     if ( iChangeCount || (iChangeCount == 0 && iPrevChangeCount < 0)) 
       
   807     {
       
   808         return ETrue;
       
   809     }
       
   810     else
       
   811     {
       
   812         return EFalse;
       
   813     }
       
   814 }
       
   815 
       
   816 //=============================================================================
       
   817 CEngineWrapper::CEngineWrapper () : 
       
   818 iScreenSize (),
       
   819 iChangeCount(0),
       
   820 iPrevChangeCount(0)
       
   821 {
       
   822 
       
   823 }
       
   824 
       
   825 //=============================================================================
       
   826 void CEngineWrapper::ConstructL ()
       
   827 {
       
   828     LOG( KEngineWrapperLogFile, "CEngineWrapper::ConstructL" );
       
   829 
       
   830 	//	Create new engine
       
   831 	iMainEngine = CFilterStack::NewL();
       
   832 
       
   833     // Set screen size to default
       
   834     iScreenSize.iWidth = 1;
       
   835     iScreenSize.iHeight = 1;
       
   836 
       
   837     //  Create and initialize system parameters
       
   838 	LOG( KEngineWrapperLogFile, "CEngineWrapper: Creating system parameters" );
       
   839     iSysPars = new (ELeave) CSystemParameters;
       
   840 }
       
   841 
       
   842 //=============================================================================
       
   843 TInt CEngineWrapper::FileExists (TDes & aFileName) const
       
   844 {
       
   845     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::FileExists (TDes & aFileName: %S)", &aFileName );
       
   846 
       
   847 	TInt result = KErrNone;
       
   848 
       
   849 	RFs &fs = CEikonEnv::Static()->FsSession();
       
   850 	
       
   851 	aFileName[0] = 'e';
       
   852 	if ( !BaflUtils::FileExists (fs, aFileName) )
       
   853 	{
       
   854 		aFileName[0] = 'c';
       
   855 		if ( !BaflUtils::FileExists (fs, aFileName) )
       
   856 		{
       
   857 			aFileName[0] = 'z';
       
   858 			if ( !BaflUtils::FileExists (fs, aFileName) )
       
   859 			{
       
   860 				return KErrNotFound;
       
   861 			}
       
   862 		}
       
   863 	}
       
   864 
       
   865 	if ( !BaflUtils::FileExists (fs, aFileName) )
       
   866 	{
       
   867 		result = KErrNotFound;
       
   868 	}
       
   869 
       
   870 	LOGFMT( KEngineWrapperLogFile, "\tresult: %d", result );
       
   871 
       
   872 	return result;
       
   873 }
       
   874 
       
   875 //=============================================================================
       
   876 void CEngineWrapper::Cleanup()
       
   877 {
       
   878     LOG( KEngineWrapperLogFile, "CEngineWrapper::Cleanup" );
       
   879 
       
   880 	//	Purge undo / redo information
       
   881 	iUndoPoints.Reset();
       
   882 	
       
   883 	//	Delete filters
       
   884 	for ( TInt i = 0; i < iMainEngine->NumFilters(); ++i)
       
   885 	{
       
   886 		iMainEngine->RemoveFilter(i);	
       
   887 	}
       
   888 	
       
   889 	//	Delete engine
       
   890 	if (iMainEngine)
       
   891 	{
       
   892 		delete iMainEngine;	
       
   893 		iMainEngine = NULL;
       
   894 	}
       
   895 	
       
   896     //  Clear rotation and scale undo buffers
       
   897     iScaleUndoBuf.Reset();
       
   898 
       
   899     //  Delete system parameters
       
   900     if (iSysPars)
       
   901     {
       
   902     	delete iSysPars;	
       
   903     	iSysPars = NULL;
       
   904     }
       
   905     
       
   906     if (iJpegComment)
       
   907     {
       
   908     	delete iJpegComment;	
       
   909     	iJpegComment = NULL;
       
   910     }
       
   911     
       
   912     //	Delete thumbnail buffer
       
   913     delete[] iThumb;
       
   914 }
       
   915   
       
   916 //=============================================================================
       
   917 EXPORT_C void CEngineWrapper::StoreZoomL ()
       
   918 {
       
   919     LOG( KEngineWrapperLogFile, "CEngineWrapper::StoreZoom" );
       
   920 
       
   921 	iScaleSt = iScale;
       
   922 	iPanXSt = iPanX;
       
   923 	iPanYSt = iPanY;
       
   924 	
       
   925 	iScale = 1.0;
       
   926     iPanX = iSourceSize.iWidth * 0.5;
       
   927     iPanY = iSourceSize.iHeight * 0.5;
       
   928     UpdateCropRectL();
       
   929 }
       
   930 
       
   931 //=============================================================================
       
   932 EXPORT_C void CEngineWrapper::RestoreZoomL()
       
   933 {
       
   934     LOG( KEngineWrapperLogFile, "CEngineWrapper::RestoreZoom" );
       
   935 
       
   936 	if (iScale != iScaleSt)
       
   937 	{
       
   938 		iScale = iScaleSt;
       
   939 		iPanX = iPanXSt;
       
   940 		iPanY = iPanYSt;
       
   941 	    UpdateCropRectL();		
       
   942 	}
       
   943 }
       
   944 
       
   945 //=============================================================================
       
   946 EXPORT_C void CEngineWrapper::ZoomL (const TZoom aZoom)
       
   947     {
       
   948     LOGFMT( KEngineWrapperLogFile, "CEngineWrapper::ZoomL: %d", (TInt)aZoom);
       
   949 
       
   950     //  Check that the model is found
       
   951     if ( !iMainEngine )
       
   952         {
       
   953         LOG ( KEngineWrapperLogFile, "ZoomFactor: iMainEngine not created!" );
       
   954         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
   955         }
       
   956 
       
   957 	if ( aZoom == EZoomMin )
       
   958     	{
       
   959     	iScale = 1.0;
       
   960         iZoomMode = EZoomNormal;
       
   961 	    
       
   962 	    }
       
   963 	else if ( aZoom == EZoomIn )
       
   964 	    {
       
   965 
       
   966         if ( iScale == 1.0 )
       
   967             {
       
   968         	ComputeBoundingRectL();
       
   969             }
       
   970         
       
   971         if ( iZoomMode < ( ENumOfZooms - 1 ) )
       
   972             {
       
   973             // rescale
       
   974             iScale *= KZoomScaleFactor;
       
   975             // set next zoom mode
       
   976             iZoomMode = ( TZoomMode )( ( TInt )iZoomMode + 1 );
       
   977             }
       
   978 	    }
       
   979 	else
       
   980 	    {	
       
   981 	    if ( iZoomMode > EZoomNormal )
       
   982             {
       
   983             // rescale
       
   984             iScale *= 1.0 / KZoomScaleFactor;
       
   985             //set previous zoom mode	
       
   986             iZoomMode = ( TZoomMode )( ( TInt )iZoomMode - 1 );
       
   987 	        }
       
   988 	    }
       
   989 	    
       
   990 	UpdateCropRectL();
       
   991     }
       
   992     
       
   993 //=============================================================================
       
   994 EXPORT_C TZoomMode CEngineWrapper::GetZoomMode()
       
   995     {
       
   996     return iZoomMode;
       
   997     }
       
   998     
       
   999 //=============================================================================
       
  1000 EXPORT_C void CEngineWrapper::PanL (const TDirection aDir)
       
  1001 {
       
  1002     LOG( KEngineWrapperLogFile, "CEngineWrapper::PanL" );
       
  1003 
       
  1004 #ifdef VERBOSE
       
  1005     LOGFMT( KEngineWrapperLogFile, "\taDir: %d", (TInt)aDir);
       
  1006 #endif // VERBOSE
       
  1007 
       
  1008     if (iScale == 1.0)
       
  1009     {
       
  1010         return;
       
  1011     }
       
  1012 
       
  1013     //  Check that the model is found
       
  1014     if ( !iMainEngine )
       
  1015     {
       
  1016         LOG ( KEngineWrapperLogFile, "SetPanL: iMainEngine not created!" );
       
  1017         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
  1018     }
       
  1019 
       
  1020     TInt angle = ComputeRotationL();
       
  1021 
       
  1022 	switch (aDir)
       
  1023 	{
       
  1024 		case EDirectionUp:
       
  1025 		{
       
  1026 			if (angle == 0)
       
  1027 			{
       
  1028     			iPanY -= iPanStep  * iScale;
       
  1029 			}
       
  1030 			else if (angle == 90)
       
  1031 			{
       
  1032     			iPanX -= iPanStep  * iScale;
       
  1033 			}
       
  1034 			else if (angle == 180)
       
  1035 			{
       
  1036     			iPanY += iPanStep  * iScale;
       
  1037 			}
       
  1038 			else if (angle == 270)
       
  1039 			{
       
  1040     			iPanX += iPanStep  * iScale;
       
  1041 			}
       
  1042 			break;
       
  1043 		}
       
  1044 		case EDirectionDown:
       
  1045 		{
       
  1046 			if (angle == 0)
       
  1047 			{
       
  1048     			iPanY += iPanStep  * iScale;
       
  1049 			}
       
  1050 			else if (angle == 90)
       
  1051 			{
       
  1052     			iPanX += iPanStep  * iScale;
       
  1053 			}
       
  1054 			else if (angle == 180)
       
  1055 			{
       
  1056     			iPanY -= iPanStep  * iScale;
       
  1057 			}
       
  1058 			else if (angle == 270)
       
  1059 			{
       
  1060     			iPanX -= iPanStep  * iScale;
       
  1061 			}
       
  1062 			break;
       
  1063 		}
       
  1064 		case EDirectionLeft:
       
  1065 		{
       
  1066 			if (angle == 0)
       
  1067 			{
       
  1068     			iPanX -= iPanStep * iScale;
       
  1069 			}
       
  1070 			else if (angle == 90)
       
  1071 			{
       
  1072     			iPanY += iPanStep * iScale;
       
  1073 			}
       
  1074 			else if (angle == 180)
       
  1075 			{
       
  1076     			iPanX += iPanStep * iScale;
       
  1077 			}
       
  1078 			else if (angle == 270)
       
  1079 			{
       
  1080     			iPanY -= iPanStep * iScale;
       
  1081 			}
       
  1082 			break;
       
  1083 		}
       
  1084 		case EDirectionRight:
       
  1085 		{
       
  1086 			if (angle == 0)
       
  1087 			{
       
  1088     			iPanX += iPanStep  * iScale;
       
  1089 			}
       
  1090 			else if (angle == 90)
       
  1091 			{
       
  1092     			iPanY -= iPanStep * iScale;
       
  1093 			}
       
  1094 			else if (angle == 180)
       
  1095 			{
       
  1096     			iPanX -= iPanStep * iScale;
       
  1097 			}
       
  1098 			else if (angle == 270)
       
  1099 			{
       
  1100     			iPanY += iPanStep * iScale;
       
  1101 			}
       
  1102 			break;
       
  1103 		}
       
  1104 		default:
       
  1105 			break;
       
  1106 	}
       
  1107 	UpdateCropRectL();
       
  1108 
       
  1109 }
       
  1110 
       
  1111 //=============================================================================
       
  1112 EXPORT_C void CEngineWrapper::PanL( TInt aXChange, TInt aYChange )
       
  1113     {
       
  1114     LOG( KEngineWrapperLogFile, "CEngineWrapper::Pan" );
       
  1115 
       
  1116 #ifdef VERBOSE
       
  1117     LOGFMT( KEngineWrapperLogFile, "\taXChange: %d, aYChange: %d ", aXChange, aYChange );
       
  1118 #endif // VERBOSE
       
  1119 
       
  1120     if (iScale == 1.0)
       
  1121         {
       
  1122         return;
       
  1123         }
       
  1124 
       
  1125     //  Check that the model is found
       
  1126     if ( !iMainEngine )
       
  1127         {
       
  1128         LOG ( KEngineWrapperLogFile, "SetPanL: iMainEngine not created!" );
       
  1129         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
  1130         }
       
  1131 
       
  1132     TInt angle = ComputeRotationL();
       
  1133 
       
  1134     if (angle == 0)
       
  1135 		{
       
  1136 		// X change
       
  1137         iPanX += aXChange*(iScale/iMinScale);
       
  1138 
       
  1139         // Y change
       
  1140         iPanY += aYChange*(iScale/iMinScale);
       
  1141    		}
       
  1142 	else if (angle == 90)
       
  1143 		{
       
  1144 		// X change
       
  1145         iPanX += aYChange*(iScale/iMinScale);
       
  1146 
       
  1147         // Y change
       
  1148         iPanY -= aXChange*(iScale/iMinScale);
       
  1149 		}
       
  1150 	else if (angle == 180)
       
  1151 		{
       
  1152 		// X change
       
  1153         iPanX -= aXChange*(iScale/iMinScale);
       
  1154 
       
  1155         // Y change
       
  1156         iPanY -= aYChange*(iScale/iMinScale);
       
  1157 		}
       
  1158 	else if (angle == 270)
       
  1159 		{
       
  1160 		// X change
       
  1161         iPanX -= aYChange*(iScale/iMinScale);
       
  1162 
       
  1163         // Y change
       
  1164         iPanY += aXChange*(iScale/iMinScale);
       
  1165 		}			
       
  1166 
       
  1167 	UpdateCropRectL();
       
  1168 
       
  1169 }
       
  1170 
       
  1171 //=============================================================================
       
  1172 EXPORT_C void CEngineWrapper::RotateL (const TRotation aRot)
       
  1173 {
       
  1174     LOG( KEngineWrapperLogFile, "CEngineWrapper::RotateL" );
       
  1175 #ifdef VERBOSE
       
  1176     LOGFMT( KEngineWrapperLogFile, "\taRot: %d", (TInt)aRot);
       
  1177 #endif // VERBOSE
       
  1178 
       
  1179     //  Check that the model is found
       
  1180     if ( !iMainEngine )
       
  1181     {
       
  1182         LOG ( KEngineWrapperLogFile, "Rotation: iMainEngine not created!" );
       
  1183         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
  1184     }
       
  1185 
       
  1186     //  Set undo / redo point
       
  1187     AddUndoRedoStepL ();
       
  1188 
       
  1189     //  Add rotate filter
       
  1190     AddRotateFilterL();
       
  1191 
       
  1192     //  Set rotation pars
       
  1193     TBuf<128> cmd;
       
  1194 	cmd.Copy (_L("angle "));
       
  1195     
       
  1196     if ( ERotationCounterClockwise == aRot )
       
  1197     {
       
  1198 		cmd.AppendNum (270);
       
  1199     }
       
  1200     else if ( ERotationClockwise == aRot )
       
  1201     {
       
  1202 		cmd.AppendNum (90);
       
  1203     }
       
  1204     else if ( ERotation180 == aRot )
       
  1205     {
       
  1206 		cmd.AppendNum (180);
       
  1207     }
       
  1208     else
       
  1209     {
       
  1210         User::Leave (KErrArgument);
       
  1211     }
       
  1212     SetParamsL (cmd);
       
  1213 }
       
  1214 
       
  1215 //=============================================================================
       
  1216 EXPORT_C CSystemParameters * CEngineWrapper::GetSystemPars ()
       
  1217 {
       
  1218 	LOG( KEngineWrapperLogFile, "CEngineWrapper::GetSystemPars" );
       
  1219 
       
  1220 	ComputeSystemParameters();
       
  1221 	
       
  1222     return iSysPars;
       
  1223 }
       
  1224 
       
  1225 //=============================================================================
       
  1226 void CEngineWrapper::ComputeSystemParameters ()
       
  1227 {
       
  1228 	LOG( KEngineWrapperLogFile, "CEngineWrapper::ComputeSystemParameters" );
       
  1229 	
       
  1230 	    //  Check that the model is found
       
  1231     if ( !iMainEngine )
       
  1232     {
       
  1233         LOG ( KEngineWrapperLogFile, "GetSystemPars: iMainEngine not created!" );
       
  1234         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
  1235     }
       
  1236 
       
  1237 	MImageFilter * filter = iMainEngine->Filter(iMainEngine->NumFilters() - 3);
       
  1238 	TSize size = filter->ViewPortSize();
       
  1239 	iSysPars->ViewPortRect().iTl.iX = 0;
       
  1240 	iSysPars->ViewPortRect().iTl.iY = 0;
       
  1241 	iSysPars->ViewPortRect().iBr.iX = size.iWidth;
       
  1242 	iSysPars->ViewPortRect().iBr.iY = size.iHeight;
       
  1243 
       
  1244     LOGFMT( KEngineWrapperLogFile, "ViewPortRect().iTl.iX: %d", iSysPars->ViewPortRect().iTl.iX );
       
  1245     LOGFMT( KEngineWrapperLogFile, "ViewPortRect().iTl.iY: %d", iSysPars->ViewPortRect().iTl.iY );
       
  1246     LOGFMT( KEngineWrapperLogFile, "ViewPortRect().iBr.iX: %d", iSysPars->ViewPortRect().iBr.iX );
       
  1247     LOGFMT( KEngineWrapperLogFile, "ViewPortRect().iBr.iY: %d", iSysPars->ViewPortRect().iBr.iY );
       
  1248 
       
  1249 	iSysPars->VisibleImageRect() = filter->Rect();
       
  1250 
       
  1251     LOGFMT( KEngineWrapperLogFile, "VisibleImageRect().iTl.iX: %d", iSysPars->VisibleImageRect().iTl.iX );
       
  1252     LOGFMT( KEngineWrapperLogFile, "VisibleImageRect().iTl.iY: %d", iSysPars->VisibleImageRect().iTl.iY );
       
  1253     LOGFMT( KEngineWrapperLogFile, "VisibleImageRect().iBr.iX: %d", iSysPars->VisibleImageRect().iBr.iX );
       
  1254     LOGFMT( KEngineWrapperLogFile, "VisibleImageRect().iBr.iY: %d", iSysPars->VisibleImageRect().iBr.iY );
       
  1255 
       
  1256     // Get the relative scale of the topmost filter
       
  1257     iSysPars->RelScale() = filter->Scale();
       
  1258 
       
  1259 	LOGFMT( KEngineWrapperLogFile, "RelScale(): %f", iSysPars->RelScale() );
       
  1260 
       
  1261 	TInt n = iMainEngine->NumFilters();
       
  1262 	if ( n > 3 )
       
  1263 	{
       
  1264 	
       
  1265 		TRect rect;
       
  1266 	
       
  1267 		TSize srcsize = iMainEngine->Filter(n - 3)->Rect().Size();
       
  1268 		TSize tgtsize = iMainEngine->Filter(n - 1)->Rect().Size();
       
  1269 
       
  1270 		//	Compute aspect ratio of the source
       
  1271 		TInt ars = (TReal)(srcsize.iWidth << KScaleBits) / srcsize.iHeight + 0.5;
       
  1272 
       
  1273 		//	Compute aspect ratio of the target
       
  1274 		TInt art = (TReal)(tgtsize.iWidth << KScaleBits) / tgtsize.iHeight + 0.5;
       
  1275 
       
  1276 		//	Select scale so that aspect ratio is preserved
       
  1277 		if ( ars >= art )
       
  1278 		{
       
  1279 			TInt scale = (TReal)(tgtsize.iWidth << KScaleBits) / srcsize.iWidth + 0.5;
       
  1280 			rect.iTl.iX = 0;
       
  1281 			rect.iBr.iX = tgtsize.iWidth;
       
  1282 			TInt h = (srcsize.iHeight * scale) >> KScaleBits;
       
  1283 			rect.iTl.iY = (TReal)(tgtsize.iHeight - h) / 2 + 0.5;
       
  1284 			rect.iBr.iY = (TReal)(tgtsize.iHeight + h) / 2 + 0.5;
       
  1285 		}
       
  1286 		else
       
  1287 		{
       
  1288 			TInt scale = (TReal)(tgtsize.iHeight << KScaleBits) / srcsize.iHeight + 0.5;
       
  1289 			rect.iTl.iY = 0;
       
  1290 			rect.iBr.iY = tgtsize.iHeight;
       
  1291 			TInt w = (srcsize.iWidth * scale) >> KScaleBits;
       
  1292 			rect.iTl.iX = (TReal)(tgtsize.iWidth - w) / 2 + 0.5;
       
  1293 			rect.iBr.iX = (TReal)(tgtsize.iWidth + w) / 2 + 0.5;
       
  1294 		}
       
  1295    	
       
  1296 		iSysPars->VisibleImageRectPrev() = rect;
       
  1297    		
       
  1298 	    LOGFMT( KEngineWrapperLogFile, "VisibleImageRectPrev().iTl.iX: %d", iSysPars->VisibleImageRectPrev().iTl.iX );
       
  1299 	    LOGFMT( KEngineWrapperLogFile, "VisibleImageRectPrev().iTl.iY: %d", iSysPars->VisibleImageRectPrev().iTl.iY );
       
  1300 	    LOGFMT( KEngineWrapperLogFile, "VisibleImageRectPrev().iBr.iX: %d", iSysPars->VisibleImageRectPrev().iBr.iX );
       
  1301 	    LOGFMT( KEngineWrapperLogFile, "VisibleImageRectPrev().iBr.iY: %d", iSysPars->VisibleImageRectPrev().iBr.iY );
       
  1302 	}
       
  1303 }
       
  1304 
       
  1305 
       
  1306 
       
  1307 //=============================================================================
       
  1308 EXPORT_C void CEngineWrapper::GetOutputImageSize ( TInt& /*aWidth*/, TInt& /*aHeight*/ ) const
       
  1309 {
       
  1310 
       
  1311 }
       
  1312 
       
  1313 //=============================================================================
       
  1314 EXPORT_C void CEngineWrapper::SetJpegCommentL (const TDesC8& /*aComment*/)
       
  1315 {
       
  1316     LOG ( KEngineWrapperLogFile, "CEngineWrapper::SetJpegComment" );
       
  1317 
       
  1318     //  Check that the model is found
       
  1319     if ( !iMainEngine )
       
  1320     {
       
  1321         LOG ( KEngineWrapperLogFile, "SetJpegComment: iMainEngine not created!" );
       
  1322         User::Panic (KEnginePanic, KEnginePanicAllocation);
       
  1323     }
       
  1324 }
       
  1325 
       
  1326 //=============================================================================
       
  1327 void CEngineWrapper::AddRotateFilterL()
       
  1328 {
       
  1329     LOG ( KEngineWrapperLogFile, "CEngineWrapper::AddRotateFilterL()" );
       
  1330 
       
  1331     //  Add filter to engine
       
  1332     AddFilterL (KFilterRotate);
       
  1333 }
       
  1334 
       
  1335 //=============================================================================
       
  1336 TRect CEngineWrapper::ComputeViewPort (const TInt /*aStartInd*/)
       
  1337 {
       
  1338     LOG ( KEngineWrapperLogFile, "CEngineWrapper::ComputeViewPort()" );
       
  1339     return TRect();
       
  1340 }
       
  1341 
       
  1342 //=============================================================================
       
  1343 TRect CEngineWrapper::ComputeVisibleViewPort (const TRect & /*aViewPort*/)
       
  1344 {
       
  1345     LOG ( KEngineWrapperLogFile, "CEngineWrapper::ComputeVisibleViewPort()" );
       
  1346 	return TRect(0,0,0,0);
       
  1347 }
       
  1348 
       
  1349 //=============================================================================
       
  1350 TPoint CEngineWrapper::ComputeNewPanValue (const TRect & /*aVvpOld*/)
       
  1351 {
       
  1352     LOG ( KEngineWrapperLogFile, "CEngineWrapper::ComputeNewPanValue()" );
       
  1353 
       
  1354 	return TPoint();
       
  1355 }
       
  1356 
       
  1357 //=============================================================================
       
  1358 void CEngineWrapper::CopyBufferL (TUint32 * aBuffer)
       
  1359 {
       
  1360     LOG( KEngineWrapperLogFile, "CEngineWrapper::CopyBufferL" );
       
  1361     
       
  1362 	iScreenBitmap->LockHeapLC();
       
  1363 
       
  1364 	TSize size = iScreenBitmap->SizeInPixels();
       
  1365 	TDisplayMode dmode = iScreenBitmap->DisplayMode();
       
  1366 	TInt ws = iScreenBitmap->ScanLineLength (size.iWidth, dmode);
       
  1367 
       
  1368 	TUint8 * tpos = (TUint8*)( iScreenBitmap->DataAddress() );
       
  1369 	TUint8 * tp;
       
  1370 
       
  1371 	for ( TInt y = 0; y < size.iHeight; y++ )
       
  1372 	{
       
  1373 	
       
  1374 		tp = tpos;
       
  1375 		tpos += ws;
       
  1376 		
       
  1377 		for ( TInt x = 0; x < size.iWidth; x++ )
       
  1378 		{
       
  1379 			TUint32 c = *aBuffer++;
       
  1380 			*tp++ = c & 0xFF;
       
  1381 			c >>= 8;
       
  1382 			*tp++ = c & 0xFF;
       
  1383 			c >>= 8;
       
  1384 			*tp++ = c & 0xFF;
       
  1385 		}
       
  1386 	}
       
  1387 
       
  1388 	CleanupStack::PopAndDestroy(); // iScreenBitmap->LockHeapLC	
       
  1389 }
       
  1390 
       
  1391 //=============================================================================
       
  1392 TBool CEngineWrapper::IsSameString (
       
  1393 	const TUint8 *		aString1, 
       
  1394 	const TUint8 *		aString2
       
  1395 	)
       
  1396 {
       
  1397 	TPtrC8 s1( (TUint8*)aString1 );
       
  1398 	TPtrC8 s2( (TUint8*)aString2);
       
  1399 	
       
  1400 	if ( s1.Compare( s2 ) == 0 )
       
  1401 	{
       
  1402 		return ETrue;
       
  1403 	}
       
  1404 	else
       
  1405 	{
       
  1406 		return EFalse;
       
  1407 	}		
       
  1408 }
       
  1409 
       
  1410 //=============================================================================
       
  1411 void CEngineWrapper::UpdateCropRectL ()
       
  1412 {
       
  1413     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateCropRect" );
       
  1414 
       
  1415     TSize screensize = iScreenSize;
       
  1416     TSize imagesize = iBoundingRect.Size();
       
  1417 	TRect croprect = iBoundingRect;
       
  1418 
       
  1419 	if (iScale != 1.0)
       
  1420 	{
       
  1421 	    //  check rotation
       
  1422 	    TInt angle = ComputeRotationL();
       
  1423 	    TSize cropsize = imagesize;
       
  1424 	    TReal sw = 0.0;
       
  1425 	    TReal sh = 0.0;
       
  1426 	    if ((angle == 90) || (angle == 270))
       
  1427 	    {
       
  1428 	        cropsize.iWidth = imagesize.iWidth;
       
  1429 	        cropsize.iHeight = (TReal)(screensize.iWidth * imagesize.iWidth) / screensize.iHeight + 0.5;
       
  1430 	        TReal ari = (TReal)cropsize.iWidth / cropsize.iHeight;    
       
  1431 	        TReal ars = (TReal)screensize.iWidth / screensize.iHeight;    
       
  1432 	        if (ari >= ars)
       
  1433 	        {
       
  1434 	            sw = 0.5 * iScale * cropsize.iWidth;
       
  1435 	            sh = 0.5 * iScale * cropsize.iHeight;
       
  1436 	        }
       
  1437 	        else
       
  1438 	        {
       
  1439 	            sh = 0.5 * iScale * cropsize.iHeight;
       
  1440 	            sw = 0.5 * iScale * cropsize.iWidth;
       
  1441 	        }
       
  1442 	    }
       
  1443 	    else
       
  1444 	    {
       
  1445 	        TReal ari = (TReal)cropsize.iWidth / cropsize.iHeight;    
       
  1446 	        TReal ars = (TReal)screensize.iWidth / screensize.iHeight;    
       
  1447 	        if (ari >= ars)
       
  1448 	        {
       
  1449 	            sw = 0.5 * iScale * cropsize.iWidth;
       
  1450 	            sh = 0.5 * iScale * (cropsize.iWidth / ars);
       
  1451 	        }
       
  1452 	        else
       
  1453 	        {
       
  1454 	            sh = 0.5 * iScale * cropsize.iHeight;
       
  1455 	            sw = 0.5 * iScale * (cropsize.iHeight * ars);
       
  1456 	        }
       
  1457 	    }
       
  1458 
       
  1459 	    //  clip pan
       
  1460 	    if (iPanX - sw < iBoundingRect.iTl.iX)
       
  1461 	    {
       
  1462 	    	if (iScale == 1.0)
       
  1463 	    	{
       
  1464 	    		iPanX = (iBoundingRect.iTl.iX + iBoundingRect.iBr.iX) / 2;
       
  1465 	    	}
       
  1466 	    	else
       
  1467 	    	{
       
  1468 	        	iPanX = iBoundingRect.iTl.iX + sw;
       
  1469 	    	}
       
  1470 	    }
       
  1471 	    else if (iPanX + sw > iBoundingRect.iBr.iX)
       
  1472 	    {   
       
  1473 	    	if (iScale == 1.0)
       
  1474 	    	{
       
  1475 	    		iPanX = (iBoundingRect.iTl.iX + iBoundingRect.iBr.iX) / 2;
       
  1476 	    	}
       
  1477 	    	else
       
  1478 	    	{
       
  1479 	        	iPanX = iBoundingRect.iBr.iX - sw;
       
  1480 	    	}
       
  1481 	    }
       
  1482 	    if (iPanY - sh < iBoundingRect.iTl.iY)
       
  1483 	    {
       
  1484 	    	if (iScale == 1.0)
       
  1485 	    	{
       
  1486 	    		iPanY = (iBoundingRect.iTl.iY + iBoundingRect.iBr.iY) / 2;
       
  1487 	    	}
       
  1488 	    	else
       
  1489 	    	{
       
  1490 	        	iPanY = iBoundingRect.iTl.iY + sh;
       
  1491 	    	}
       
  1492 	    }
       
  1493 	    else if (iPanY + sh > iBoundingRect.iBr.iY)
       
  1494 	    {   
       
  1495 	    	if (iScale == 1.0)
       
  1496 	    	{
       
  1497 	    		iPanY = (iBoundingRect.iTl.iY + iBoundingRect.iBr.iY) / 2;
       
  1498 	    	}
       
  1499 	    	else
       
  1500 	    	{
       
  1501 	        	iPanY = iBoundingRect.iBr.iY - sh;
       
  1502 	    	}
       
  1503 	    }
       
  1504 
       
  1505 	    //  scale rect
       
  1506 	    croprect = TRect(iPanX - sw, iPanY - sh, iPanX + sw, iPanY + sh);
       
  1507 	    if (croprect.iTl.iX < iBoundingRect.iTl.iX)
       
  1508 	    {
       
  1509 	        croprect.iTl.iX = iBoundingRect.iTl.iX;
       
  1510 	    }
       
  1511 	    if (croprect.iTl.iY < iBoundingRect.iTl.iY)
       
  1512 	    {
       
  1513 	        croprect.iTl.iY = iBoundingRect.iTl.iY;
       
  1514 	    }
       
  1515 	    if (croprect.iBr.iX > iBoundingRect.iBr.iX)
       
  1516 	    {
       
  1517 	        croprect.iBr.iX = iBoundingRect.iBr.iX;
       
  1518 	    }
       
  1519 	    if (croprect.iBr.iY > iBoundingRect.iBr.iY)
       
  1520 	    {
       
  1521 	        croprect.iBr.iY = iBoundingRect.iBr.iY;
       
  1522 	    }
       
  1523 
       
  1524 	}
       
  1525 	
       
  1526 	if (croprect != iOldCropRect)
       
  1527 	{
       
  1528 		//	Update crop rectangle
       
  1529 		iCmd.Format( _L("ulc %d ulr %d lrc %d lrr %d"), croprect.iTl.iX, croprect.iTl.iY, 
       
  1530 			croprect.iBr.iX, croprect.iBr.iY);
       
  1531 		LOGDES (KEngineWrapperLogFile, iCmd);			
       
  1532 		iMainEngine->FunctionL ( 0, iCmd );
       
  1533 		iRenderScaleBuffer = ETrue;
       
  1534 		iOldCropRect = croprect;
       
  1535 	}
       
  1536 }
       
  1537 
       
  1538 
       
  1539 //=============================================================================
       
  1540 TPtrC8 CEngineWrapper::UpdateExifThumbnailL ()
       
  1541 {
       
  1542     LOG ( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifThumbnailL" );
       
  1543 
       
  1544 	//	Create Jpeg encoder for memory buffer
       
  1545 	MJpegSave * encoder = JpegSaveFactory::CreateJpegSaveLC (0,0);
       
  1546 
       
  1547     LOG ( KEngineWrapperLogFile, "UpdateExifThumbnailL::0" );
       
  1548  	
       
  1549 	// 	Initialize saving
       
  1550 	encoder->StartSaveL (iThumbSize, TPtr8(0,0), 65536, KThumbnailJpegQuality);
       
  1551 
       
  1552     LOG ( KEngineWrapperLogFile, "UpdateExifThumbnailL::1" );
       
  1553 
       
  1554 	// 	Save in blocks
       
  1555 	TBitmapHandle bmBlock;
       
  1556 	bmBlock.iData = new (ELeave) TUint32 [16 * 8];
       
  1557 
       
  1558     LOG ( KEngineWrapperLogFile, "UpdateExifThumbnailL::2" );
       
  1559 	
       
  1560 	for (TInt y = 0; y < iThumbSize.iHeight; y += 8)
       
  1561 	{
       
  1562 		for (TInt x = 0; x < iThumbSize.iWidth; x += 16)
       
  1563 		{
       
  1564 		
       
  1565 			TInt lastY = y + 8;
       
  1566 			if (lastY >= iThumbSize.iHeight)
       
  1567 			{
       
  1568 				lastY = iThumbSize.iHeight - 1;
       
  1569 			}
       
  1570 			TInt lastX = x + 16;
       
  1571 			if (lastX >= iThumbSize.iWidth)
       
  1572 			{
       
  1573 				lastX = iThumbSize.iWidth - 1;			
       
  1574 			}
       
  1575 			
       
  1576 			TUint32 * pDOS = (TUint32 *)bmBlock.iData;
       
  1577 			TUint32 * pSOS = iThumb + y * iThumbSize.iWidth + x;
       
  1578 			
       
  1579 			for (TInt yy = y; yy < lastY; yy++ )
       
  1580 			{
       
  1581 			
       
  1582 				TUint32 * pD = pDOS;
       
  1583 				pDOS += 16;
       
  1584 
       
  1585 				TUint32 * pS = pSOS;
       
  1586 				pSOS += iThumbSize.iWidth;
       
  1587 				
       
  1588 				for (TInt xx = x; xx < lastX; xx++ )
       
  1589 				{
       
  1590 					*pD++ = *pS++;
       
  1591 				}
       
  1592 			}
       
  1593 		
       
  1594 		
       
  1595 			encoder->SaveBlock (bmBlock);
       
  1596 		}
       
  1597 	}
       
  1598 
       
  1599     LOG ( KEngineWrapperLogFile, "UpdateExifThumbnailL::3" );
       
  1600 	
       
  1601 	delete (TUint32 *)bmBlock.iData;
       
  1602 	bmBlock.iData = NULL;
       
  1603 
       
  1604     LOG ( KEngineWrapperLogFile, "UpdateExifThumbnailL::4" );
       
  1605 
       
  1606 	TPtrC8 thumbNail = encoder->Finalize();
       
  1607 
       
  1608     LOG ( KEngineWrapperLogFile, "UpdateExifThumbnailL::5" );
       
  1609 
       
  1610 	TPtrC8 exif = iExifParser->SaveL (thumbNail);
       
  1611 
       
  1612     LOG ( KEngineWrapperLogFile, "UpdateExifThumbnailL::6" );
       
  1613 
       
  1614 	CleanupStack::PopAndDestroy (); // encoder
       
  1615 
       
  1616 	return exif;
       
  1617 }    
       
  1618 
       
  1619 //=============================================================================
       
  1620 void CEngineWrapper::UpdateExifTagsL()
       
  1621 {
       
  1622     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL" );
       
  1623 
       
  1624     // DateTime 
       
  1625     LOG ( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- DateTime" );
       
  1626     TBuf8<64> dateTimeBuf;
       
  1627     GetCurrentDateTime ( dateTimeBuf );
       
  1628     iExifParser->DeleteTag ( CExifParser::EIfd0, 0x0132);
       
  1629     iExifParser->AddTagL ( CExifParser::EIfd0, 0x0132, dateTimeBuf.PtrZ());
       
  1630 
       
  1631     TInt n = iMainEngine->NumFilters();
       
  1632     MImageFilter * filter = iMainEngine->Filter(n - 2);
       
  1633 	
       
  1634 	TInt targetWidth = (TReal)(filter->ViewPortSize().iWidth * iSysPars->Scale()) + 0.5;
       
  1635 	TInt targetHeight = (TReal)(filter->ViewPortSize().iHeight * iSysPars->Scale()) + 0.5;
       
  1636 
       
  1637     // ImageWidth - not needed  
       
  1638     iExifParser->DeleteTag ( CExifParser::EIfd0, 0x0100);
       
  1639 
       
  1640     // ImageHeight - not needed  
       
  1641     iExifParser->DeleteTag ( CExifParser::EIfd0, 0x0101);
       
  1642 
       
  1643     // Orientation
       
  1644     if ( !iExifParser->TagExist (CExifParser::EIfd0, 0x0112) )
       
  1645     {
       
  1646     	LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- Orientation" );
       
  1647     	iExifParser->AddTagL ( CExifParser::EIfd0, 0x0112, (TUint16)1);
       
  1648     }
       
  1649 
       
  1650     // EXIF version 
       
  1651     TUint8 exifVersion [] = "0220";
       
  1652     if ( !iExifParser->TagExist (CExifParser::ESubIfd, 0x9000) )
       
  1653     {
       
  1654 	   	LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- ExifVersion" );
       
  1655 	    iExifParser->AddTagL ( CExifParser::ESubIfd, 0x9000, TPtrC8 (exifVersion));
       
  1656     }
       
  1657     
       
  1658     // FlashPixVersion
       
  1659     TUint8 flashPixVersion [] = "0100";
       
  1660     if ( !iExifParser->TagExist (CExifParser::ESubIfd, 0xA000) )
       
  1661     {
       
  1662 	    LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- FlashPixVersion" );
       
  1663 	    iExifParser->DeleteTag ( CExifParser::ESubIfd, 0xA000);
       
  1664 	    iExifParser->AddTagL ( CExifParser::ESubIfd, 0xA000, TPtrC8 (flashPixVersion));
       
  1665     }
       
  1666     
       
  1667     // ComponentsConfiguration
       
  1668     TUint8 exifComponentsConfiguration [4] = {1,2,3,0};
       
  1669     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- ComponentsConfiguration" );
       
  1670     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0x9101);
       
  1671     iExifParser->AddTagL ( CExifParser::ESubIfd, 0x9101, TPtrC8(exifComponentsConfiguration, 4));
       
  1672 
       
  1673     // ColorSpace 
       
  1674     LOG ( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- ColorSpace" );
       
  1675     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0xA001);
       
  1676     iExifParser->AddTagL ( CExifParser::ESubIfd, 0xA001, (TUint16)1);
       
  1677 
       
  1678     // Interoperability index 
       
  1679     iExifParser->DeleteTag ( CExifParser::EInteroperability, 0x0001);
       
  1680 
       
  1681     // PixelXResolution 
       
  1682     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- PlaneXResolution" );
       
  1683     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0xA002);
       
  1684     iExifParser->AddTagL ( CExifParser::ESubIfd, 0xA002,(TUint32)targetWidth);
       
  1685 
       
  1686     // PixelYResolution 
       
  1687     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- PlaneYResolution" );
       
  1688     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0xA003);
       
  1689     iExifParser->AddTagL ( CExifParser::ESubIfd, 0xA003, (TUint32)targetHeight);
       
  1690 
       
  1691     // FocalPlaneResolutionUnit
       
  1692     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0xA210);
       
  1693 
       
  1694     // FocalPlaneXResolution 
       
  1695     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0xA20E);
       
  1696     
       
  1697     // FocalPlaneYResolution 
       
  1698     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0xA20F);
       
  1699 
       
  1700     // User Comment 
       
  1701     TBuf8<256> comment;
       
  1702     TUint8 KCharCode[8] = {0x41,0x53,0x43,0x49,0x49,0x00,0x00,0x00}; // ASCII char code
       
  1703 	comment.Append(TPtrC8(KCharCode, 8));
       
  1704     comment.AppendFormat(KImageEditorExifComment, my_version_major, my_version_minor, my_version_build);
       
  1705 
       
  1706     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- UserComment" );
       
  1707     iExifParser->DeleteTag ( CExifParser::ESubIfd, 0x9286);
       
  1708     iExifParser->AddTagL ( CExifParser::ESubIfd, 0x9286, comment);
       
  1709 
       
  1710     TBuf8<128> make;
       
  1711     TBuf8<128> model;
       
  1712     ImageEditorUtils::GetMakeAndModelL ( make, model );
       
  1713 
       
  1714     // Make
       
  1715     if ( !iExifParser->TagExist (CExifParser::EIfd0, 0x010F) )
       
  1716     {
       
  1717     	LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- Make updated" );
       
  1718 	    iExifParser->AddTagL ( CExifParser::EIfd0, 0x010F, make.PtrZ());
       
  1719     }
       
  1720 
       
  1721     // Model
       
  1722     if ( !iExifParser->TagExist (CExifParser::EIfd0, 0x0110) )
       
  1723     {
       
  1724     	LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- Model updated" );
       
  1725 	    iExifParser->AddTagL ( CExifParser::EIfd0, 0x0110, model.PtrZ());
       
  1726     }
       
  1727 
       
  1728     // DateTimeOriginal
       
  1729     if ( !iExifParser->TagExist (CExifParser::ESubIfd, 0x9003) )
       
  1730     {
       
  1731     	LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- DateTimeOriginal updated" );
       
  1732 	    iExifParser->AddTagL ( CExifParser::ESubIfd, 0x9003, dateTimeBuf.PtrZ());
       
  1733     }
       
  1734 
       
  1735     // DateTimeDigitized
       
  1736     if ( !iExifParser->TagExist (CExifParser::ESubIfd, 0x9004) )
       
  1737     {
       
  1738     	LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- DateTimeDigitized updated" );
       
  1739 	    iExifParser->AddTagL ( CExifParser::ESubIfd, 0x9004, dateTimeBuf.PtrZ());
       
  1740     }
       
  1741         
       
  1742     // XResolution
       
  1743     LOG ( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- XResolution" );
       
  1744     if ( !iExifParser->TagExist (CExifParser::EIfd0, 0x011A) )
       
  1745     {
       
  1746     	iExifParser->AddTagL ( CExifParser::EIfd0, 0x011A, (TUint32)300, (TUint32)1);	
       
  1747     }
       
  1748     
       
  1749     // YResolution
       
  1750     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- YResolution" );
       
  1751     if ( !iExifParser->TagExist (CExifParser::EIfd0, 0x011B) )
       
  1752     {
       
  1753     	iExifParser->AddTagL ( CExifParser::EIfd0, 0x011B, (TUint32)300, (TUint32)1);	
       
  1754     }
       
  1755     
       
  1756     // ResolutionUnit
       
  1757     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- ResolutionUnit" );
       
  1758     if ( !iExifParser->TagExist (CExifParser::EIfd0, 0x0128) )
       
  1759     {
       
  1760     	iExifParser->AddTagL ( CExifParser::EIfd0, 0x0128, (TUint16)2 ); 	
       
  1761     }
       
  1762     
       
  1763     // YCbCrPositioning
       
  1764     LOG( KEngineWrapperLogFile, "CEngineWrapper::UpdateExifTagsL() -- YCbCrPositioning" );
       
  1765     if ( !iExifParser->TagExist (CExifParser::EIfd0, 0x0213) )
       
  1766     {
       
  1767     	iExifParser->AddTagL ( CExifParser::EIfd0, 0x0213, (TUint16)1 ); 	
       
  1768     }
       
  1769   
       
  1770     
       
  1771 }
       
  1772 
       
  1773 //=============================================================================
       
  1774 void CEngineWrapper::GetCurrentDateTime (TDes8 & aDateTimeBuf) const
       
  1775 {
       
  1776     // Time in microseconds since 0 AD nominal Gregorian
       
  1777     TTime time;
       
  1778     // year-month-day-hour-minute-second-microsecond
       
  1779     TDateTime dateTime;
       
  1780 
       
  1781     // Get current local time
       
  1782     time.HomeTime();
       
  1783 
       
  1784     // Convert to fields
       
  1785     dateTime = time.DateTime();
       
  1786 
       
  1787     // Create descriptors for the components.
       
  1788     // This is needed because the leading zeros 
       
  1789     // cannotbe suppressed.
       
  1790     TBuf8<2> month;
       
  1791     TBuf8<2> day;
       
  1792     TBuf8<2> hour;
       
  1793     TBuf8<2> minute;
       
  1794     TBuf8<2> second;
       
  1795 
       
  1796     if( TInt(dateTime.Month()) < 9 )
       
  1797     {
       
  1798         month.AppendNum( 0 );
       
  1799     }
       
  1800     month.AppendNum( TInt(dateTime.Month()+1) );
       
  1801 
       
  1802     if( dateTime.Day() < 9 )
       
  1803     {
       
  1804         day.AppendNum( 0 );
       
  1805     }
       
  1806     day.AppendNum( dateTime.Day()+1 );
       
  1807 
       
  1808     if( dateTime.Hour() < 10 )
       
  1809     {
       
  1810         hour.AppendNum( 0 );
       
  1811     }
       
  1812     hour.AppendNum( dateTime.Hour() );
       
  1813 
       
  1814     if( dateTime.Minute() < 10 )
       
  1815     {
       
  1816         minute.AppendNum( 0 );
       
  1817     }
       
  1818     minute.AppendNum( dateTime.Minute() );
       
  1819 
       
  1820     if( dateTime.Second() < 10 )
       
  1821     {
       
  1822         second.AppendNum( 0 );
       
  1823     }
       
  1824     second.AppendNum( dateTime.Second() );
       
  1825 
       
  1826     // Format the time to the format
       
  1827     // "YYYY:MM:DD HH:MM:SS"
       
  1828     _LIT8(KFormatTxt,"%d:%S:%S %S:%S:%S");
       
  1829     aDateTimeBuf.Format(
       
  1830         KFormatTxt,
       
  1831         dateTime.Year(),
       
  1832         &month, 
       
  1833         &day, 
       
  1834         &hour, 
       
  1835         &minute, 
       
  1836         &second
       
  1837         );
       
  1838 }
       
  1839 
       
  1840 //=============================================================================
       
  1841 EXPORT_C void CEngineWrapper::SetBitmap (CFbsBitmap * aBitmap)
       
  1842 {
       
  1843 	iScreenBitmap = aBitmap;
       
  1844 }
       
  1845 
       
  1846 
       
  1847 //=============================================================================
       
  1848 EXPORT_C void CEngineWrapper::CreateExifThumbNailL ()
       
  1849 {
       
  1850     LOG( KEngineWrapperLogFile, "CEngineWrapper::CreateExifThumbNailL" );
       
  1851 
       
  1852 #ifdef EXIF_SUPPORT    
       
  1853     
       
  1854     //	Delete old thumbnail
       
  1855     delete[] iThumb;
       
  1856     iThumb = NULL; 
       
  1857 
       
  1858 	//	Re-load the zoomed image if needed
       
  1859 	if ( iRenderScaleBuffer )
       
  1860 	{
       
  1861 		iMainEngine->FunctionL ( 0, _L("loadimage"));
       
  1862 		iRenderScaleBuffer = EFalse;
       
  1863 	}
       
  1864 	for ( TInt i = 0; i < iMainEngine->NumFilters(); ++i)
       
  1865 	{
       
  1866 		iMainEngine->FunctionL (i, _L("nop"));
       
  1867 	}
       
  1868 
       
  1869 	TReal scale = 1.0;
       
  1870 	TSize imagesize = iMainEngine->Filter(iMainEngine->NumFilters() - 3)->Rect().Size();
       
  1871 	if (imagesize.iWidth > imagesize.iHeight)
       
  1872 	{
       
  1873 		scale = (TReal)imagesize.iWidth / KThumbnailMaxDimension;
       
  1874 	}
       
  1875 	else
       
  1876 	{
       
  1877 		scale = (TReal)imagesize.iHeight / KThumbnailMaxDimension;
       
  1878 	}
       
  1879 
       
  1880 	//	Crete new thumbnail
       
  1881 	iThumbSize.iWidth = (TInt)((imagesize.iWidth / scale) + 0.5);
       
  1882 	iThumbSize.iHeight = (TInt)((imagesize.iHeight / scale) + 0.5);
       
  1883 	
       
  1884 	// Just ensure that dimension are never 0
       
  1885 	if (iThumbSize.iWidth == 0)
       
  1886 	{
       
  1887 		iThumbSize.iWidth = 1;
       
  1888 	}
       
  1889 	if (iThumbSize.iHeight == 0)
       
  1890 	{
       
  1891 		iThumbSize.iHeight = 1;
       
  1892 	}
       
  1893 	
       
  1894     LOGFMT( KEngineWrapperLogFile, "iThumbSize.iWidth = %d", iThumbSize.iWidth);
       
  1895     LOGFMT( KEngineWrapperLogFile, "iThumbSize.iHeight = %d", iThumbSize.iHeight);
       
  1896 
       
  1897 	iThumb = new (ELeave) TUint32 [iThumbSize.iWidth * iThumbSize.iHeight];
       
  1898 	
       
  1899 	//	Set thumbnail size to buffer filter
       
  1900 	iCmd.Format( _L("width %d height %d"), iThumbSize.iWidth, iThumbSize.iHeight);
       
  1901 	iMainEngine->FunctionL ( iMainEngine->NumFilters() - 1, iCmd );
       
  1902 	iMainEngine->FunctionL ( iMainEngine->NumFilters() - 2, _L("nop"));
       
  1903 
       
  1904 	//	Copy data to the new thumbnail
       
  1905 	TUint32 * pBuffer = (TUint32 *)iMainEngine->FunctionL (iMainEngine->NumFilters() - 1, _L("getbitmap"));
       
  1906 	Mem::Copy (iThumb, pBuffer, iThumbSize.iWidth * iThumbSize.iHeight * sizeof(TUint32));
       
  1907 
       
  1908     LOG( KEngineWrapperLogFile, "EXIF thumbnail created!" );
       
  1909 	
       
  1910 #endif
       
  1911 }
       
  1912 
       
  1913 
       
  1914 //=============================================================================
       
  1915 TInt CEngineWrapper::ComputeRotationL ()
       
  1916 {
       
  1917 	
       
  1918 	TInt angle = 0;
       
  1919 	TInt ind = 0;
       
  1920 	while ( ind < iMainEngine->NumFilters() )
       
  1921 	{
       
  1922 	    MImageFilter * filter = iMainEngine->Filter(ind);
       
  1923 	    char * cmpstr = "rotate";
       
  1924 	    TPtrC8 type ( (const TUint8 *)filter->Type() );
       
  1925 	    TPtrC8 typecmp ((const TUint8 *)cmpstr);
       
  1926 	    if ( type == typecmp )
       
  1927 	    {
       
  1928 	        angle += filter->CmdL(_L("getangle"));
       
  1929 	    }
       
  1930 	    ind++;
       
  1931 	}
       
  1932 	angle %= 360;
       
  1933 	return angle;
       
  1934 }
       
  1935 
       
  1936 
       
  1937 //=============================================================================
       
  1938 void CEngineWrapper::ComputeBoundingRectL()
       
  1939 {
       
  1940     MImageFilter * pFilter = iMainEngine->Filter(iMainEngine->NumFilters() - 3);
       
  1941     TReal relscale = pFilter->Scale();
       
  1942     TRect rect = pFilter->Rect();
       
  1943     TSize size = iMainEngine->Filter(0)->ViewPortSize();
       
  1944     rect.iTl.iX = (TInt)((rect.iTl.iX / relscale) + 0.5);
       
  1945     rect.iTl.iY = (TInt)((rect.iTl.iY / relscale) + 0.5);
       
  1946     rect.iBr.iX = (TInt)((rect.iBr.iX / relscale) + 0.5);
       
  1947     rect.iBr.iY = (TInt)((rect.iBr.iY / relscale) + 0.5);
       
  1948     TInt angle = ComputeRotationL();
       
  1949  
       
  1950     if (angle == 90 || angle == 270)
       
  1951     {
       
  1952         iBoundingRect.iTl.iX = rect.iTl.iY;
       
  1953         iBoundingRect.iTl.iY = rect.iTl.iX;
       
  1954         iBoundingRect.iBr.iX = rect.iBr.iY;
       
  1955         iBoundingRect.iBr.iY = rect.iBr.iX;
       
  1956     }
       
  1957     else
       
  1958     {
       
  1959         iBoundingRect = rect;
       
  1960     }
       
  1961 
       
  1962     size = iBoundingRect.Size();
       
  1963     iPanX = (iBoundingRect.iTl.iX + iBoundingRect.iBr.iX) / 2;
       
  1964     iPanY = (iBoundingRect.iTl.iY + iBoundingRect.iBr.iY) / 2;
       
  1965 }
       
  1966 
       
  1967 
       
  1968 // End of File