videoeditorengine/vedengine/GenManip/src/DCDigitalZoom.cpp
changeset 0 951a5db380a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/vedengine/GenManip/src/DCDigitalZoom.cpp	Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,1059 @@
+/*
+* 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:  
+*
+*/
+
+
+//----IMAAMI----
+//*************************************************************************
+//DCDCDigitalZoom.h
+//
+//Version 1.00
+//
+//Contains:
+//	CDCDCDigitalZoom 
+//		Scaling of image to display size & zooming.
+//		Includes support for different scaling and crop sizes with pan&scan.
+//		Pan can use previously computed scaled data when changing.
+//		Based on IMAAMI scaling algorithm.
+//	
+//History:
+//	19.08.2003 version 1.00 created using existing IMAAMI algorithms	
+//*************************************************************************
+
+
+
+#include <fbs.h>
+#include "DCDigitalZoom.h"
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+    CDCDigitalZoom::CDCDigitalZoom
+
+	C++ constructor.
+
+	Initialises set of member parameters.
+
+-----------------------------------------------------------------------------
+*/
+CDCDigitalZoom::CDCDigitalZoom()
+{
+
+	iParams.sizeX      = 176; //640;	// Size of VGA image for X
+	iParams.sizeY      = 144; //480;	// Size of VGA image for Y
+	iParams.scaleX     = 1.0f;	// No Scaling for X
+	iParams.scaleY     = 1.0f;	// No scaling for Y
+	iParams.allShiftX  = 0;		// No pan
+	iParams.allShiftY  = 0;		// 
+	iParams.newShiftX  = 0;		// No pan
+	iParams.newShiftY  = 0;		//
+
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+    CDCDigitalZoom::ConstructL
+
+	Second phase constructor.
+
+	Construct the object. (not used, may leave)
+
+-----------------------------------------------------------------------------
+*/
+
+void CDCDigitalZoom::ConstructL()
+{
+	// This function is intentionally left blank.
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+    CDCDigitalZoom::NewLC
+
+	Allocate the memory and construct the object.
+	Pushs pointer to a new instance to Cleanupstack.
+
+    Return value:
+		CDCDigitalZoom* self		Pointer to a new instance
+
+-----------------------------------------------------------------------------
+*/
+
+CDCDigitalZoom* CDCDigitalZoom::NewLC()
+{
+	CDCDigitalZoom* self = new (ELeave) CDCDigitalZoom();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+
+	return self;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+    CDCDigitalZoom::NewL
+
+	Allocate the memory and construct the object.
+
+    Return value:
+		CDCDigitalZoom* self		Pointer to a new instance
+
+-----------------------------------------------------------------------------
+*/
+
+CDCDigitalZoom* CDCDigitalZoom::NewL()
+{
+	CDCDigitalZoom* self = CDCDigitalZoom::NewLC();
+	CleanupStack::Pop();
+
+	return self;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+    CDCDigitalZoom::~CDCDigitalZoom
+
+	C++ destructor.
+
+-----------------------------------------------------------------------------
+*/
+
+CDCDigitalZoom::~CDCDigitalZoom()
+{
+	// This function is intentionally left blank.
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+    CDCDigitalZoom::ProcessL
+
+	Main function of digital zoom. (public)
+	Calls processing function (zoomImage).
+
+	NOTE:
+		ImageZoomParams iParams have to be set before calling
+		this function, so that the wanted processing is done.
+
+    Parameters in:
+		CFbsBitmap* aOriPtr		Pointer to source image bitmap
+
+	Parameters out:
+		CFbsBitmap* aOutPtr		Pointer to destination image bitmap
+
+    Return value: None
+
+-----------------------------------------------------------------------------
+*/
+
+void CDCDigitalZoom::ProcessL(const CFbsBitmap *aOriPtr, CFbsBitmap *aOutPtr)
+{
+	//EColor16M image is needed
+	if(aOutPtr->DisplayMode() != EColor16M)
+	{
+		return;
+	}
+
+	if(aOriPtr->DisplayMode() != EColor16M)
+	{
+		return;
+	}
+
+	// Find size of original image
+	TInt oriSizeX = aOriPtr->SizeInPixels().iWidth;
+	TInt oriSizeY = aOriPtr->SizeInPixels().iHeight;
+
+	//Do scaling
+	DecimateL(aOriPtr, aOutPtr,
+			iParams.sizeX, iParams.sizeY,
+			oriSizeX, oriSizeY,
+			iParams.scaleX, iParams.scaleY,
+			iParams.allShiftX, iParams.allShiftY,
+			iParams.newShiftX, iParams.newShiftY);
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+  DecimateL
+
+  IMAAMI scaling core function
+		
+-----------------------------------------------------------------------------
+*/
+void CDCDigitalZoom::DecimateL(const CFbsBitmap* aOriPtr, CFbsBitmap* aOutPtr,
+									 TInt aOutSizeX, TInt aOutSizeY,
+									 TInt aOriSizeX, TInt aOriSizeY,
+									 TReal aZoomX, TReal aZoomY,
+									 TInt allShiftX, TInt allShiftY,
+									 TInt newShiftX, TInt newShiftY)
+{
+	TInt32
+		divider,
+		xPos, yPos, tmpline,
+		xAver, yAver,
+		xStep, yStep,
+		tmpEnd, tmpSta,
+		sumB, sumG, sumR,
+		tmpB, tmpG, tmpR;
+
+	TInt32
+		x, y,
+		i, j,
+		LastLine,
+		xInt, yInt,
+		xStaInt, yStaInt,
+		xEndInt, yEndInt,
+		xFirstInt, yFirstInt;
+
+	TUint32
+		LineNum,
+		outFlag,
+		xRem, yRem,
+		xStaRem, yStaRem,
+		xEndRem, yEndRem,
+		xStaWei, yStaWei,
+		xEndWei, yEndWei,
+		xAllWei, yAllWei,
+		xMaxWei, yMaxWei,
+		xLoopSta, yLoopSta,
+		xLoopEnd, yLoopEnd,
+		xFirstRem, yFirstRem;
+
+	TUint32
+		PIX_BITS	= 13,						// 13
+		PIXEL		= (TUint32)(1 << PIX_BITS),
+		HALF_PIX	= (TUint32)(1 << (PIX_BITS - 1)),
+		REMAINDER	= (TUint32)(PIXEL - 1),
+		WEI_BITS	= 4,						// 4
+		HALF_WEI	= (TUint32)(1 << (WEI_BITS - 1)),
+		DIF1_BITS	= (TUint32)(PIX_BITS - WEI_BITS),
+		HALF_DIF1	= (TUint32)(1 << (DIF1_BITS - 1)),
+		REM_HDIF1	= (TUint32)(HALF_DIF1 - 1),
+		RED_BITS	= 4,						// 4
+		HALF_RED	= (TUint32)(1 << (RED_BITS - 1));
+
+
+	if(aZoomX < 0.20 || aZoomY < 0.20)
+	{
+		RED_BITS = 5;
+		HALF_RED = (TUint32)(1 << (RED_BITS - 1));
+	}
+
+	// Allocate local temporal input0 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine0 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine0);
+	
+	// Allocate local temporal input1 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine1 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine1);
+
+	// Allocate local temporal input2 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine2 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine2);
+
+	// Allocate local temporal input3 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine3 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine3);
+
+	// Allocate local temporal input4 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine4 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine4);
+
+	// Allocate local temporal input5 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine5 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine5);
+	
+	// Allocate local temporal input6 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine6 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine6);
+
+	// Allocate local temporal input7 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine7 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine7);
+
+	// Allocate local temporal input8 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine8 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine8);
+
+	// Allocate local temporal input9 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine9 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine9);
+
+	// Allocate local temporal input10 line buffer and push its pointer to CleanupStack
+	HBufC8* oriLine10 = HBufC8::NewMaxL(3 * aOriSizeX);	// BGRBGR...
+	CleanupStack::PushL(oriLine10);
+	
+	// Set pointers of input lines
+	TUint8* line0Ptr = (TUint8*)oriLine0->Des().Ptr();
+	TUint8* line1Ptr = (TUint8*)oriLine1->Des().Ptr();
+	TUint8* line2Ptr = (TUint8*)oriLine2->Des().Ptr();
+	TUint8* line3Ptr = (TUint8*)oriLine3->Des().Ptr();
+	TUint8* line4Ptr = (TUint8*)oriLine4->Des().Ptr();
+	TUint8* line5Ptr = (TUint8*)oriLine5->Des().Ptr();
+	TUint8* line6Ptr = (TUint8*)oriLine6->Des().Ptr();
+	TUint8* line7Ptr = (TUint8*)oriLine7->Des().Ptr();
+	TUint8* line8Ptr = (TUint8*)oriLine8->Des().Ptr();
+	TUint8* line9Ptr = (TUint8*)oriLine9->Des().Ptr();
+	TUint8* line10Ptr = (TUint8*)oriLine10->Des().Ptr();
+	TUint8* linePtrs[11] = {line0Ptr, line1Ptr, line2Ptr, line3Ptr, line4Ptr,
+							line5Ptr, line6Ptr, line7Ptr, line8Ptr, line9Ptr, line10Ptr};
+
+	TUint8* tmpPtr;
+	TUint8* tempPtr;
+	
+	// Set TPtr8s of input lines
+	TPtr8 Ptr0(line0Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr1(line1Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr2(line2Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr3(line3Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr4(line4Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr5(line5Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr6(line6Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr7(line7Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr8(line8Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr9(line9Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptr10(line10Ptr, 3 * aOriSizeX, 3 * aOriSizeX);
+	TPtr8 Ptrs[11] = {Ptr0, Ptr1, Ptr2, Ptr3, Ptr4, Ptr5, Ptr6, Ptr7, Ptr8, Ptr9, Ptr10};
+	
+	// Set indicator for order of input lines
+	TInt lines[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+	
+	// Allocate local temporal output line buffer and push its pointer to CleanupStack
+	HBufC8* scanLine = HBufC8::NewMaxL(3 * aOutSizeX);
+	CleanupStack::PushL(scanLine);
+	
+	// Set pointer of output line
+	TUint8* DataPtr = (TUint8*)scanLine->Des().Ptr();
+	
+	// Set TPtr8 of output line
+	TPtr8 linePtr(DataPtr, 3 * aOutSizeX, 3 * aOutSizeX);
+
+	
+	// Calculate step between output pixels in original image
+	xStep = (TInt)(PIXEL / aZoomX + 0.5);
+	yStep = (TInt)(PIXEL / aZoomY + 0.5);
+	
+	// Calculate First output pixel position in original image
+	xPos = ((aOriSizeX - 1) << (PIX_BITS - 1)) - (((aOutSizeX - 1 - (allShiftX << 1)) * xStep) >> 1);
+	yPos = ((aOriSizeY - 1) << (PIX_BITS - 1)) - (((aOutSizeY - 1 - (allShiftY << 1)) * yStep) >> 1);
+	
+	xFirstInt = (TInt32)(xPos >> PIX_BITS);
+	if(xPos < 0) xFirstRem = (TUint32)((xPos + ((-xFirstInt) << PIX_BITS)) & REMAINDER);
+	else		 xFirstRem = (TUint32)(xPos & REMAINDER);
+	
+	yFirstInt = (TInt32)(yPos >> PIX_BITS);
+	if(yPos < 0) yFirstRem = (TUint32)((yPos + ((-yFirstInt) << PIX_BITS)) & REMAINDER);
+	else		 yFirstRem = (TUint32)(yPos & REMAINDER);
+	
+	// Calculate averaging area around the original pixel position
+	xAver = (TInt)(xStep >> 1);
+	yAver = (TInt)(yStep >> 1);
+	
+	// For bilinear interpolation at least 1 pixel have to be used
+	if(aZoomX > 1 && xAver < (TInt32)(HALF_PIX)) xAver = HALF_PIX;
+	if(aZoomY > 1 && yAver < (TInt32)(HALF_PIX)) yAver = HALF_PIX;
+	
+	// Calculate maximum weight sum
+	yMaxWei = (TUint32)(((yAver << 1) + HALF_DIF1) >> DIF1_BITS);
+	xMaxWei = (TUint32)(((xAver << 1) + HALF_DIF1) >> DIF1_BITS);
+	
+	// Calculate filter divider for filter window
+	divider = (TInt)((xMaxWei * yMaxWei + HALF_RED) >> RED_BITS);
+	
+	while(divider <= 256 && WEI_BITS < PIX_BITS)
+	{
+		WEI_BITS++;
+		HALF_WEI  = (TUint32)(1 << (WEI_BITS - 1));
+		DIF1_BITS = (TUint32)(PIX_BITS - WEI_BITS);
+		HALF_DIF1 = (TUint32)(1 << (DIF1_BITS - 1));
+		REM_HDIF1 = (TUint32)(HALF_DIF1 - 1);
+		
+		// Calculate maximum weight sum
+		yMaxWei = (TUint32)(((yAver << 1) + HALF_DIF1) >> DIF1_BITS);
+		xMaxWei = (TUint32)(((xAver << 1) + HALF_DIF1) >> DIF1_BITS);
+		
+		// Calculate filter divider for filter window
+		divider = (TInt)((xMaxWei * yMaxWei + HALF_RED) >> RED_BITS);
+	}
+	
+	if(divider > 1024)
+	{
+		WEI_BITS--;
+		HALF_WEI  = (TUint32)(1 << (WEI_BITS - 1));
+		DIF1_BITS = (TUint32)(PIX_BITS - WEI_BITS);
+		HALF_DIF1 = (TUint32)(1 << (DIF1_BITS - 1));
+		REM_HDIF1 = (TUint32)(HALF_DIF1 - 1);
+		
+		// Calculate maximum weight sum
+		yMaxWei = (TUint32)(((yAver << 1) + HALF_DIF1) >> DIF1_BITS);
+		xMaxWei = (TUint32)(((xAver << 1) + HALF_DIF1) >> DIF1_BITS);
+		
+		// Calculate filter divider for filter window
+		divider = (TInt)((xMaxWei * yMaxWei + HALF_RED) >> RED_BITS);
+	}
+	
+	while(divider <= 512 && RED_BITS > 0)
+	{
+		RED_BITS--;
+		HALF_RED = (TUint32)(1 << (RED_BITS - 1));
+		
+		divider = (TInt)((xMaxWei * yMaxWei + HALF_RED) >> RED_BITS);
+	}
+	
+	if(divider > 1024)
+	{
+		RED_BITS++;
+		HALF_RED = (TUint32)(1 << (RED_BITS - 1));
+	}
+	
+	// Initialise y loop limiters
+	yLoopSta = 0;
+	yLoopEnd = (TUint32)(aOutSizeY);
+	
+	// Initialise x loop limiters
+	xLoopSta = 0;
+	xLoopEnd = (TUint32)(aOutSizeX);
+
+	// Calculate only the panned image
+		if(newShiftY > 0)
+		{
+			// Update y loop start
+			yLoopSta = (TUint32)(aOutSizeY - newShiftY);
+
+			// Initialise y position
+			yInt = yFirstInt;
+			yRem = yFirstRem;
+
+			// Copy available image and change y position
+			for(y = 0; y < (TInt32)yLoopSta; y++)
+			{
+				// Read output line from source image
+				aOriPtr->GetScanLine(Ptrs[lines[0]], TPoint(0, y+newShiftY), aOriSizeX, aOriPtr->DisplayMode());
+
+				//Set the line to destination image
+				aOutPtr->SetScanLine(linePtr, y);
+
+				// Update y position
+				tmpEnd = (TInt)(yRem + yStep);
+				yInt = (TInt32)(yInt + (tmpEnd >> PIX_BITS));
+				yRem = (TUint32)(tmpEnd & REMAINDER);
+			}
+
+			// Update y position of first pixel
+			yFirstInt = yInt;
+			yFirstRem = yRem;
+		}
+		else if(newShiftY < 0)
+		{
+			// Update y loop end
+			yLoopEnd = (TUint32)(-newShiftY);
+
+			// Copy available image
+			for(y = (TInt32)(aOutSizeY - 1); y >= (TInt32)yLoopEnd; y--)
+			{
+				// Read output line from source image
+				aOriPtr->GetScanLine(Ptrs[lines[0]], TPoint(0, y+newShiftY), aOriSizeX, aOriPtr->DisplayMode());
+
+				//Set the line to destination image
+				aOutPtr->SetScanLine(linePtr, y);
+			}
+		}
+
+		// Calculate only the panned image
+		if(newShiftX > 0)
+		{
+			// Update x loop start
+			xLoopSta = (TUint32)(aOutSizeX - newShiftX);
+
+			// Initialise x position
+			xInt = xFirstInt;
+			xRem = xFirstRem;
+
+			// Change x position
+			for(x = 0; x < (TInt32)xLoopSta; x++)
+			{
+				// Update x position
+				tmpSta = (TInt)(xRem + xStep);
+				xInt = (TInt32)(xInt + (tmpSta >> PIX_BITS));
+				xRem = (TUint32)(tmpSta & REMAINDER);
+			}
+
+			// Update x position of first pixel
+			xFirstInt = xInt;
+			xFirstRem = xRem;
+		}
+		else if(newShiftX < 0)
+		{
+			// Update loop end
+			xLoopEnd = (TUint32)(-newShiftX);
+		}
+
+		// Initialise y position
+		yInt = yFirstInt;
+		yRem = yFirstRem;
+
+		tmpEnd = (TInt)(yRem + yAver + HALF_PIX + HALF_WEI);
+		yEndInt = (TInt32)((tmpEnd >> PIX_BITS) + yInt);
+		yEndRem = (TUint32)(tmpEnd & REMAINDER);
+
+		//Read 11 lines from the source image
+		if (yEndInt >= 10)
+		{
+			aOriPtr->GetScanLine(Ptrs[lines[0]], TPoint(0, yEndInt-10), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[1]], TPoint(0, yEndInt-9), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[2]], TPoint(0, yEndInt-8), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[3]], TPoint(0, yEndInt-7), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[4]], TPoint(0, yEndInt-6), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[5]], TPoint(0, yEndInt-5), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[6]], TPoint(0, yEndInt-4), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[7]], TPoint(0, yEndInt-3), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[8]], TPoint(0, yEndInt-2), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[9]], TPoint(0, yEndInt-1), aOriSizeX, aOriPtr->DisplayMode());
+			aOriPtr->GetScanLine(Ptrs[lines[10]], TPoint(0, yEndInt  ), aOriSizeX, aOriPtr->DisplayMode());
+		}
+		else
+		{
+			if(yEndInt >= 0)
+				aOriPtr->GetScanLine(Ptrs[lines[10]], TPoint(0, yEndInt  ), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 1)
+				aOriPtr->GetScanLine(Ptrs[lines[9]], TPoint(0, yEndInt-1), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 2)
+				aOriPtr->GetScanLine(Ptrs[lines[8]], TPoint(0, yEndInt-2), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 3)
+				aOriPtr->GetScanLine(Ptrs[lines[7]], TPoint(0, yEndInt-3), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 4)
+				aOriPtr->GetScanLine(Ptrs[lines[6]], TPoint(0, yEndInt-4), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 5)
+				aOriPtr->GetScanLine(Ptrs[lines[5]], TPoint(0, yEndInt-5), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 6)
+				aOriPtr->GetScanLine(Ptrs[lines[4]], TPoint(0, yEndInt-6), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 7)
+				aOriPtr->GetScanLine(Ptrs[lines[3]], TPoint(0, yEndInt-7), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 8)
+				aOriPtr->GetScanLine(Ptrs[lines[2]], TPoint(0, yEndInt-8), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 9)
+				aOriPtr->GetScanLine(Ptrs[lines[1]], TPoint(0, yEndInt-9), aOriSizeX, aOriPtr->DisplayMode());
+			if(yEndInt >= 10)
+				aOriPtr->GetScanLine(Ptrs[lines[0]], TPoint(0, yEndInt-10), aOriSizeX, aOriPtr->DisplayMode());
+		}
+		LastLine = (TInt32)(yEndInt);
+
+		// Loop y for result image
+		for(y = (TInt32)yLoopSta; y < (TInt32)yLoopEnd; y++)
+		{
+			// Calculate used y pixels
+			tmpSta = (TInt)(yRem - yAver + HALF_PIX + HALF_WEI);
+			yStaInt = (TInt32)((tmpSta >> PIX_BITS) + yInt);
+			yStaRem = (TUint32)(tmpSta & REMAINDER);
+
+			tmpEnd = (TInt)(yRem + yAver + HALF_PIX + HALF_WEI);
+			yEndInt = (TInt32)((tmpEnd >> PIX_BITS) + yInt);
+			yEndRem = (TUint32)(tmpEnd & REMAINDER);
+
+			//Read a new line from the source image if needed
+			while (yEndInt > LastLine && LastLine < aOriSizeY-1)
+			{
+				LastLine++;
+				tmpline = lines[0];
+				lines[0] = lines[1];
+				lines[1] = lines[2];
+				lines[2] = lines[3];
+				lines[3] = lines[4];
+				lines[4] = lines[5];
+				lines[5] = lines[6];
+				lines[6] = lines[7];
+				lines[7] = lines[8];
+				lines[8] = lines[9];
+				lines[9] = lines[10];
+				lines[10] = tmpline;
+
+				if(LastLine >= 0)
+					aOriPtr->GetScanLine(Ptrs[lines[10]], TPoint(0, LastLine), aOriSizeX, aOriPtr->DisplayMode());
+			}
+
+			//Set pixel pointer to beginning of destination line
+			DataPtr = (TUint8*)scanLine->Des().Ptr();
+
+			// Calculate column weights and weight sum
+			yStaWei = (TUint32)((PIXEL - yStaRem - 1) >> DIF1_BITS);
+			yEndWei = (TUint32)((yEndRem) >> DIF1_BITS);
+			yAllWei = (TUint32)(yStaWei + ((yEndInt - yStaInt - 1) << WEI_BITS) + yEndWei);
+
+			// Check that the weight sum is not too big
+			if(yAllWei > yMaxWei)
+			{
+				if(((yEndRem) & REM_HDIF1) > ((PIXEL - yStaRem) & REM_HDIF1))
+				{
+					yStaWei -= 1;
+				}
+				else
+				{
+					yEndWei -= 1;
+				}
+				yAllWei -= 1;
+			}
+
+			// Initialise x position
+			xInt = xFirstInt;
+			xRem = xFirstRem;
+
+			// Calculate only the panned image
+			if(newShiftX > 0)
+			{
+				tmpPtr = DataPtr;	
+				tempPtr = tmpPtr + newShiftX * 3;
+
+				// Copy available image to the beginning of line
+				for(x = 0; x < (TInt32)xLoopSta; x++)
+				{
+					*tmpPtr++ = *tempPtr++;
+					*tmpPtr++ = *tempPtr++;
+					*tmpPtr++ = *tempPtr++;	
+				}
+			}
+			else if(newShiftX < 0)
+			{
+				tmpPtr = DataPtr + 3 * aOutSizeX - 1;	
+				tempPtr = tmpPtr + newShiftX * 3;
+
+				// Copy available image to the end of line
+				for(x = (TInt32)(aOutSizeX - 1); x >= (TInt32)xLoopEnd; x--)
+				{
+					*tmpPtr-- = *tempPtr--;
+					*tmpPtr-- = *tempPtr--;
+					*tmpPtr-- = *tempPtr--;	
+				}
+			}
+
+				LineNum = (TUint32)((yStaInt - LastLine + 10) % 11);
+
+			// Loop x for result image
+			for(x = (TInt32)xLoopSta; x < (TInt32)xLoopEnd; x++)
+			{
+				// Calculate used x pixels
+				tmpSta = (TInt)(xRem - xAver + HALF_PIX + HALF_WEI);
+				xStaInt = (TInt32)((tmpSta >> PIX_BITS) + xInt);
+				xStaRem = (TUint32)((tmpSta & REMAINDER));
+
+				tmpEnd = (TInt)(xRem + xAver + HALF_PIX + HALF_WEI);
+				xEndInt = (TInt32)((tmpEnd >> PIX_BITS) + xInt);
+				xEndRem = (TUint32)(tmpEnd & REMAINDER);
+
+				// Calculate line weights and weight sum
+				xStaWei = (TUint32)((PIXEL - xStaRem - 1) >> DIF1_BITS);
+				xEndWei = (TUint32)((xEndRem) >> DIF1_BITS);
+				xAllWei = (TUint32)(xStaWei + ((xEndInt - xStaInt - 1) << WEI_BITS) + xEndWei);
+
+				// Check that the weight sum is not too big
+				if(xAllWei > xMaxWei)
+				{
+					if(((xEndRem) & REM_HDIF1) > ((PIXEL - xStaRem) & REM_HDIF1))
+					{
+						xStaWei -= 1;
+					}
+					else
+					{
+						xEndWei -= 1;
+					}
+					xAllWei -= 1;
+				}
+
+				// Calculate filter divider for filter window
+				divider = (TInt)((xAllWei * yAllWei + HALF_RED) >> RED_BITS);
+
+				// Calculate pixel values
+				outFlag = 0;
+
+				// Initialise block result
+				sumB = 0;
+				sumG = 0;
+				sumR = 0;
+
+				LineNum = (TUint32)((yStaInt - LastLine + 10) % 11);
+
+				// Accumulate first line
+				if(yStaWei != 0)
+				{
+					// Line number
+					if(yStaInt < 0)		   		 outFlag = 1;
+					else if(yStaInt >= aOriSizeY) outFlag = 1;
+					else
+					{
+						// Initialise line result
+						tmpB = 0;
+						tmpG = 0;
+						tmpR = 0;
+
+						// First pixel in first line
+						if(xStaWei != 0)
+						{
+							// Column number
+							if(xStaInt < 0)				 outFlag = 1;
+							else if(xStaInt >= aOriSizeX) outFlag = 1;
+							else
+							{
+								// Pixel weighting to line result
+								tmpB = (TInt)(tmpB + (*(linePtrs[lines[LineNum]] + 3 * xStaInt))     * xStaWei);
+								tmpG = (TInt)(tmpG + (*(linePtrs[lines[LineNum]] + 3 * xStaInt + 1)) * xStaWei);
+								tmpR = (TInt)(tmpR + (*(linePtrs[lines[LineNum]] + 3 * xStaInt + 2)) * xStaWei);
+							}
+						}
+
+						// Middle pixels in first line
+						for(i = (TInt32)(xStaInt + 1); i < xEndInt; i++)
+						{
+							// Column number
+							if(i < 0)			   outFlag = 1;
+							else if(i >= aOriSizeX) outFlag = 1;
+							else
+							{
+								// Pixel weighting to line result
+								tmpB = (TInt)(tmpB + ((*(linePtrs[lines[LineNum]] + 3 * i    )) << WEI_BITS));
+								tmpG = (TInt)(tmpG + ((*(linePtrs[lines[LineNum]] + 3 * i + 1)) << WEI_BITS));
+								tmpR = (TInt)(tmpR + ((*(linePtrs[lines[LineNum]] + 3 * i + 2)) << WEI_BITS));
+							}
+						}
+
+						// Last pixel in first line
+						if(xEndWei != 0)
+						{
+							// Column number
+							if(xEndInt < 0)				 outFlag = 1;
+							else if(xEndInt >= aOriSizeX) outFlag = 1;
+							else
+							{
+								// Pixel weighting to line result
+								tmpB = (TInt)(tmpB + (*(linePtrs[lines[LineNum]] + 3 * xEndInt    )) * xEndWei);
+								tmpG = (TInt)(tmpG + (*(linePtrs[lines[LineNum]] + 3 * xEndInt + 1)) * xEndWei);
+								tmpR = (TInt)(tmpR + (*(linePtrs[lines[LineNum]] + 3 * xEndInt + 2)) * xEndWei);
+							}
+						}
+
+						// Pixel weighting to block result
+						sumB = (TInt)(sumB + ((yStaWei * tmpB + HALF_RED) >> RED_BITS));
+						sumG = (TInt)(sumG + ((yStaWei * tmpG + HALF_RED) >> RED_BITS));
+						sumR = (TInt)(sumR + ((yStaWei * tmpR + HALF_RED) >> RED_BITS));
+					}
+				}
+				LineNum++;
+
+				// Accumulate middle lines
+				for(j = (TInt32)(yStaInt + 1); j < yEndInt; j++)
+				{
+					// Line number 
+					if(j < 0)			   outFlag = 1;
+					else if(j >= aOriSizeY) outFlag = 1;
+					else
+					{
+						// Initialise line result
+						tmpB = 0;
+						tmpG = 0;
+						tmpR = 0;
+
+						// First pixel in middle lines
+						if(xStaWei != 0)
+						{
+							// Column number
+							if(xStaInt < 0)				 outFlag = 1;
+							else if(xStaInt >= aOriSizeX) outFlag = 1;
+							else
+							{
+								// Pixel weighting to line result
+								tmpB = (TInt)(tmpB + (*(linePtrs[lines[LineNum]] + 3 * xStaInt    )) * xStaWei);
+								tmpG = (TInt)(tmpG + (*(linePtrs[lines[LineNum]] + 3 * xStaInt + 1)) * xStaWei);
+								tmpR = (TInt)(tmpR + (*(linePtrs[lines[LineNum]] + 3 * xStaInt + 2)) * xStaWei);
+							}
+						}
+
+						// Middle pixels in middle lines
+						for(i = (TInt32)(xStaInt + 1); i < xEndInt; i++)
+						{
+							// Column number
+							if(i < 0)			   outFlag = 1;
+							else if(i >= aOriSizeX) outFlag = 1;
+							else
+							{
+								// Pixel weighting to line result
+								tmpB = (TInt)(tmpB + ((*(linePtrs[lines[LineNum]] + 3 * i    )) << WEI_BITS));
+								tmpG = (TInt)(tmpG + ((*(linePtrs[lines[LineNum]] + 3 * i + 1)) << WEI_BITS));
+								tmpR = (TInt)(tmpR + ((*(linePtrs[lines[LineNum]] + 3 * i + 2)) << WEI_BITS));
+							}
+						}
+
+						// Last pixel in middle lines
+						if(xEndWei != 0)
+						{
+							// Column number
+							if(xEndInt < 0)				 outFlag = 1;
+							else if(xEndInt >= aOriSizeX) outFlag = 1;
+							else
+							{
+								// Pixel weighting to line result
+								tmpB = (TInt)(tmpB + (*(linePtrs[lines[LineNum]] + 3 * xEndInt    )) * xEndWei);
+								tmpG = (TInt)(tmpG + (*(linePtrs[lines[LineNum]] + 3 * xEndInt + 1)) * xEndWei);
+								tmpR = (TInt)(tmpR + (*(linePtrs[lines[LineNum]] + 3 * xEndInt + 2)) * xEndWei);
+							}
+						}
+
+						// Pixel weighting to block result
+						sumB = (TInt)(sumB + (((tmpB << WEI_BITS) + HALF_RED) >> RED_BITS));
+						sumG = (TInt)(sumG + (((tmpG << WEI_BITS) + HALF_RED) >> RED_BITS));
+						sumR = (TInt)(sumR + (((tmpR << WEI_BITS) + HALF_RED) >> RED_BITS));
+					}
+					LineNum++;
+				}
+
+
+				// Accumulate last line
+				if(yEndWei != 0)
+				{
+					// Line number 
+					if(yEndInt < 0)				 outFlag = 1;
+					else if(yEndInt >= aOriSizeY) outFlag = 1;
+					else
+					{
+						// Initialise line result
+						tmpB = 0;
+						tmpG = 0;
+						tmpR = 0;
+
+						// First pixel in last line
+						if(xStaWei != 0)
+						{
+							// Column number
+							if(xStaInt < 0)				 outFlag = 1;
+							else if(xStaInt >= aOriSizeX) outFlag = 1;
+							else
+							{
+								tmpB = (TInt)(tmpB + (*(linePtrs[lines[LineNum]] + 3 * xStaInt    )) * xStaWei);
+								tmpG = (TInt)(tmpG + (*(linePtrs[lines[LineNum]] + 3 * xStaInt + 1)) * xStaWei);
+								tmpR = (TInt)(tmpR + (*(linePtrs[lines[LineNum]] + 3 * xStaInt + 2)) * xStaWei);
+							}
+						}
+
+						// Middle pixels in last line
+						for(i = (TInt32)(xStaInt + 1); i < xEndInt; i++)
+						{
+							// Column number
+							if(i < 0)			   outFlag = 1;
+							else if(i >= aOriSizeX) outFlag = 1;
+							else
+							{
+								tmpB = (TInt)(tmpB + ((*(linePtrs[lines[LineNum]] + 3 * i    )) << WEI_BITS));
+								tmpG = (TInt)(tmpG + ((*(linePtrs[lines[LineNum]] + 3 * i + 1)) << WEI_BITS));
+								tmpR = (TInt)(tmpR + ((*(linePtrs[lines[LineNum]] + 3 * i + 2)) << WEI_BITS));
+							}
+						}
+
+						// Last pixel in last line
+						if(xEndWei != 0)
+						{
+							// Column number
+							if(xEndInt < 0)				 outFlag = 1;
+							else if(xEndInt >= aOriSizeX) outFlag = 1;
+							else
+							{
+								tmpB = (TInt)(tmpB + (*(linePtrs[lines[LineNum]] + 3 * xEndInt    )) * xEndWei);
+								tmpG = (TInt)(tmpG + (*(linePtrs[lines[LineNum]] + 3 * xEndInt + 1)) * xEndWei);
+								tmpR = (TInt)(tmpR + (*(linePtrs[lines[LineNum]] + 3 * xEndInt + 2)) * xEndWei);
+							}
+						}
+
+						// Pixel weighting to block result
+						sumB = (TInt)(sumB + ((yEndWei * tmpB + HALF_RED) >> RED_BITS));
+						sumG = (TInt)(sumG + ((yEndWei * tmpG + HALF_RED) >> RED_BITS));
+						sumR = (TInt)(sumR + ((yEndWei * tmpR + HALF_RED) >> RED_BITS));
+					}
+				}
+				LineNum++;
+
+
+				// Pixels outside the original image are needed
+				if(outFlag > 0 || divider == 0)
+				{
+					// Save output values
+					*(DataPtr + x * 3    ) = 255;
+					*(DataPtr + x * 3 + 1) = 255;
+					*(DataPtr + x * 3 + 2) = 255;
+				}
+
+				// Pixels are inside the original image
+				else
+				{
+					if(divider == 1)
+					{
+						tmpB = sumB;
+						tmpG = sumG;
+						tmpR = sumR;
+					}
+					else if(divider == 2)
+					{
+						tmpB = (TInt)((sumB + 1) >> 1);
+						tmpG = (TInt)((sumG + 1) >> 1);
+						tmpR = (TInt)((sumR + 1) >> 1);
+					}
+					else if(divider == 4)
+					{
+						tmpB = (TInt)((sumB + 2) >> 2);
+						tmpG = (TInt)((sumG + 2) >> 2);
+						tmpR = (TInt)((sumR + 2) >> 2);
+					}
+					else if(divider == 8)
+					{
+						tmpB = (TInt)((sumB + 4) >> 3);
+						tmpG = (TInt)((sumG + 4) >> 3);
+						tmpR = (TInt)((sumR + 4) >> 3);
+					}
+					else if(divider == 16)
+					{
+						tmpB = (TInt)((sumB + 8) >> 4);
+						tmpG = (TInt)((sumG + 8) >> 4);
+						tmpR = (TInt)((sumR + 8) >> 4);
+					}
+					else if(divider == 32)
+					{
+						tmpB = (TInt)((sumB + 16) >> 5);
+						tmpG = (TInt)((sumG + 16) >> 5);
+						tmpR = (TInt)((sumR + 16) >> 5);
+					}
+					else if(divider == 64)
+					{
+						tmpB = (TInt)((sumB + 32) >> 6);
+						tmpG = (TInt)((sumG + 32) >> 6);
+						tmpR = (TInt)((sumR + 32) >> 6);
+					}
+					else if(divider == 128)
+					{
+						tmpB = (TInt)((sumB + 64) >> 7);
+						tmpG = (TInt)((sumG + 64) >> 7);
+						tmpR = (TInt)((sumR + 64) >> 7);
+					}
+					else if(divider == 256)
+					{
+						tmpB = (TInt)((sumB + 128) >> 8);
+						tmpG = (TInt)((sumG + 128) >> 8);
+						tmpR = (TInt)((sumR + 128) >> 8);
+					}
+					else if(divider == 512)
+					{
+						tmpB = (TInt)((sumB + 256) >> 9);
+						tmpG = (TInt)((sumG + 256) >> 9);
+						tmpR = (TInt)((sumR + 256) >> 9);
+					}
+					else if(divider == 1024)
+					{
+						tmpB = (TInt)((sumB + 512) >> 10);
+						tmpG = (TInt)((sumG + 512) >> 10);
+						tmpR = (TInt)((sumR + 512) >> 10);
+					}
+					else
+					{
+						tmpB = (TInt)(((sumB * KDivTable[divider - 2]) + 32768) >> 16);
+						tmpG = (TInt)(((sumG * KDivTable[divider - 2]) + 32768) >> 16);
+						tmpR = (TInt)(((sumR * KDivTable[divider - 2]) + 32768) >> 16);
+					}
+
+					// Save output values
+					if(tmpB > 255) 
+						*(DataPtr + x * 3    ) = 255;
+					else           
+						*(DataPtr + x * 3    ) = (TUint8)(tmpB);
+					if(tmpG > 255) 
+						*(DataPtr + x * 3 + 1) = 255;
+					else           
+						*(DataPtr + x * 3 + 1) = (TUint8)(tmpG);
+					if(tmpR > 255) 
+						*(DataPtr + x * 3 + 2) = 255;
+					else           
+						*(DataPtr + x * 3 + 2) = (TUint8)(tmpR);
+				}
+
+				// Update x position
+				tmpEnd = (TInt)(xRem + xStep);
+				xInt = (TInt32)(xInt + (tmpEnd >> PIX_BITS));
+				xRem = (TUint32)(tmpEnd & REMAINDER);
+			}
+
+			//Set processed line
+			aOutPtr->SetScanLine(linePtr, y);
+
+			// Update y position
+			tmpEnd = (TInt)(yRem + yStep);
+			yInt = (TInt32)(yInt + (tmpEnd >> PIX_BITS));
+			yRem = (TUint32)(tmpEnd & REMAINDER);
+		}
+		
+	// Delete local temporal line buffers (pop from CleanupStack)
+	CleanupStack::PopAndDestroy(12);	// scanLine, oriLine0 and oriLine1
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+  SetParams
+	
+  Set processing parameters
+	  
+  Return Values:  none
+		
+-----------------------------------------------------------------------------
+*/
+void CDCDigitalZoom::SetParameters(DCDigitalZoomParams* params)
+{
+	iParams = *params;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+  GetParams
+	
+  Get current processing parameters
+	  
+  Return Values:  none
+		
+-----------------------------------------------------------------------------
+*/
+void CDCDigitalZoom::GetParameters(DCDigitalZoomParams* params)
+{
+	*params = iParams;
+}
+//----IMAAMI----