vtprotocolplugins/DisplaySink/src/CVtImageScalerImplNearest.cpp
changeset 0 ed9695c8bcbe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vtprotocolplugins/DisplaySink/src/CVtImageScalerImplNearest.cpp	Mon Nov 23 14:47:47 2009 +0200
@@ -0,0 +1,522 @@
+/*
+* 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:  Image Transforms subsystem.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <e32svr.h>
+#include <fbs.h>
+
+#include "CVtImageScalerImplNearest.h"
+#include "cvtimage.h"
+
+// MACROS
+
+#ifdef _DEBUG
+#    define __IF_DEBUG(t) {RDebug::t;}
+#else
+#    define __IF_DEBUG(t)
+#endif
+
+// LOCAL CONSTANTS AND MACROS
+
+const TUint32 KDecimalBits = 16;        // 16.16 pseudo real format
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ======================= CVtImageScalerImplNearest =======================
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale( TBool& aContinue )
+// -----------------------------------------------------------------------------
+TInt CVtImageScalerImplNearest::Scale( TBool& aContinue )
+    {
+    TInt result( KErrNone );
+
+    aContinue = EFalse;
+
+    // this implementation does not support different display modes for source
+    // and target
+    if( iSource->DisplayMode() != iTarget->DisplayMode() )
+        {
+        return KErrNotSupported;
+        }
+
+    // if sizes are same, just copy the data
+    if( iSource->Size() == iTarget->Size() )
+        {
+        Mem::Copy(
+            iTarget->DataAddress(),
+            iSource->DataAddress(),
+            iTarget->BytesPerRow() * iTarget->Size().iHeight );
+        }
+    else if( ( iSource->Size().iHeight * 2 == iTarget->Size().iHeight ) &&
+        ( iSource->Size().iWidth * 2 == iTarget->Size().iWidth ) )
+        {
+        switch( iSource->DisplayMode() )
+            {
+            case CVtImage::EVtColor4K:
+            case CVtImage::EVtColor64K:
+                Scale2x4K64K();
+                break;
+
+            case CVtImage::EVtColor16M:
+                Scale2x16M();
+                break;
+
+            case CVtImage::EVtColor16MU:
+            case CVtImage::EVtColor16MA:
+                Scale2x16MU16MA();
+                break;
+
+            default:
+                if ( iSource->Type() == CVtImage::EVtImageBitmap &&
+                     iTarget->Type() == CVtImage::EVtImageBitmap )
+                    {
+                    TRAPD( error,
+                        ScaleWithBitmapScalerL(
+                            CBitmapScaler::EMinimumQuality ) );
+                    result = error;
+                    }
+                else
+                    {
+                    result = KErrNotSupported;
+                    }
+            }
+        }
+    else
+        {
+        Initialize();
+
+        switch( iSource->DisplayMode() )
+            {
+            case CVtImage::EVtColor4K:
+                Scale4K(
+                    reinterpret_cast< const TUint16* >(
+                        iSource->DataAddress() ),
+                    iSource->BytesPerRow(),
+                    reinterpret_cast< TUint16* >( iTarget->DataAddress() ),
+                    iTarget->Size().iWidth,
+                    iTarget->Size().iHeight,
+                    iU,
+                    iV );
+                break;
+
+            case CVtImage::EVtColor64K:
+                Scale64K(
+                    reinterpret_cast< const TUint16* >(
+                        iSource->DataAddress() ),
+                    iSource->BytesPerRow(),
+                    reinterpret_cast< TUint16* >( iTarget->DataAddress() ),
+                    iTarget->Size().iWidth,
+                    iTarget->Size().iHeight,
+                    iU,
+                    iV );
+                break;
+
+            case CVtImage::EVtColor16M:
+                Scale16M(
+                    reinterpret_cast< const TUint8* >(
+                        iSource->DataAddress() ),
+                    iSource->BytesPerRow(),
+                    reinterpret_cast< TUint8* >( iTarget->DataAddress() ),
+                    iTarget->Size().iWidth,
+                    iTarget->Size().iHeight,
+                    iTarget->BytesPerRow(),
+                    iU,
+                    iV );
+                break;
+
+            case CVtImage::EVtColor16MU:
+            case CVtImage::EVtColor16MA:
+                Scale16MU16MA(
+                    iSource->DataAddress(),
+                    iSource->BytesPerRow(),
+                    iTarget->DataAddress(),
+                    iTarget->Size().iWidth,
+                    iTarget->Size().iHeight,
+                    iU,
+                    iV );
+                break;
+
+            default:
+                if ( iSource->Type() == CVtImage::EVtImageBitmap &&
+                     iTarget->Type() == CVtImage::EVtImageBitmap )
+                    {
+                    TRAPD( error,
+                        ScaleWithBitmapScalerL(
+                            CBitmapScaler::EMinimumQuality ) );
+                    result = error;
+                    }
+                else
+                    {
+                    result = KErrNotSupported;
+                    }
+            }
+        }
+
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::ValidateSourceTargetL(
+//  const CVtImage& aSource, CVtImage& aTarget )
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::ValidateSourceTargetL(
+    const CVtImage& aSource,
+    CVtImage& aTarget )
+    {
+    if( aSource.DisplayMode() != aTarget.DisplayMode() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    switch( aSource.DisplayMode() )
+        {
+        case CVtImage::EVtColor4K:
+        case CVtImage::EVtColor64K:
+        case CVtImage::EVtColor16M:
+        case CVtImage::EVtColor16MU:
+        case CVtImage::EVtColor16MA:
+            break;
+
+        default:
+            // Scaling for bitmaps is supported for other display modes
+            if ( !( aSource.Type() == CVtImage::EVtImageBitmap &&
+                 aTarget.Type() == CVtImage::EVtImageBitmap ) )
+                {
+                User::Leave( KErrNotSupported );
+                }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Initialize()
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Initialize()
+    {
+    iU = ( 1 << KDecimalBits ) * iSource->Size().iWidth /
+        iTarget->Size().iWidth + 1;
+    iV = ( 1 << KDecimalBits ) * iSource->Size().iHeight /
+        iTarget->Size().iHeight + 1;
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale4K(
+//  const TUint16* aSrcPtr, TUint32 aSrcWidth, TUint16* aTrgPtr,
+//  TUint32 aTrgWidth, TUint32 aTrgHeight, TUint32 aDx, TUint32 aDy )
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Scale4K(
+    const TUint16* aSrcPtr,
+    TUint32 aSrcWidth,
+    TUint16* aTrgPtr,
+    TUint32 aTrgWidth,
+    TUint32 aTrgHeight,
+    TUint32 aDx,
+    TUint32 aDy )
+    {
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale4K() >>" ), RThread().Id().operator TUint() ) );
+    // scaling 4K and 64K is equal procedure
+    Scale64K( aSrcPtr, aSrcWidth, aTrgPtr, aTrgWidth, aTrgHeight, aDx, aDy );
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale4K() <<" ), RThread().Id().operator TUint() ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale64K(
+//  const TUint16* aSrcPtr, TUint32 aSrcPitch, TUint16* aTrgPtr,
+//  TUint32 aTrgWidth, TUint32 aTrgHeight, TUint32 aDx, TUint32 aDy )
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Scale64K(
+    const TUint16* aSrcPtr,
+    TUint32 aSrcPitch,
+    TUint16* aTrgPtr,
+    TUint32 aTrgWidth,
+    TUint32 aTrgHeight,
+    TUint32 aDx,
+    TUint32 aDy )
+    {
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale64K() >>" ), RThread().Id().operator TUint() ) );
+
+    TUint32 sy( 0 );
+
+    for( TUint32 y = 0; y < aTrgHeight; y++ )
+        {
+        const TUint16* srow =
+            aSrcPtr + ( sy >> KDecimalBits ) * ( aSrcPitch >> 1 );
+
+        TUint32 sx( 0 );
+
+        TUint32 x( 0 );
+
+        // loop unrolled with 8
+        for( ; x < ( aTrgWidth >> 3 ); x++ )
+            {
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            }
+
+        // handle remaining columns
+        for( x = 0; x < ( aTrgWidth & 7 ); x++ )
+            {
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            }
+
+        // if target width is not even aligning is needed
+        if( aTrgWidth & 1 )
+            {
+            aTrgPtr++;
+            }
+
+        sy += aDy;
+        }
+
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale64K() <<" ), RThread().Id().operator TUint() ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale16M(
+//  const TUint8* aSrcPtr, TUint32 aSrcPitch, TUint8* aTrgPtr,
+//  TUint32 aTrgWidth, TUint32 aTrgHeight, TUint32 aTrgPitch, TUint32 aDx, TUint32 aDy )
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Scale16M(
+    const TUint8* aSrcPtr,
+    TUint32 aSrcPitch,
+    TUint8* aTrgPtr,
+    TUint32 aTrgWidth,
+    TUint32 aTrgHeight,
+    TUint32 aTrgPitch,
+    TUint32 aDx,
+    TUint32 aDy )
+    {
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16M() >>" ), RThread().Id().operator TUint() ) );
+
+    TUint32 sy( 0 );
+
+    for( TUint32 y = 0; y < aTrgHeight; y++ )
+        {
+        const TUint8* s = aSrcPtr + ( sy >> KDecimalBits ) * aSrcPitch;
+
+        TUint8* d = aTrgPtr;
+
+        TUint32 sx( 0 );
+
+        TUint32 x( 0 );
+
+        for( ; x < aTrgWidth; x++ )
+            {
+            const TUint8* tempSrc = s + ( sx >> KDecimalBits ) * 3;
+            *d++ = *tempSrc++;
+            *d++ = *tempSrc++;
+            *d++ = *tempSrc++;
+            sx += aDx;
+            }
+
+        aTrgPtr += aTrgPitch;
+
+        sy += aDy;
+        }
+
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16M() <<" ), RThread().Id().operator TUint() ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale16MU16MA( const TUint32* aSrcPtr,
+//  TUint32 aSrcPitch, TUint32* aTrgPtr, TUint32 aTrgWidth, TUint32 aTrgHeight,
+//  TUint32 aDx, TUint32 aDy )
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Scale16MU16MA(
+    const TUint32* aSrcPtr,
+    TUint32 aSrcPitch,
+    TUint32* aTrgPtr,
+    TUint32 aTrgWidth,
+    TUint32 aTrgHeight,
+    TUint32 aDx,
+    TUint32 aDy )
+    {
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16MU16MA() >>" ), RThread().Id().operator TUint() ) );
+
+    TUint32 sy( 0 );
+
+    for( TUint32 y = 0; y < aTrgHeight; y++ )
+        {
+        const TUint32* srow =
+            aSrcPtr + ( sy >> KDecimalBits ) * ( aSrcPitch >> 2 );
+
+        TUint32 sx( 0 );
+
+        TUint32 x( 0 );
+
+        // loop unrolled with 8
+        for( ; x < ( aTrgWidth >> 3 ); x++ )
+            {
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            }
+
+        // handle remaining columns
+        for( x = 0; x < ( aTrgWidth & 7 ); x++ )
+            {
+            *aTrgPtr++ = srow[ sx >> KDecimalBits ];
+            sx += aDx;
+            }
+
+        sy += aDy;
+        }
+
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16MU16MA() <<" ), RThread().Id().operator TUint() ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale2x4K64K()
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Scale2x4K64K()
+    {
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x4K64K() >>" ), RThread().Id().operator TUint() ) );
+
+    TInt sheight = iSource->Size().iHeight;
+    TInt swidth = iSource->Size().iWidth;
+    TInt spitch = iSource->BytesPerRow();
+    TInt dpitch = iTarget->BytesPerRow();
+
+    TUint16* s = reinterpret_cast< TUint16* >( iSource->DataAddress() );
+    TUint32* d = iTarget->DataAddress();
+
+    for( TInt y = 0; y < sheight; y++ )
+        {
+        TUint16* s2 = s;
+        TUint32* d1 = d;
+        for( TInt x = 0; x < swidth; x++ )
+            {
+            TUint32 p = *s2++;
+            p |= ( p << 16 );
+            *d1++ = p;
+            }
+        d = reinterpret_cast< TUint32* >(
+            Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch ) );
+        s = reinterpret_cast< TUint16* >(
+            reinterpret_cast< TUint8* >( s ) + spitch );
+        }
+
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x4K64K() <<" ), RThread().Id().operator TUint() ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale2x16M()
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Scale2x16M()
+    {
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16M() >>" ), RThread().Id().operator TUint() ) );
+
+    TInt sheight = iSource->Size().iHeight;
+    TInt swidth = iSource->Size().iWidth;
+    TInt spitch = iSource->BytesPerRow();
+    TInt dpitch = iTarget->BytesPerRow();
+
+    TUint8* s = reinterpret_cast< TUint8* >( iSource->DataAddress() );
+    TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
+
+    for( TInt y = 0; y < sheight; y++ )
+        {
+        TUint8* s2 = s;
+        TUint8* d1 = d;
+        for( TInt x = 0; x < swidth; x++ )
+            {
+            TUint8 g = *s2++;
+            TUint8 b = *s2++;
+            TUint8 r = *s2++;
+
+            *d1++ = g;
+            *d1++ = b;
+            *d1++ = r;
+
+            *d1++ = g;
+            *d1++ = b;
+            *d1++ = r;
+            }
+        d = Mem::Copy( d + dpitch, d, dpitch );
+        s += spitch;
+        }
+
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16M() <<" ), RThread().Id().operator TUint() ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageScalerImplNearest::Scale2x16MU16MA()
+// -----------------------------------------------------------------------------
+void CVtImageScalerImplNearest::Scale2x16MU16MA()
+    {
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16MU16MA() >>" ), RThread().Id().operator TUint() ) );
+
+    TInt sheight = iSource->Size().iHeight;
+    TInt swidth = iSource->Size().iWidth;
+    TInt spitch = iSource->BytesPerRow();
+    TInt dpitch = iTarget->BytesPerRow();
+
+    TUint32* s = iSource->DataAddress();
+    TUint32* d = iTarget->DataAddress();
+
+    for( TInt y = 0; y < sheight; y++ )
+        {
+        TUint32* s2 = s;
+        TUint32* d1 = d;
+        for( TInt x = 0; x < swidth; x++ )
+            {
+            TUint32 p = *s2++;
+            *d1++ = p;
+            *d1++ = p;
+            }
+        d = reinterpret_cast< TUint32* >(
+            Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch ) );
+        s = reinterpret_cast< TUint32* >(
+            reinterpret_cast< TUint8* >( s ) + spitch );
+        }
+
+    __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16MU16MA() <<" ), RThread().Id().operator TUint() ) );
+    }
+
+// End of File
+
+