diff -r 000000000000 -r 951a5db380a0 videoeditorengine/vedengine/GenManip/src/DCDigitalZoom.cpp --- /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 +#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----