--- a/imagehandlinglib/Src/CIHLScaler.cpp Fri Sep 03 10:29:37 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1315 +0,0 @@
-/*
-* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "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:
-*
-* Description: Implementation of Scaling processor
-* : using Font and Bitmap Server bitmaps.
-*
-*/
-
-// INCLUDE FILES
-#include "CIHLScaler.h"
-#include "IHLDebugPrint.h" // Debug print
-#include <MIHLImageViewer.h> // MIHLImageViewer
-#include <fbs.h>
-#include <hal.h>
-
-// Private namespace for constants and functions
-namespace
- {
- // Processed pixels per one activesheduler step
- const TInt KProcessPixelsPerStep = 16384;
-
- // These make the fast path scalings step out about every 5-10ms
- // no reason to cut more aggressively since it just slows down everything
- const TInt KBytesPerStepFastPath = 640*480;
- const TInt KBytesPerStepFastPathScaleOnly = 640*480*2;
-
- const TInt KStepPrecision = 16; // 16 bit = 65k subpixels
- const TInt KMaxProcessSize = KMaxTInt / 2;
- }
-
-//functions and typedefs used inside ProcessBilinear scaling
-namespace
- {
- // using our own RGB instead of TRGB as we need TInt32 for each value
- typedef struct
- {
- TInt32 r, g, b, a;
- } TColorRGB;
-
- // structure for handling data of 4 pixels
- typedef struct
- {
- TColorRGB colXY00, colXY01, colXY10, colXY11;
- TColorRGB col0, col1, col;
- } TPixelData;
-
- // functions to handle conversion between TColorRGB and colr value stored in TInt32
- inline void IntToRgb(TInt32 aIntRGB_val, TColorRGB &col)
- {
- col.r = (aIntRGB_val >> 16) & 0x00ff;
- col.g = (aIntRGB_val >> 8) & 0x00ff;
- col.b = aIntRGB_val & 0x00ff;
- col.a = (aIntRGB_val >> 24) & 0x00ff;
- }
- inline TUint32 RgbToInt(TColorRGB &col)
- {
- return 0x00000000 | ( ( col.r & 0xff) << 16 ) | ( ( col.g & 0xff) << 8 )
- | ( col.b & 0xff) | ( ( col.a & 0xff) << 24 );
- }
-
- // function which interpolates color using gathered data
- inline void ProcessColorData( TPixelData &dat, TPoint aSrcPos )
- {
- TInt32 pixel_width = 1 << KStepPrecision;
-
- //first pass (Y axis)
- dat.col0.r = (dat.colXY01.r - dat.colXY00.r)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY00.r;
- dat.col0.g = (dat.colXY01.g - dat.colXY00.g)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY00.g;
- dat.col0.b = (dat.colXY01.b - dat.colXY00.b)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY00.b;
- dat.col0.a = (dat.colXY01.a - dat.colXY00.a)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY00.a;
-
- dat.col1.r = (dat.colXY11.r - dat.colXY10.r)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY10.r;
- dat.col1.g = (dat.colXY11.g - dat.colXY10.g)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY10.g;
- dat.col1.b = (dat.colXY11.b - dat.colXY10.b)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY10.b;
- dat.col1.a = (dat.colXY11.a - dat.colXY10.a)*(aSrcPos.iY % pixel_width) / pixel_width + dat.colXY10.a;
-
- //second pass (X axis)
- dat.col.r = (dat.col1.r - dat.col0.r)*(aSrcPos.iX % pixel_width) / pixel_width + dat.col0.r;
- dat.col.g = (dat.col1.g - dat.col0.g)*(aSrcPos.iX % pixel_width) / pixel_width + dat.col0.g;
- dat.col.b = (dat.col1.b - dat.col0.b)*(aSrcPos.iX % pixel_width) / pixel_width + dat.col0.b;
- dat.col.a = (dat.col1.a - dat.col0.a)*(aSrcPos.iX % pixel_width) / pixel_width + dat.col0.a;
- }
- }
-
-// ======================== STATIC FACTORY FUNCTION ============================
-// -----------------------------------------------------------------------------
-// IHLScaler::CreateL
-// -----------------------------------------------------------------------------
-//
-EXPORT_C MIHLScaler* IHLScaler::CreateL( const TUint32 aOptions )
- {
- return CIHLScaler::NewL( aOptions );
- }
-
-// ============================ MEMBER FUNCTIONS ===============================
-// -----------------------------------------------------------------------------
-//
-// C++ default constructor can NOT contain any code, that
-// might leave.
-// -----------------------------------------------------------------------------
-CIHLScaler::CIHLScaler( const TUint32 aOptions )
-:CActive( CActive::EPriorityStandard ), iOptions( aOptions )
- {
- CActiveScheduler::Add( this );
- }
-
-// -----------------------------------------------------------------------------
-//
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-CIHLScaler* CIHLScaler::NewL( const TUint32 aOptions )
- {
- CIHLScaler* self = new( ELeave ) CIHLScaler( aOptions );
- return self;
- }
-
-// -----------------------------------------------------------------------------
-// Destructor
-// -----------------------------------------------------------------------------
-CIHLScaler::~CIHLScaler()
- {
- Cancel();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::Scale
-// -----------------------------------------------------------------------------
-TInt CIHLScaler::Scale( TRequestStatus& aStatus,
- const CFbsBitmap& aSrcBitmap, const TRect& aSrcRect,
- CFbsBitmap& aDstBitmap, const TRect& aDstRect )
- {
- if( IsBusy() )
- {
- return KErrNotReady;
- }
-
- TSize srcRectSize( aSrcRect.Size() );
- TSize dstRectSize( aDstRect.Size() );
- if( Abs( srcRectSize.iWidth ) > KMaxProcessSize ||
- Abs( srcRectSize.iHeight ) > KMaxProcessSize ||
- Abs( dstRectSize.iWidth ) > KMaxProcessSize ||
- Abs( dstRectSize.iHeight ) > KMaxProcessSize )
- {
- return KErrTooBig;
- }
-
- if( !aSrcBitmap.Handle() ||
- !IsValidRect( aSrcBitmap.SizeInPixels(), aSrcRect ) )
- {
- return KErrArgument;
- }
-
- if( aDstBitmap.Handle() )
- {
- if( !IsValidRect( aDstBitmap.SizeInPixels(), aDstRect ) )
- {
- return KErrArgument;
- }
- }
- else
- {
- // Create destination bitmap
- TSize dstSize( Abs( dstRectSize.iWidth ), Abs( dstRectSize.iHeight ) );
- TInt err = aDstBitmap.Create( dstSize, aSrcBitmap.DisplayMode() );
- if( err )
- {
- return err;
- }
- }
-
-#ifdef RD_MEASURE_THROUGHPUT
- iStartTime = User::FastCounter(); // For measuring scaler throughput
-#endif
-
- TSize srcSize( aSrcBitmap.SizeInPixels() );
- TSize dstSize( aDstBitmap.SizeInPixels() );
-
- if( srcSize.iWidth == 0 || srcSize.iHeight == 0 ||
- dstSize.iWidth == 0 || dstSize.iHeight == 0 ||
- aSrcRect.iTl.iX == aSrcRect.iBr.iX ||
- aSrcRect.iTl.iY == aSrcRect.iBr.iY ||
- aDstRect.iTl.iX == aDstRect.iBr.iX ||
- aDstRect.iTl.iY == aDstRect.iBr.iY )
- {
- // Bitmap or rect width or height is zero so there is nothing to do.
- // Complete process without error.
- iNeedProcess = EFalse;
- }
- else
- {
- iNeedProcess = ETrue;
-
- // Set parameters to member data references
- iSrcBitmap = &aSrcBitmap;
- iSrcRect = aSrcRect;
- iDstBitmap = &aDstBitmap;
- iDstRect = aDstRect;
-
- TDisplayMode srcMode(iSrcBitmap->DisplayMode());
- TDisplayMode dstMode(iDstBitmap->DisplayMode());
-
- IHL_DEBUG3( KIHLDebug1, "CIHLScaler: src bitmap size %dx%d", srcSize.iWidth, srcSize.iHeight);
- IHL_DEBUG3( KIHLDebug2, "CIHLScaler: dst bitmap size %dx%d", dstSize.iWidth, dstSize.iHeight);
- IHL_DEBUG5( KIHLDebug3, "CIHLScaler: src bitmap rect %d.%d -> %d.%d", iSrcRect.iTl.iX, iSrcRect.iTl.iY, iSrcRect.iBr.iX, iSrcRect.iBr.iY);
- IHL_DEBUG5( KIHLDebug4, "CIHLScaler: dst bitmap rect %d.%d -> %d.%d", iDstRect.iTl.iX, iDstRect.iTl.iY, iDstRect.iBr.iX, iDstRect.iBr.iY);
- IHL_DEBUG2( KIHLDebug5, "CIHLScaler: src bitmap mode %d", srcMode);
- IHL_DEBUG2( KIHLDebug6, "CIHLScaler: dst bitmap mode %d", dstMode);
- IHL_DEBUG2( KIHLDebug7, "CIHLScaler: src compressed %d", iSrcBitmap->IsCompressedInRAM());
- IHL_DEBUG2( KIHLDebug8, "CIHLScaler: dst compressed %d", iSrcBitmap->IsCompressedInRAM());
-
- // Init stepper values
- TBool onlyScaling = InitStepperValues();
-
- // Select correct code path
- InitCodePath(srcSize, srcMode, dstSize, dstMode, onlyScaling);
- }
-
- IHL_DEBUG1( KIHLDebug, "IHL - CIHLScaler - Start bitmap scaling" );
-
- // Start processing
- iScalerStatus = &aStatus;
- *iScalerStatus = KRequestPending;
-
- SelfComplete();
- return KErrNone;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::IsBusy
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::IsBusy() const
- {
- return IsActive();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::CancelProcess
-// -----------------------------------------------------------------------------
-void CIHLScaler::CancelProcess()
- {
- Cancel();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::SetFilter
-// -----------------------------------------------------------------------------
-void CIHLScaler::SetFilter( MIHFilter* /*aFilter*/ )
- {
- // Not in use
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::DoCancel
-// -----------------------------------------------------------------------------
-void CIHLScaler::DoCancel()
- {
- RequestComplete( KErrCancel );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::RunL
-// -----------------------------------------------------------------------------
-void CIHLScaler::RunL()
- {
- User::LeaveIfError( iStatus.Int() );
-
- // Process bitmap (this if-else may look weird but it removes one extra triggering of the AS
- if( iNeedProcess )
- {
- // Call the selected code path directly via a function pointer
- iNeedProcess = (this->*ProcessingFunc)();
- }
-
- if(!iNeedProcess)
- {
-#ifdef RD_MEASURE_THROUGHPUT
- // Calculate throughput
- TUint32 end = User::FastCounter();
-
- TInt tickPeriod;
- HAL::Get(HALData::EFastCounterFrequency, tickPeriod);
- TReal time = TReal(end-iStartTime) / TReal(tickPeriod);
- TReal bytes = iProcessSize.iWidth*iProcessSize.iHeight*2;
-
- IHL_DEBUG3("IHL - CIHLScaler - Scaling complete, %.3f ms, %.3f MB/s", time*1000.0, (bytes/time)/1024.0/1024.0);
-#else
- IHL_DEBUG1( KIHLDebug, "IHL - CIHLScaler - Scaling complete!" );
-#endif
- // Process complete
- RequestComplete( KErrNone );
- }
- else
- {
- // Another round
- SelfComplete();
- }
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::RunError
-// -----------------------------------------------------------------------------
-TInt CIHLScaler::RunError( TInt aError )
- {
- IHL_DEBUG2( KIHLDebug, "IHL - CIHLScaler - Scaling error: %d", aError );
-
- RequestComplete( aError );
- return KErrNone;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::IsValidRect
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::IsValidRect( const TSize& aSize, const TRect& aRect )
- {
- if( aRect.iTl.iX >= 0 &&
- aRect.iTl.iX <= aSize.iWidth &&
- aRect.iTl.iY >= 0 &&
- aRect.iTl.iY <= aSize.iHeight &&
- aRect.iBr.iX >= 0 &&
- aRect.iBr.iX <= aSize.iWidth &&
- aRect.iBr.iY >= 0 &&
- aRect.iBr.iY <= aSize.iHeight )
- {
- return ETrue;
- }
- return EFalse;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::InitStepperValues
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::InitStepperValues()
- {
- TBool onlyScaling = EFalse;
-
- TSize srcRectSize( Abs( iSrcRect.Width() ), Abs( iSrcRect.Height() ) );
- TSize dstRectSize( Abs( iDstRect.Width() ), Abs( iDstRect.Height() ) );
-
- TReal srcW = srcRectSize.iWidth << KStepPrecision;
- TReal srcH = srcRectSize.iHeight << KStepPrecision;
-
- // -----------------------------------------
- // Set source start point and increment
- // -----------------------------------------
- if( iSrcRect.iTl.iX > iSrcRect.iBr.iX &&
- iSrcRect.iTl.iY < iSrcRect.iBr.iY )
- {
- TReal incrementInner( srcH / TReal(dstRectSize.iWidth) );
- TReal incrementOuter( srcW / TReal(dstRectSize.iHeight) );
-
- iSrcIncrementInner.iX = 0;
- iSrcIncrementInner.iY = incrementInner;
- iSrcIncrementOuter.iX = -incrementOuter;
- iSrcIncrementOuter.iY = 0;
-
- iSrcPos.SetXY( (iSrcRect.iTl.iX << KStepPrecision) - (incrementOuter / 2.0),
- (iSrcRect.iTl.iY << KStepPrecision) + (incrementInner / 2.0) );
- }
- else if ( iSrcRect.iTl.iX > iSrcRect.iBr.iX &&
- iSrcRect.iTl.iY > iSrcRect.iBr.iY )
- {
- TReal incrementInner( srcW / TReal(dstRectSize.iWidth) );
- TReal incrementOuter( srcH / TReal(dstRectSize.iHeight) );
-
- iSrcIncrementInner.iX = -incrementInner;
- iSrcIncrementInner.iY = 0;
- iSrcIncrementOuter.iX = 0;
- iSrcIncrementOuter.iY = -incrementOuter;
-
- iSrcPos.SetXY( (iSrcRect.iTl.iX << KStepPrecision) - (incrementInner / 2.0),
- (iSrcRect.iTl.iY << KStepPrecision) - (incrementOuter / 2.0) );
- }
- else if ( iSrcRect.iTl.iX < iSrcRect.iBr.iX &&
- iSrcRect.iTl.iY > iSrcRect.iBr.iY )
- {
- TReal incrementInner( srcH / TReal(dstRectSize.iWidth) );
- TReal incrementOuter( srcW / TReal(dstRectSize.iHeight) );
-
- iSrcIncrementInner.iX = 0;
- iSrcIncrementInner.iY = -incrementInner;
- iSrcIncrementOuter.iX = incrementOuter;
- iSrcIncrementOuter.iY = 0;
-
- iSrcPos.SetXY( (iSrcRect.iTl.iX << KStepPrecision) + (incrementOuter / 2.0),
- (iSrcRect.iTl.iY << KStepPrecision) - (incrementInner / 2.0) );
- }
- else
- {
- TReal incrementInner( srcW / TReal(dstRectSize.iWidth) );
- TReal incrementOuter( srcH / TReal(dstRectSize.iHeight) );
-
- IHL_DEBUG3(KIHLDebug, "incrementInner: %f, incrementOuter: %f", incrementInner, incrementOuter);
-
- iSrcIncrementInner.iX = incrementInner;
- iSrcIncrementInner.iY = 0;
- iSrcIncrementOuter.iX = 0;
- iSrcIncrementOuter.iY = incrementOuter;
-
- iSrcPos.SetXY( (iSrcRect.iTl.iX << KStepPrecision) + (incrementInner / 2.0),
- (iSrcRect.iTl.iY << KStepPrecision) + (incrementOuter / 2.0) );
-
- onlyScaling = ETrue;
- }
-
- // -----------------------------------------
- // Set destination start point and increment
- // -----------------------------------------
-
- iDstPos.iX = iDstRect.iTl.iX;
- iDstIncrementInner = 1;
- iDstPos.iY = iDstRect.iTl.iY;
- iDstIncrementOuter = 1;
-
- if( iDstRect.iTl.iX > iDstRect.iBr.iX )
- {
- // From right to left
- iDstPos.iX--;
- iDstIncrementInner = -1;
- onlyScaling = EFalse;
- }
-
- if( iDstRect.iTl.iY > iDstRect.iBr.iY )
- {
- // From bottom to up
- iDstPos.iY--;
- iDstIncrementOuter = -1;
- onlyScaling = EFalse;
- }
-
- // -----------------------------------------
- // Reset process counters
- // -----------------------------------------
- iProcessInner = 0;
- iProcessOuter = 0;
- iProcessSize = dstRectSize;
-
- // These are for fast code path
-
- // Init how many scanlines to process
- iScanlinesLeft = iProcessSize.iHeight;
-
- return onlyScaling;
- }
-
-
-// Optimize the fast code paths properly for ARM
-#ifdef __ARMCC__
-#pragma push
-#pragma O3
-#pragma Otime
-#pragma arm
-#endif
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::ProcessNearestNeighbour64K
-// Description: Scales & rotates 64K color bitmaps
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::ProcessNearestNeighbour64K()
- {
- // Lock bitmap heaps
- iSrcBitmap->LockHeap();
- iDstBitmap->LockHeap();
-
- // Pointers to start of bitmap data
- TUint16 *srcBitmapPtr = (TUint16*)iSrcBitmap->DataAddress();
- TUint16 *dstBitmapPtr = (TUint16*)iDstBitmap->DataAddress();
-
- // Get pointer to correct destination pixel (offset is updated after every round)
- register TUint16* dst = dstBitmapPtr + iDstStartOffset;
-
- TUint32 width = iProcessSize.iWidth;
-
- // Check how many scanlines we can process this round
- register TUint32 scanlinesLeft = iScanlinesLeft;
- if(scanlinesLeft>iScanlinesPerRound)
- {
- scanlinesLeft = iScanlinesPerRound;
- }
-
- // How many scanlines left for the next round
- iScanlinesLeft-=scanlinesLeft;
-
- // Faster access to variables (it's slow to use member variables)
- register TInt srcPosX(iSrcPos.iX);
- register TInt srcPosY(iSrcPos.iY);
- register TInt srcPitch = iSrcPitchInPixels;
-
- TInt incOuterSrcX = (-iSrcIncrementInner.iX * width) + iSrcIncrementOuter.iX;
- TInt incOuterSrcY = (-iSrcIncrementInner.iY * width) + iSrcIncrementOuter.iY;
-
- while(scanlinesLeft!=0)
- {
- for(register TUint32 x = width; x!=0; x--)
- {
- register TUint16* src = srcBitmapPtr + ((srcPosY >> KStepPrecision) * srcPitch) + (srcPosX>>KStepPrecision);
- *dst = *src;
-
- // Add inner counters
- srcPosX+=iSrcIncrementInner.iX;
- srcPosY+=iSrcIncrementInner.iY;
-
- dst+=iDstIncrementInner;
- }
-
- // Reset inner counters and add outer counters
- srcPosX += incOuterSrcX;
- srcPosY += incOuterSrcY;
-
- // Move destination pointer to next pixel
- dst += iDstResidualPixels;
-
- // One scanline done, n to go
- scanlinesLeft--;
- }
- // Unlock bitmap heaps
- iDstBitmap->UnlockHeap();
- iSrcBitmap->UnlockHeap();
-
- if(iScanlinesLeft)
- {
- // Not all scanlines were processed yet
-
- // Save the necessary offsets for next round
- iSrcPos.iX = srcPosX;
- iSrcPos.iY = srcPosY;
- iDstStartOffset = dst - dstBitmapPtr;
-
- return ETrue;
- }
-
- // Processing done
- return EFalse;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::ProcessNearestNeighbour64KScaleOnly
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::ProcessNearestNeighbour64KScaleOnly()
- {
- // Lock bitmap heaps
- iSrcBitmap->LockHeap();
- iDstBitmap->LockHeap();
-
- // Get bitmap data start addresses
- TUint16 *srcBitmapPtr = (TUint16*)iSrcBitmap->DataAddress();
- TUint16 *dstBitmapPtr = (TUint16*)iDstBitmap->DataAddress();
-
- // Target height and width
- TInt width = iProcessSize.iWidth;
-
- // fixed point source coordinates
- TInt startX = iSrcPos.iX;
- TInt srcY = iSrcPos.iY;
-
- // How much to increase src position (in fixed point)
- TInt srcYIncrement = iSrcIncrementOuter.iY;
- register TInt srcXIncrement = iSrcIncrementInner.iX;
-
- // Set pointers to correct location (src = start of scanline, dst = start pixel)
- register TUint16* dst = dstBitmapPtr + iDstStartOffset;
-
- // Calculate how many scanlines we can process this round
- register TInt scanlinesLeft = iScanlinesLeft;
- if(scanlinesLeft>iScanlinesPerRound)
- {
- scanlinesLeft = iScanlinesPerRound;
- }
-
- iScanlinesLeft-=scanlinesLeft;
-
- while(scanlinesLeft--)
- {
- // Outer loop
-
- // Reset src X and scanline pointer
- register TInt srcX = startX;
- register TUint16* src = srcBitmapPtr + (srcY >> KStepPrecision) * iSrcPitchInPixels;
-
- // Init pixel counter
- register TUint32 pixels = width;
-
- // Unaligned pixels to the left of 8B-aligned section
- while((TUint32(dst)&0x7) && pixels)
- {
- *dst++ = (*(src + (srcX >> KStepPrecision)));
-
- srcX += srcXIncrement;
-
- pixels--;
- }
-
- // Aligned middle section
- register TUint32 middle = pixels&0xFFFFFFFC;
- pixels &= 0x3;
-
- while(middle)
- {
- // Read four pixels
- register TUint16 p1 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
- register TUint16 p2 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
- register TUint16 p3 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
- register TUint16 p4 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
-
- // Write four pixels
- *(dst++) = p1;
- *(dst++) = p2;
- *(dst++) = p3;
- *(dst++) = p4;
-
- middle-=4;
- }
-
- // Unaligned residual pixels to the right of 8-aligned section
- while(pixels)
- {
- *dst++ = (*(src + (srcX >> KStepPrecision)));
-
- srcX += srcXIncrement;
-
- pixels--;
- }
-
- // Move to next correct src scanline
- srcY += srcYIncrement;
-
- // Advance dst to start of correct pixel in the next row
- dst += iDstResidualPixels;
- }
-
- iDstBitmap->UnlockHeap();
- iSrcBitmap->UnlockHeap();
-
- if(iScanlinesLeft)
- {
- // Not all scanlines were processed yet
-
- // Save the necessary offsets for next round
- iSrcPos.iY = srcY;
- iDstStartOffset = dst - dstBitmapPtr;
-
- return ETrue;
- }
-
- return EFalse;
-
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::ProcessNearestNeighbour16MX
-// Description: Scales & rotates 16MU/MA color bitmaps
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::ProcessNearestNeighbour16MX()
- {
- // Lock bitmap heaps
- iSrcBitmap->LockHeap();
- iDstBitmap->LockHeap();
-
- // Pointers to start of bitmap data
- TUint32 *srcBitmapPtr = (TUint32*)iSrcBitmap->DataAddress();
- TUint32 *dstBitmapPtr = (TUint32*)iDstBitmap->DataAddress();
-
- // Get pointer to correct destination pixel (offset is updated after every round)
- register TUint32* dst = dstBitmapPtr + iDstStartOffset;
-
- TUint32 width = iProcessSize.iWidth;
-
- // Check how many scanlines we can process this round
- register TUint32 scanlinesLeft = iScanlinesLeft;
- if(scanlinesLeft>iScanlinesPerRound)
- {
- scanlinesLeft = iScanlinesPerRound;
- }
-
- // How many scanlines left for the next round
- iScanlinesLeft-=scanlinesLeft;
-
- // Faster access to variables (it's slow to use member variables)
- register TInt srcPosX(iSrcPos.iX);
- register TInt srcPosY(iSrcPos.iY);
- register TInt srcPitch = iSrcPitchInPixels;
-
- TInt incOuterSrcX = (-iSrcIncrementInner.iX * width) + iSrcIncrementOuter.iX;
- TInt incOuterSrcY = (-iSrcIncrementInner.iY * width) + iSrcIncrementOuter.iY;
-
- while(scanlinesLeft!=0)
- {
- for(register TUint32 x = width; x!=0; x--)
- {
- register TUint32* src = srcBitmapPtr + ((srcPosY >> KStepPrecision) * srcPitch) + (srcPosX>>KStepPrecision);
- *dst = *src;
-
- // Add inner counters
- srcPosX+=iSrcIncrementInner.iX;
- srcPosY+=iSrcIncrementInner.iY;
-
- dst+=iDstIncrementInner;
- }
-
- // Reset inner counters and add outer counters
- srcPosX += incOuterSrcX;
- srcPosY += incOuterSrcY;
-
- // Move destination pointer to next pixel
- dst += iDstResidualPixels;
-
- // One scanline done, n to go
- scanlinesLeft--;
- }
- // Unlock bitmap heaps
- iDstBitmap->UnlockHeap();
- iSrcBitmap->UnlockHeap();
-
- if(iScanlinesLeft)
- {
- // Not all scanlines were processed yet
-
- // Save the necessary offsets for next round
- iSrcPos.iX = srcPosX;
- iSrcPos.iY = srcPosY;
- iDstStartOffset = dst - dstBitmapPtr;
-
- return ETrue;
- }
-
- // Processing done
- return EFalse;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::ProcessNearestNeighbour64KScaleOnly
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::ProcessNearestNeighbour16MXScaleOnly()
- {
- // Lock bitmap heaps
- iSrcBitmap->LockHeap();
- iDstBitmap->LockHeap();
-
- // Get bitmap data start addresses
- TUint32 *srcBitmapPtr = (TUint32*)iSrcBitmap->DataAddress();
- TUint32 *dstBitmapPtr = (TUint32*)iDstBitmap->DataAddress();
-
- // Target height and width
- TInt width = iProcessSize.iWidth;
-
- // fixed point source coordinates
- TInt startX = iSrcPos.iX;
- TInt srcY = iSrcPos.iY;
-
- // How much to increase src position (in fixed point)
- TInt srcYIncrement = iSrcIncrementOuter.iY;
- register TInt srcXIncrement = iSrcIncrementInner.iX;
-
- // Set pointers to correct location (src = start of scanline, dst = start pixel)
- register TUint32* dst = dstBitmapPtr + iDstStartOffset;
-
- // Calculate how many scanlines we can process this round
- register TInt scanlinesLeft = iScanlinesLeft;
- if(scanlinesLeft>iScanlinesPerRound)
- {
- scanlinesLeft = iScanlinesPerRound;
- }
-
- iScanlinesLeft-=scanlinesLeft;
-
- while(scanlinesLeft--)
- {
- // Outer loop
-
- // Reset src X and scanline pointer
- register TInt srcX = startX;
- register TUint32* src = srcBitmapPtr + (srcY >> KStepPrecision) * iSrcPitchInPixels;
-
- // Init pixel counter
- register TUint32 pixels = width;
-
- // Unaligned pixels to the left of 16B-aligned section
- while((TUint32(dst)&0xF) && pixels)
- {
- *dst++ = (*(src + (srcX >> KStepPrecision)));
-
- srcX += srcXIncrement;
-
- pixels--;
- }
-
- // Aligned middle section
- register TUint32 middle = pixels&0xFFFFFFFC;
- pixels &= 0x3;
-
- while(middle)
- {
- // Read four pixels
- register TUint32 p1 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
- register TUint32 p2 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
- register TUint32 p3 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
- register TUint32 p4 = (*(src + (srcX >> KStepPrecision)));
- srcX += srcXIncrement;
-
- // Write four pixels
- *(dst+0) = p1;
- *(dst+1) = p2;
- *(dst+2) = p3;
- *(dst+3) = p4;
-
- middle-=4;
- dst+=4;
- }
-
- // Unaligned residual pixels to the right of 8-aligned section
- while(pixels)
- {
- *dst++ = (*(src + (srcX >> KStepPrecision)));
-
- srcX += srcXIncrement;
-
- pixels--;
- }
-
- // Move to next correct src scanline
- srcY += srcYIncrement;
-
- // Advance dst to start of correct pixel in the next row
- dst += iDstResidualPixels;
- }
-
- iDstBitmap->UnlockHeap();
- iSrcBitmap->UnlockHeap();
-
- if(iScanlinesLeft)
- {
- // Not all scanlines were processed yet
-
- // Save the necessary offsets for next round
- iSrcPos.iY = srcY;
- iDstStartOffset = dst - dstBitmapPtr;
-
- return ETrue;
- }
-
- return EFalse;
-
- }
-
-// Restore previous pragma state
-#ifdef __ARMCC__
-#pragma pop
-#endif
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::ProcessNearestNeighbour
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::ProcessNearestNeighbour()
- {
- // Util needs non-const pointers even if it's only used for reading pixels
- TBitmapUtil srcBitmap( const_cast<CFbsBitmap*>( iSrcBitmap ) );
- TBitmapUtil dstBitmap( iDstBitmap );
- srcBitmap.Begin( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.Begin( iDstPos ); // heap already locked by srcBitmap
- TInt pixelCounter( KProcessPixelsPerStep );
-
- // Start outer and inner process loops
- while( iProcessOuter < iProcessSize.iHeight && pixelCounter )
- {
- while( iProcessInner < iProcessSize.iWidth && pixelCounter )
- {
- srcBitmap.SetPos( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.SetPos( iDstPos );
- dstBitmap.SetPixel( srcBitmap );
-
- // Add inner counters
- iSrcPos += iSrcIncrementInner;
- iDstPos.iX += iDstIncrementInner;
- ++iProcessInner;
- --pixelCounter;
- }
- // Check if inner loop is finished (not just pixel counter)
- if( iProcessInner == iProcessSize.iWidth )
- {
- // Reset inner counters
- iSrcPos.iX -= iSrcIncrementInner.iX * iProcessInner;
- iSrcPos.iY -= iSrcIncrementInner.iY * iProcessInner;
-
- iDstPos.iX -= iDstIncrementInner * iProcessInner;
- iProcessInner = 0;
-
- // Add outer counters
- iSrcPos += iSrcIncrementOuter;
- iDstPos.iY += iDstIncrementOuter;
- ++iProcessOuter;
- }
- }
-
- // Release heap lock
- dstBitmap.End();
- srcBitmap.End();
-
- // ETrue if more processing is still needed
- return ( iProcessOuter < iProcessSize.iHeight );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::ProcessBilinear
-// -----------------------------------------------------------------------------
-TBool CIHLScaler::ProcessBilinear()
- {
- // Util needs non-const pointers
- //even if it's only used for reading pixels
- TBitmapUtil srcBitmap( const_cast<CFbsBitmap*>( iSrcBitmap ) );
- TBitmapUtil dstBitmap( iDstBitmap );
-
- srcBitmap.Begin( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.Begin( iDstPos ); // heap already locked by srcBitmap
- TInt pixelCounter( KProcessPixelsPerStep );
-
- TInt incSrcX = iSrcIncrementInner.iX + iSrcIncrementOuter.iX;
- TInt incSrcY = iSrcIncrementInner.iY + iSrcIncrementOuter.iY;
-
- TPixelData pixelData;
- TUint32 color;
-
- TInt32 pixel_width = 1 << KStepPrecision;
-
- //if there is no scaling then process through loop using NearestNeighbour alghoritm
- if ( incSrcX == pixel_width || -incSrcX == pixel_width )
- {
- while( iProcessOuter < iProcessSize.iHeight && pixelCounter )
- {
- while( iProcessInner < iProcessSize.iWidth && pixelCounter )
- {
- srcBitmap.SetPos( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.SetPos( iDstPos );
- dstBitmap.SetPixel( srcBitmap );
-
- // Add inner counters
- iSrcPos += iSrcIncrementInner;
- iDstPos.iX += iDstIncrementInner;
- ++iProcessInner;
- --pixelCounter;
- }
-
- // Check if inner loop is finished (not just pixel counter)
- if( iProcessInner == iProcessSize.iWidth )
- {
- // Reset inner counters
- iSrcPos.iX -= iSrcIncrementInner.iX * iProcessInner;
- iSrcPos.iY -= iSrcIncrementInner.iY * iProcessInner;
-
- iDstPos.iX -= iDstIncrementInner * iProcessInner;
- iProcessInner = 0;
-
- // Add outer counters
- iSrcPos += iSrcIncrementOuter;
- iDstPos.iY += iDstIncrementOuter;
- ++iProcessOuter;
- }
- }
- }
- // Process using bilinear method according to
- // orientation between source and destination bitmap
- //
- // There are 4 possibilities of orientation and can be
- // determined by this if we're increasing or decreasing
- // position on source bitmap.
- else if ( ( incSrcY >= 0) && (incSrcX >= 0 ) )
- {
- while( iProcessOuter < iProcessSize.iHeight && pixelCounter )
- {
- while( iProcessInner < iProcessSize.iWidth && pixelCounter )
- {
- srcBitmap.SetPos( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.SetPos( iDstPos );
-
- // gather pixel data with step:
- // 00 > 10
- // V
- // 01 < 11
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY00);
- srcBitmap.IncXPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY10);
- srcBitmap.IncYPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY11);
- srcBitmap.DecXPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY01);
- //return to starting position
- srcBitmap.DecYPos();
-
- // interpolate color using gathered pixel-data
- ProcessColorData(pixelData, iSrcPos);
-
- // put color in destination package
- color = RgbToInt(pixelData.col);
- dstBitmap.SetPixel(color);
-
- // Add inner counters
- iSrcPos += iSrcIncrementInner;
- iDstPos.iX += iDstIncrementInner;
- ++iProcessInner;
- --pixelCounter;
- }
-
- // Check if inner loop is finished (not just pixel counter)
- if( iProcessInner == iProcessSize.iWidth )
- {
- // Reset inner counters
- iSrcPos.iX -= iSrcIncrementInner.iX * iProcessInner;
- iSrcPos.iY -= iSrcIncrementInner.iY * iProcessInner;
-
- iDstPos.iX -= iDstIncrementInner * iProcessInner;
- iProcessInner = 0;
-
- // Add outer counters
- iSrcPos += iSrcIncrementOuter;
- iDstPos.iY += iDstIncrementOuter;
- ++iProcessOuter;
- }
- }
- }
- else if ( ( incSrcY >= 0) && (incSrcX < 0 ) )
- {
- while( iProcessOuter < iProcessSize.iHeight && pixelCounter )
- {
- while( iProcessInner < iProcessSize.iWidth && pixelCounter )
- {
- srcBitmap.SetPos( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.SetPos( iDstPos );
-
- // gather pixel data with step:
- // 00 10
- // /\ V
- // 01 < 11
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY10);
- srcBitmap.IncYPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY11);
- srcBitmap.DecXPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY01);
- srcBitmap.DecYPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY00);
- //return to starting position
- srcBitmap.IncXPos();
-
- // interpolate color using gathered pixel-data
- ProcessColorData(pixelData, iSrcPos);
-
- // put color in destination package
- color = RgbToInt(pixelData.col);
- dstBitmap.SetPixel(color);
-
- // Add inner counters
- iSrcPos += iSrcIncrementInner;
- iDstPos.iX += iDstIncrementInner;
- ++iProcessInner;
- --pixelCounter;
- }
-
- // Check if inner loop is finished (not just pixel counter)
- if( iProcessInner == iProcessSize.iWidth )
- {
- // Reset inner counters
- iSrcPos.iX -= iSrcIncrementInner.iX * iProcessInner;
- iSrcPos.iY -= iSrcIncrementInner.iY * iProcessInner;
-
- iDstPos.iX -= iDstIncrementInner * iProcessInner;
- iProcessInner = 0;
-
- // Add outer counters
- iSrcPos += iSrcIncrementOuter;
- iDstPos.iY += iDstIncrementOuter;
- ++iProcessOuter;
- }
-
- }
- }
- else if ( ( incSrcY < 0) && (incSrcX >= 0 ) )
- {
- while( iProcessOuter < iProcessSize.iHeight && pixelCounter )
- {
- while( iProcessInner < iProcessSize.iWidth && pixelCounter )
- {
- srcBitmap.SetPos( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.SetPos( iDstPos );
-
- // gather pixel data with step:
- // 00 > 10
- // /\ V
- // 01 11
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY01);
- srcBitmap.DecYPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY00);
- srcBitmap.IncXPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY10);
- srcBitmap.IncYPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY11);
- //return to starting position
- srcBitmap.DecXPos();
-
- // interpolate color using gathered pixel-data
- ProcessColorData(pixelData, iSrcPos);
-
- // put color in destination package
- color = RgbToInt(pixelData.col);
- dstBitmap.SetPixel(color);
-
- // Add inner counters
- iSrcPos += iSrcIncrementInner;
- iDstPos.iX += iDstIncrementInner;
- ++iProcessInner;
- --pixelCounter;
- }
-
- // Check if inner loop is finished (not just pixel counter)
- if( iProcessInner == iProcessSize.iWidth )
- {
- // Reset inner counters
- iSrcPos.iX -= iSrcIncrementInner.iX * iProcessInner;
- iSrcPos.iY -= iSrcIncrementInner.iY * iProcessInner;
-
- iDstPos.iX -= iDstIncrementInner * iProcessInner;
- iProcessInner = 0;
-
- // Add outer counters
- iSrcPos += iSrcIncrementOuter;
- iDstPos.iY += iDstIncrementOuter;
- ++iProcessOuter;
- }
- }
- }
- else
- {
- while( iProcessOuter < iProcessSize.iHeight && pixelCounter )
- {
- while( iProcessInner < iProcessSize.iWidth && pixelCounter )
- {
- srcBitmap.SetPos( TPoint( iSrcPos.iX >> KStepPrecision, iSrcPos.iY >> KStepPrecision ) );
- dstBitmap.SetPos( iDstPos );
-
- // gather pixel data with step:
- // 00 > 10
- // /\
- // 01 < 11
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY11);
- srcBitmap.DecXPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY01);
- srcBitmap.DecYPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY00);
- srcBitmap.IncXPos();
- IntToRgb(srcBitmap.GetPixel(),pixelData.colXY10);
- //return to starting position
- srcBitmap.IncYPos();
-
- // interpolate color using gathered pixel-data
- ProcessColorData(pixelData, iSrcPos);
-
- // put color in destination package
- color = RgbToInt(pixelData.col);
- dstBitmap.SetPixel(color);
-
- // Add inner counters
- iSrcPos += iSrcIncrementInner;
- iDstPos.iX += iDstIncrementInner;
- ++iProcessInner;
- --pixelCounter;
- }
-
- // Check if inner loop is finished (not just pixel counter)
- if( iProcessInner == iProcessSize.iWidth )
- {
- // Reset inner counters
- iSrcPos.iX -= iSrcIncrementInner.iX * iProcessInner;
- iSrcPos.iY -= iSrcIncrementInner.iY * iProcessInner;
-
- iDstPos.iX -= iDstIncrementInner * iProcessInner;
- iProcessInner = 0;
-
- // Add outer counters
- iSrcPos += iSrcIncrementOuter;
- iDstPos.iY += iDstIncrementOuter;
- ++iProcessOuter;
- }
-
- }
- }
-
- // Release heap lock
- dstBitmap.End();
- srcBitmap.End();
-
- // ETrue if more processing is still needed
- return ( iProcessOuter < iProcessSize.iHeight );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::SelfComplete
-// -----------------------------------------------------------------------------
-void CIHLScaler::SelfComplete()
- {
- SetActive();
- iStatus = KRequestPending;
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, KErrNone );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::RequestComplete
-// -----------------------------------------------------------------------------
-void CIHLScaler::RequestComplete( TInt aReason )
- {
- ASSERT( iScalerStatus );
- User::RequestComplete( iScalerStatus, aReason );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLScaler::InitCodePath
-// -----------------------------------------------------------------------------
-void CIHLScaler::InitCodePath(const TSize& aSrcSize, const TDisplayMode &aSrcMode, const TSize& aDstSize, const TDisplayMode &aDstMode, TBool aOnlyScaling)
- {
- // Choose the correct processing code path
- ProcessingFunc = &CIHLScaler::ProcessNearestNeighbour;
-
- if( iOptions & MIHLImageViewer::EOptionUseBilinearInterpolation )
- {
- // TODO: optimize bilinear scaling
- IHL_DEBUG("CIHLScaler::InitCodePath: slow bilinear");
- ProcessingFunc = &CIHLScaler::ProcessBilinear;
- iScanlinesPerRound = KProcessPixelsPerStep / iProcessSize.iWidth;
- }
- else if(aSrcMode == EColor64K && aSrcMode==aDstMode && !iSrcBitmap->IsCompressedInRAM() && !iDstBitmap->IsCompressedInRAM())
- {
- // 16 bit non-compressed bitmaps
-
- // Calculate how many pixels the scanline is actually wide in the memory
- iSrcPitchInPixels = CFbsBitmap::ScanLineLength( aSrcSize.iWidth, aSrcMode ) >> 1;
- iDstPitchInPixels = CFbsBitmap::ScanLineLength( aDstSize.iWidth, aDstMode ) >> 1;
-
- // How many pixels to move destination pointer at the end of each scanline to get to next pixel
- iDstResidualPixels = iDstIncrementOuter*iDstPitchInPixels - iDstIncrementInner*iProcessSize.iWidth;
-
- // Buffer offset to the first destination pixel
- iDstStartOffset = iDstPos.iY * iDstPitchInPixels + iDstPos.iX;
-
- if(!aOnlyScaling)
- {
- IHL_DEBUG("CIHLScaler::InitCodePath: fast 64K scale&rotate");
- ProcessingFunc = &CIHLScaler::ProcessNearestNeighbour64K;
-
- // Calculate how often the process should allow AS to run
- iScanlinesPerRound = KBytesPerStepFastPath / (iProcessSize.iWidth<<1);
- }
- else
- {
- IHL_DEBUG("CIHLScaler::InitCodePath: fast 64K scale only");
- ProcessingFunc = &CIHLScaler::ProcessNearestNeighbour64KScaleOnly;
-
- // Calculate how often the process should allow AS to run
- iScanlinesPerRound = KBytesPerStepFastPathScaleOnly / (iProcessSize.iWidth<<1);
- }
- }
-
- else if((aSrcMode == EColor16MU || aSrcMode == EColor16MA) && aSrcMode==aDstMode && !iSrcBitmap->IsCompressedInRAM() && !iDstBitmap->IsCompressedInRAM())
- {
- // 32 bit non-compressed bitmaps
-
- // Calculate how many pixels the scanline is actually wide in the memory
- iSrcPitchInPixels = CFbsBitmap::ScanLineLength( aSrcSize.iWidth, aSrcMode ) >> 2;
- iDstPitchInPixels = CFbsBitmap::ScanLineLength( aDstSize.iWidth, aDstMode ) >> 2;
-
- // How many pixels to move destination pointer at the end of each scanline to get to next pixel
- iDstResidualPixels = iDstIncrementOuter*iDstPitchInPixels - iDstIncrementInner*iProcessSize.iWidth;
-
- // Buffer offset to the first destination pixel
- iDstStartOffset = iDstPos.iY * iDstPitchInPixels + iDstPos.iX;
-
- if(!aOnlyScaling)
- {
- IHL_DEBUG("CIHLScaler::InitCodePath: fast 16MX scale&rotate");
- ProcessingFunc = &CIHLScaler::ProcessNearestNeighbour16MX;
-
- // Calculate how often the process should allow AS to run
- iScanlinesPerRound = KBytesPerStepFastPath / (iProcessSize.iWidth<<2);
- }
- else
- {
- IHL_DEBUG("CIHLScaler::InitCodePath: fast 16MX scale only");
- ProcessingFunc = &CIHLScaler::ProcessNearestNeighbour16MXScaleOnly;
-
- // Calculate how often the process should allow AS to run
- iScanlinesPerRound = KBytesPerStepFastPathScaleOnly / (iProcessSize.iWidth<<2);
- }
- }
- else
- {
- IHL_DEBUG("CIHLScaler::InitCodePath: slow nearest neighbor");
- iScanlinesPerRound = KProcessPixelsPerStep / iProcessSize.iWidth;
- }
-
- IHL_DEBUG2(KIHLDebug, "CIHLScaler::InitCodePath: scanlines per round = %d", iScanlinesPerRound);
- }
-
-// End of File