vtprotocolplugins/DisplaySink/src/CVtImageRotatorImplMirrorFlip.cpp
changeset 0 ed9695c8bcbe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vtprotocolplugins/DisplaySink/src/CVtImageRotatorImplMirrorFlip.cpp	Mon Nov 23 14:47:47 2009 +0200
@@ -0,0 +1,589 @@
+/*
+* 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 "CVtImageRotatorImplMirrorFlip.h"
+#include "cvtimage.h"
+#include "CVtImageIYUV.h"
+
+// MACROS
+
+#ifdef _DEBUG
+#    define __IF_DEBUG(t) {RDebug::t;}
+#else
+#    define __IF_DEBUG(t)
+#endif
+
+// LOCAL CONSTANTS AND MACROS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ======================= CVtImageRotatorImplMirrorFlip =======================
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::CVtImageRotatorImplMirrorFlip(
+//  const CVtImageRotator::TRotationAngle& aAngle )
+// -----------------------------------------------------------------------------
+CVtImageRotatorImplMirrorFlip::CVtImageRotatorImplMirrorFlip(
+    const CVtImageRotator::TRotationAngle& aAngle ) : CVtImageRotatorImpl( aAngle )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::Rotate( TBool& aContinue )
+// -----------------------------------------------------------------------------
+TInt CVtImageRotatorImplMirrorFlip::Rotate( TBool& aContinue )
+    {
+    __IF_DEBUG( Print( _L( "ImageRotator [%d]: CVtImageRotatorImplMirrorFlip::Rotate() >>" ), RThread().Id().operator TUint() ) );
+
+    TInt result( KErrNone );
+
+    aContinue = EFalse;
+
+    TBool isSameBitmap( iSource->DataAddress() == iTarget->DataAddress() );
+
+    if( iAngle == CVtImageRotator::EFlipVerticalAxis )
+        {
+        // Are source and target referencing same bitmap?
+        if( isSameBitmap  )
+            {
+            // YES: Flip inside bitmap
+            Flip( *iTarget );
+            }
+        else
+            {
+            // NO: Use flipping from source to target
+            Flip();
+            }
+        }
+    else if( iAngle == CVtImageRotator::EMirrorHorizontalAxis )
+        {
+        // Are source and target referencing same bitmap?
+        if( isSameBitmap )
+            {
+            // YES: Mirror inside bitmap
+            Mirror( *iTarget );
+            }
+        else
+            {
+            // NO: Mirror from source to target
+            Mirror();
+            }
+        }
+    else if( iAngle == CVtImageRotator::E180DegreesClockwise )
+        {
+        // Are source and target referencing same bitmap?
+        if( isSameBitmap )
+            {
+            // YES: Mirror inside bitmap
+            Mirror( *iTarget );
+            }
+        else
+            {
+            // NO: Mirror from source to target
+            Mirror();
+            }
+        Flip( *iTarget );
+        }
+
+    __IF_DEBUG( Print( _L( "ImageRotator [%d]: CVtImageRotatorImplMirrorFlip::Rotate() <<" ), RThread().Id().operator TUint() ) );
+
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::ValidateSourceTargetL(
+//  const CVtImage& aSource, CVtImage& aTarget )
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::ValidateSourceTargetL(
+    const CVtImage& aSource,
+    CVtImage& aTarget )
+    {
+
+
+    // Sizes must match
+    if( aSource.Size() != aTarget.Size() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    // Displaymodes must match
+    if( aSource.DisplayMode() != aTarget.DisplayMode() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    // Check that displaymode is one of the supported
+    switch( aSource.DisplayMode() )
+        {
+        case CVtImage::EVtColor4K:
+        case CVtImage::EVtColor64K:
+        case CVtImage::EVtColor16M:
+        case CVtImage::EVtColor16MU:
+        case CVtImage::EVtColor16MA:
+        case CVtImage::EVtColorIYUV:
+            break;
+
+        default:
+            User::Leave( KErrNotSupported );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::ValidateSourceTargetL(
+//  const CVtImage& aSource, CVtImage& aTarget )
+// -----------------------------------------------------------------------------
+TBool CVtImageRotatorImplMirrorFlip::SupportsRotationAngle(
+    const CVtImageRotator::TRotationAngle& aAngle )
+    {
+    TBool result( EFalse );
+
+    if( ( aAngle == CVtImageRotator::EMirrorHorizontalAxis ) ||
+        ( aAngle == CVtImageRotator::EFlipVerticalAxis ) ||
+        ( aAngle == CVtImageRotator::E180DegreesClockwise ) )
+        {
+        result = ETrue;
+        }
+
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::Mirror()
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::Mirror()
+    {
+    TInt bytesPerRow( iSource->BytesPerRow() );
+
+    TInt height( iSource->Size().iHeight );
+
+    TInt width( iSource->Size().iWidth );
+
+    switch( iSource->DisplayMode() )
+        {
+        // DisplayMode: 4K and 64K
+        case CVtImage::EVtColor4K:
+        case CVtImage::EVtColor64K:
+            {
+            const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
+
+            TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
+
+            d += bytesPerRow;
+
+            if( width & 1 )
+                {
+                d -= 2;
+                }
+
+            for( TInt y = height - 1; y >= 0; y-- )
+                {
+                register const TUint16* tempS = reinterpret_cast< const TUint16* >( s );
+
+                register TUint16* tempD = reinterpret_cast< TUint16* >( d );
+
+                for( register TInt x = width - 1; x >= 0; x-- )
+                    {
+                    *--tempD = *tempS++;
+                    }
+
+                s += bytesPerRow;
+
+                d += bytesPerRow;
+                }
+            }
+            break;
+
+        // DisplayMode: 16M
+        case CVtImage::EVtColor16M:
+            {
+            const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
+
+            TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
+
+            d += width * 3;
+
+            for( TInt y = height - 1; y >= 0; y-- )
+                {
+                const TUint8* tempS = s;
+
+                TUint8* tempD = d - 3;
+
+                for( TInt x = width - 1; x >= 0; x-- )
+                    {
+                    tempD[ 0 ] = *tempS++;
+                    tempD[ 1 ] = *tempS++;
+                    tempD[ 2 ] = *tempS++;
+                    tempD -= 3;
+                    }
+
+                s += bytesPerRow;
+
+                d += bytesPerRow;
+                }
+            }
+            break;
+
+        // DisplayMode: 16MU and 16MA
+        case CVtImage::EVtColor16MU:
+        case CVtImage::EVtColor16MA:
+            {
+            const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
+
+            TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
+
+            d += bytesPerRow;
+
+            for( TInt y = height - 1; y >= 0; y-- )
+                {
+                register const TUint32* tempS = reinterpret_cast< const TUint32* >( s );
+                register TUint32* tempD = reinterpret_cast< TUint32* >( d );
+
+                for( TInt x = width - 1; x >= 0; x-- )
+                    {
+                    *--tempD = *tempS++;
+                    }
+
+                s += bytesPerRow;
+
+                d += bytesPerRow;
+                }
+            }
+            break;
+
+        // IYUV
+        case CVtImage::EVtColorIYUV:
+            MirrorIYUV( reinterpret_cast< const CVtImageIYUV& >( *iSource ), reinterpret_cast< CVtImageIYUV& >( *iTarget ) );
+            break;
+
+        default:
+            break;
+
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::Mirror( CVtImage& aTarget )
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::Mirror( CVtImage& aTarget )
+    {
+    TInt bytesPerRow( aTarget.BytesPerRow() );
+
+    TInt height( aTarget.Size().iHeight );
+
+    TInt width( aTarget.Size().iWidth );
+
+    switch( aTarget.DisplayMode() )
+        {
+        // DisplayMode: 4K and 64K
+        case CVtImage::EVtColor4K:
+        case CVtImage::EVtColor64K:
+            {
+            TUint8* d = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
+
+            TUint8* s = reinterpret_cast< TUint8* >( d );
+
+            d += bytesPerRow;
+
+            if( width & 1 )
+                {
+                d -= 2;
+                }
+
+            for( TInt y = height - 1; y >= 0; y-- )
+                {
+                register TUint16* tempS = reinterpret_cast< TUint16* >( s );
+
+                register TUint16* tempD = reinterpret_cast< TUint16* >( d );
+
+                for( register TInt x = width/2 - 1; x >= 0; x-- )
+                    {
+                    TUint16 p = *tempS;
+                    *tempS++ = *--tempD;
+                    *tempD = p;
+                    }
+
+                s += bytesPerRow;
+
+                d += bytesPerRow;
+                }
+            }
+            break;
+
+        // DisplayMode: 16M
+        case CVtImage::EVtColor16M:
+            {
+            TUint8* d = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
+
+            TUint8* s = reinterpret_cast< TUint8* >( d );
+
+            d += width * 3;
+
+            for( TInt y = height - 1; y >= 0; y-- )
+                {
+                TUint8* tempS = s;
+
+                TUint8* tempD = d - 3;
+
+                for( TInt x = width/2 - 1; x >= 0; x-- )
+                    {
+                    TUint8 s = *tempS;
+                    TUint8 t = *tempD;
+                    *tempD++ = s;
+                    *tempS++ = t;
+
+                    s = *tempS;
+                    t = *tempD;
+                    *tempD++ = s;
+                    *tempS++ = t;
+
+                    s = *tempS;
+                    t = *tempD;
+                    *tempD++ = s;
+                    *tempS++ = t;
+
+                    tempD -= 6;
+                    }
+
+                s += bytesPerRow;
+
+                d += bytesPerRow;
+                }
+            }
+            break;
+
+        // DisplayMode: 16MU and 16MA
+        case CVtImage::EVtColor16MU:
+        case CVtImage::EVtColor16MA:
+            {
+            TUint8* d = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
+
+            TUint8* s = reinterpret_cast< TUint8* >( d );
+
+            d += bytesPerRow;
+
+            for( TInt y = height - 1; y >= 0; y-- )
+                {
+                register TUint32* tempS = reinterpret_cast< TUint32* >( s );
+                register TUint32* tempD = reinterpret_cast< TUint32* >( d );
+
+                for( TInt x = width/2 - 1; x >= 0; x-- )
+                    {
+                    TUint32 p = *tempS;
+                    *tempS++ = *--tempD;
+                    *tempD = p;
+                    }
+
+                s += bytesPerRow;
+
+                d += bytesPerRow;
+                }
+            }
+            break;
+
+        // IYUV
+        case CVtImage::EVtColorIYUV:
+            MirrorIYUV( reinterpret_cast< const CVtImageIYUV& >( aTarget ), reinterpret_cast< CVtImageIYUV& >( aTarget ) );
+            break;
+
+        default:
+            break;
+
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::MirrorIYUV( const CVtImageIYUV& aSource,
+//  CVtImageIYUV& aTarget )
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::MirrorIYUV( const CVtImageIYUV& aSource,
+    CVtImageIYUV& aTarget )
+    {
+    MirrorPlane( aSource.Y(), aTarget.Y(), aSource.Size().iWidth,
+        aSource.Size().iHeight, aSource.BytesPerRow() );
+    MirrorPlane( aSource.U(), aTarget.U(), aSource.UVPlaneWidth(),
+        aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
+    MirrorPlane( aSource.V(), aTarget.V(), aSource.UVPlaneWidth(),
+        aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::MirrorPlane( TUint8* aSource, TUint8* aTarget,
+//  TInt aWidth, TInt aHeight, TInt aBytesPerRow )
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::MirrorPlane( TUint8* aSource,
+    TUint8* aTarget, TInt aWidth, TInt aHeight, TInt aBytesPerRow )
+    {
+    if( aSource != aTarget )
+        {
+        aTarget += aBytesPerRow;
+        for( TInt y = aHeight - 1; y >= 0; y-- )
+            {
+            register const TUint8* tempS = aSource;
+            register TUint8* tempD = aTarget;
+            for( TInt x = aWidth - 1; x >= 0; x-- )
+                {
+                *--tempD = *tempS++;
+                }
+            aSource += aBytesPerRow;
+            aTarget += aBytesPerRow;
+            }
+        }
+    else
+        {
+        aTarget += aBytesPerRow;
+        for( TInt y = aHeight - 1; y >= 0; y-- )
+            {
+            register TUint8* tempS = aSource;
+            register TUint8* tempD = aTarget;
+            for( TInt x = aWidth/2 - 1; x >= 0; x-- )
+                {
+                TUint8 p = *tempS;
+                *tempS++ = *--tempD;
+                *tempD = p;
+                }
+            aSource += aBytesPerRow;
+            aTarget += aBytesPerRow;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::Flip()
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::Flip()
+    {
+    if( iSource->DisplayMode() == CVtImage::EVtColorIYUV )
+        {
+        FlipIYUV
+            (
+            reinterpret_cast< const CVtImageIYUV& >( *iSource ),
+            reinterpret_cast< CVtImageIYUV& >( *iTarget )
+            );
+        }
+    else
+        {
+        TInt bytesPerRow( iSource->BytesPerRow() );
+
+        TInt height( iSource->Size().iHeight );
+
+        const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
+
+        TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
+
+        d += ( height - 1 ) * bytesPerRow;
+
+        for( TInt y = height - 1; y >= 0; y-- )
+            {
+            Mem::Copy( d, s, bytesPerRow );
+            s += bytesPerRow;
+            d -= bytesPerRow;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::FlipIYUV()
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::FlipIYUV
+    (
+    const CVtImageIYUV& aSource,
+    CVtImageIYUV& aTarget
+    )
+    {
+    FlipPlane( aSource.Y(), aTarget.Y(), aSource.Size().iHeight, aSource.BytesPerRow() );
+    FlipPlane( aSource.U(), aTarget.U(), aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
+    FlipPlane( aSource.V(), aTarget.V(), aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::FlipPlane()
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::FlipPlane
+    (
+    TUint8* aSource,
+    TUint8* aTarget,
+    TInt aHeight,
+    TInt aBytesPerRow
+    )
+    {
+    TBool doSwap = ( aSource == aTarget );
+
+    aTarget += ( aHeight - 1 ) * aBytesPerRow;
+
+    if( doSwap )
+        {
+        for( TInt y = aHeight / 2 - 1; y >= 0; y-- )
+            {
+            Mem::Swap( aTarget, aSource, aBytesPerRow );
+            aSource += aBytesPerRow;
+            aTarget -= aBytesPerRow;
+            }
+        }
+    else
+        {
+        for( TInt y = aHeight - 1; y >= 0; y-- )
+            {
+            Mem::Copy( aTarget, aSource, aBytesPerRow );
+            aSource += aBytesPerRow;
+            aTarget -= aBytesPerRow;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CVtImageRotatorImplMirrorFlip::Flip( CVtImage& aTarget )
+// -----------------------------------------------------------------------------
+void CVtImageRotatorImplMirrorFlip::Flip( CVtImage& aTarget )
+    {
+    if( iSource->DisplayMode() == CVtImage::EVtColorIYUV )
+        {
+        FlipIYUV
+            (
+            reinterpret_cast< const CVtImageIYUV& >( aTarget ),
+            reinterpret_cast< CVtImageIYUV& >( aTarget )
+            );
+        }
+    else
+        {
+        TInt bytesPerRow( aTarget.BytesPerRow() );
+
+        TInt height( aTarget.Size().iHeight );
+
+        TUint8* s = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
+
+        TUint8* d = s;
+
+        d += ( height - 1 ) * bytesPerRow;
+
+        for( TInt y = height / 2 - 1; y >= 0; y-- )
+            {
+            Mem::Swap( d, s, bytesPerRow );
+            s += bytesPerRow;
+            d -= bytesPerRow;
+            }
+        }
+    }
+
+// End of File
+
+