diff -r 000000000000 -r ed9695c8bcbe vtprotocolplugins/DisplaySink/src/CVtImageConverter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vtprotocolplugins/DisplaySink/src/CVtImageConverter.cpp Mon Nov 23 14:47:47 2009 +0200 @@ -0,0 +1,1876 @@ +/* +* 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: YUV to bitmap and bitmap to YUV conversion routines for VT +* +*/ + + +// INCLUDE FILES + +#include +#include +#include "CVtImageConverter.h" + +// LOCAL CONSTANTS AND MACROS + +#ifdef _DEBUG +# define __IF_DEBUG(t) {RDebug::t;} +#else +# define __IF_DEBUG(t) +#endif + +// Calculates average for two integer values +#define AVG( a, b ) ( ( a + b ) >> 1 ) + +// MODULE DATA STRUCTURES + +/** +* Holds data for one YUV pixel +* +* @lib VTImageConverter.lib +*/ +struct TVSYCrCb + { + public: + // Y data + TInt iY; + + // Cb (U) data + TInt iCb; + + // Cr (V) data + TInt iCr; + }; + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// RGBtoYCbCr( TVSYCrCb* aYuv, const TRgb& aColor ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint8 RGBtoYCbCr( TVSYCrCb* aYuv, const TRgb& aColor ) + { + const TInt YRedFactor = 19595; // 0.299 << 16 + const TInt YGreenFactor = 38470; // 0.587 << 16 + const TInt YBlueFactor = 7471; // 0.114 << 16 + const TInt CbRedFactor = 11056; // 0.1687 << 16 + const TInt CbGreenFactor = 21712; // 0.3313 << 16 + const TInt CrGreenFactor = 27440; // 0.4187 << 16 + const TInt CrBlueFactor = 5328; // 0.0813 << 16 + + TInt red = aColor.Red(); + TInt green = aColor.Green(); + TInt blue = aColor.Blue(); + + aYuv->iY = ( YRedFactor * red ) + + ( YGreenFactor * green ) + + ( YBlueFactor * blue ); + aYuv->iCb = - ( CbRedFactor * red ) - + ( CbGreenFactor * green ) + + ( blue << 15 ); + aYuv->iCr = ( red << 15 ) - + ( CrGreenFactor * green ) - + ( CrBlueFactor * blue ); + + aYuv->iY >>= 16; + aYuv->iCb >>= 16; + aYuv->iCr >>= 16; + + aYuv->iCb += 128; + aYuv->iCr += 128; + + return static_cast< TUint8 >( aYuv->iY ); + } + +// ----------------------------------------------------------------------------- +// VSReadColor4K( TAny*& aSource ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor4K( TAny*& aSource ) + { + TUint16* s = static_cast< TUint16* >( aSource ); + TRgb rgb( TRgb::Color4K( *s++ ) ); + aSource = s; + return rgb; + } + +// ----------------------------------------------------------------------------- +// VSReadColor64K( TAny*& aSource ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor64K( TAny*& aSource ) + { + TUint16* s = static_cast< TUint16* >( aSource ); + TRgb rgb( TRgb::Color64K( *s++ ) ); + aSource = s; + return rgb; + } + +// ----------------------------------------------------------------------------- +// VSReadColor16M( TAny*& aSource ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor16M( TAny*& aSource ) + { + TUint8* s = static_cast< TUint8* >( aSource ); + TRgb rgb( s[ 2 ], s[ 1 ], s[ 0 ] ); + aSource = s + 3; + return rgb; + } + +// ----------------------------------------------------------------------------- +// VSReadColor16MU( TAny*& aSource ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor16MU( TAny*& aSource ) + { + TUint32* s = static_cast< TUint32* >( aSource ); + TRgb rgb( TRgb::Color16MU( *s++ ) ); + aSource = s; + return rgb; + } + +// ----------------------------------------------------------------------------- +// VSReadColor16MA( TAny*& aSource ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor16MA( TAny*& aSource ) + { + TUint32* s = static_cast< TUint32* >( aSource ); + TRgb rgb( TRgb::Color16MA( *s++ ) ); + aSource = s; + return rgb; + } + +// ============================ MEMBER FUNCTIONS =============================== + +/** +* +*/ +const TUint8 CVTYUVFbsBitmapConverter::COFF_TBL_4K[ 80 ]= + { + 0xe9,0x66,0x01,0x00, // KRedCrFactor + 0x1a,0x58,0x00,0x00, // KGreenCbFactor + 0xd2,0xb6,0x00,0x00, // KGreenCrFactor + 0xa2,0xc5,0x01,0x00, // KBlueCbFactor + + 0x00,0x00,0x00,0x00, // 4-bit + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, // 5 + 0x00,0x00,0x00,0x00, + 0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0f, // 10 + 0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f, // 15 + 0x0f,0x0f,0x0f,0x0f + }; + +/** +* +*/ +const TUint8 CVTYUVFbsBitmapConverter::COFF_TBL_64K[ 220 ]= + { + 0xe9,0x66,0x01,0x00, // KRedCrFactor + 0x1a,0x58,0x00,0x00, // KGreenCbFactor + 0xd2,0xb6,0x00,0x00, // KGreenCrFactor + 0xa2,0xc5,0x01,0x00, // KBlueCbFactor + + 0x00,0x00,0x00,0x00, // 5-bit + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13, + 0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b, + 0x1c,0x1d,0x1e,0x1f, + 0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f, + + 0x00,0x00,0x00,0x00, // 6-bit + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13, + 0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b, + 0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23, + 0x24,0x25,0x26,0x27, + 0x28,0x29,0x2a,0x2b, + 0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33, + 0x34,0x35,0x36,0x37, + 0x38,0x39,0x3a,0x3b, + 0x3c,0x3d,0x3e,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f + }; + +/** +* +*/ +const TUint8 CVTYUVFbsBitmapConverter::COFF_TBL_16M[ 528 ] = + { + 0xe9,0x66,0x01,0x00, // KRedCrFactor + 0x1a,0x58,0x00,0x00, // KGreenCbFactor + 0xd2,0xb6,0x00,0x00, // KGreenCrFactor + 0xa2,0xc5,0x01,0x00, // KBlueCbFactor + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + + 0x00,0x01,0x02,0x03, // 8-bit + 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0f, + + 0x10,0x11,0x12,0x13, + 0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b, + 0x1c,0x1d,0x1e,0x1f, + + 0x20,0x21,0x22,0x23, + 0x24,0x25,0x26,0x27, + 0x28,0x29,0x2a,0x2b, + 0x2c,0x2d,0x2e,0x2f, + + 0x30,0x31,0x32,0x33, + 0x34,0x35,0x36,0x37, + 0x38,0x39,0x3a,0x3b, + 0x3c,0x3d,0x3e,0x3f, + + 0x40,0x41,0x42,0x43, + 0x44,0x45,0x46,0x47, + 0x48,0x49,0x4a,0x4b, + 0x4c,0x4d,0x4e,0x4f, + + 0x50,0x51,0x52,0x53, + 0x54,0x55,0x56,0x57, + 0x58,0x59,0x5a,0x5b, + 0x5c,0x5d,0x5e,0x5f, + + 0x60,0x61,0x62,0x63, + 0x64,0x65,0x66,0x67, + 0x68,0x69,0x6a,0x6b, + 0x6c,0x6d,0x6e,0x6f, + + 0x70,0x71,0x72,0x73, + 0x74,0x75,0x76,0x77, + 0x78,0x79,0x7a,0x7b, + 0x7c,0x7d,0x7e,0x7f, + + 0x80,0x81,0x82,0x83, + 0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x8b, + 0x8c,0x8d,0x8e,0x8f, + + 0x90,0x91,0x92,0x93, + 0x94,0x95,0x96,0x97, + 0x98,0x99,0x9a,0x9b, + 0x9c,0x9d,0x9e,0x9f, + + 0xa0,0xa1,0xa2,0xa3, + 0xa4,0xa5,0xa6,0xa7, + 0xa8,0xa9,0xaa,0xab, + 0xac,0xad,0xae,0xaf, + + 0xb0,0xb1,0xb2,0xb3, + 0xb4,0xb5,0xb6,0xb7, + 0xb8,0xb9,0xba,0xbb, + 0xbc,0xbd,0xbe,0xbf, + + 0xc0,0xc1,0xc2,0xc3, + 0xc4,0xc5,0xc6,0xc7, + 0xc8,0xc9,0xca,0xcb, + 0xcc,0xcd,0xce,0xcf, + + 0xd0,0xd1,0xd2,0xd3, + 0xd4,0xd5,0xd6,0xd7, + 0xd8,0xd9,0xda,0xdb, + 0xdc,0xdd,0xde,0xdf, + + 0xe0,0xe1,0xe2,0xe3, + 0xe4,0xe5,0xe6,0xe7, + 0xe8,0xe9,0xea,0xeb, + 0xec,0xed,0xee,0xef, + + 0xf0,0xf1,0xf2,0xf3, + 0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb, + 0xfc,0xfd,0xfe,0xff, + + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff + }; + +// ============================ CVTYUVFbsBitmapConverter ======================= + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::CVTYUVFbsBitmapConverter( +// const TSize& aSourceSize ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CVTYUVFbsBitmapConverter::CVTYUVFbsBitmapConverter( const TSize& aSourceSize ) +: iSourceSize( aSourceSize ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::CVTYUVFbsBitmapConverter() >>"), RThread().Id().operator TUint())); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::CVTYUVFbsBitmapConverter() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::~CVTYUVFbsBitmapConverter() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CVTYUVFbsBitmapConverter::~CVTYUVFbsBitmapConverter() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::~CVTYUVFbsBitmapConverter() >>"), RThread().Id().operator TUint())); + delete iDestination; + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::~CVTYUVFbsBitmapConverter() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::ProcessL() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVTYUVFbsBitmapConverter::ProcessL() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::ProcessL() >>"), RThread().Id().operator TUint())); + switch( iDestination->DisplayMode() ) + { + case EColor4K: + DoProcess4K(); + break; + + case EColor64K: + DoProcess64K(); + break; + + case EColor16M: + DoProcess16M(); + break; + + case EColor16MU: + case EColor16MA: // 16MU and 16MA are handled equally + DoProcess16MU16MA(); + break; + + default: + User::Leave( KErrNotSupported ); + break; + }; + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::ProcessL() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::SetDestinationL( +// const CFbsBitmap& aDestinationBitmap ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVTYUVFbsBitmapConverter::SetDestinationL( + const CFbsBitmap& aDestinationBitmap ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::SetDestinationL() >>"), RThread().Id().operator TUint())); + SetDestinationL( aDestinationBitmap.Handle() ); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::SetDestinationL() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::SetDestinationL( TInt aHandle ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVTYUVFbsBitmapConverter::SetDestinationL( TInt aHandle ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::SetDestinationL() >>"), RThread().Id().operator TUint())); + ReConstructL( aHandle ); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::SetDestinationL() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::ConstructL( TInt aBitmapHandle ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVFbsBitmapConverter::ConstructL( TInt aBitmapHandle ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::ConstructL() >>"), RThread().Id().operator TUint())); + iDestination = new (ELeave) CFbsBitmap(); + ReConstructL( aBitmapHandle ); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::ConstructL() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::ReConstructL( TInt aBitmapHandle ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVFbsBitmapConverter::ReConstructL( TInt aBitmapHandle ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::ReConstructL() >>"), RThread().Id().operator TUint())); + User::LeaveIfError( iDestination->Duplicate( aBitmapHandle ) ); + // make sure that destination bitmap's displaymode is supported + if( ( iDestination->DisplayMode() != EColor4K ) && + ( iDestination->DisplayMode() != EColor64K ) && + ( iDestination->DisplayMode() != EColor16M ) && + ( iDestination->DisplayMode() != EColor16MU ) && + ( iDestination->DisplayMode() != EColor16MA ) + ) + { + User::Leave( KErrNotSupported ); + } + iDestinationSize = iDestination->SizeInPixels(); + SizeUpdateL(); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::ReConstructL() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVFbsBitmapConverter::SizeUpdateL() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVFbsBitmapConverter::SizeUpdateL() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::SizeUpdate() >>"), RThread().Id().operator TUint())); + if( ( SourceSize().iWidth < 2 ) || ( DestinationSize().iWidth < 2 ) ) + { + User::Leave( KErrNotSupported ); // !!!! + } + + iVSkipReal = TReal32( SourceSize().iHeight ) / + TReal32( DestinationSize().iHeight ); + iHSkipReal = TReal32( SourceSize().iWidth ) / + TReal32( DestinationSize().iWidth ); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVFbsBitmapConverter::SizeUpdate() <<"), RThread().Id().operator TUint())); + } + +// ============================ CVTYUVPlanarFbsBitmapConverter =============================== + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::SetSourceSizeL( const TSize& aSize ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVTYUVPlanarFbsBitmapConverter::SetSourceSizeL( + const TSize& aSize ) + { + iSourceSize = aSize; + SizeUpdateL(); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::SetSourceL( +// const TSize& aSize, const TDesC8& aSourceData ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVTYUVPlanarFbsBitmapConverter::SetSourceL( + const TSize& aSize, + const TDesC8& aSourceData ) + { + iSourceSize = aSize; + SetSourceL( aSourceData ); + SizeUpdateL(); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::CVTYUVPlanarFbsBitmapConverter( +// const TSize& aSourceSize ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CVTYUVPlanarFbsBitmapConverter::CVTYUVPlanarFbsBitmapConverter( + const TSize& aSourceSize ) +: CVTYUVFbsBitmapConverter( aSourceSize ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::CVTYUVPlanarFbsBitmapConverter() >>"), RThread().Id().operator TUint())); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::CVTYUVPlanarFbsBitmapConverter() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess4K() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess4K() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess4K() >>"), RThread().Id().operator TUint())); + + // Vertical scaling needed? + if( ( iVSkipReal == 1 ) && ( iHSkipReal == 1 ) ) + { + // NO: Use really fast conversion + DoProcess4KNoScale(); + } + else + { + + // YES: Use slower conversion method + const TUint8* y = iY; + const TUint8* u = iU; + const TUint8* v = iV; + const TUint8* clip = COFF_TBL_4K + 40; + + TInt height = DestinationSize().iHeight; + TInt width = DestinationSize().iWidth; + + iDestination->LockHeap(); + TUint32* d = iDestination->DataAddress(); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess4K(): [%d, %d] for >>"), RThread().Id().operator TUint(), width, height )); + + for( TInt h = 0; h < height; h++ ) + { + TInt sourceY = TInt( TReal32( h ) * iVSkipReal ); + TInt hTimesW = sourceY * SourceSize().iWidth; + TInt uvIdx = ( sourceY >> 1 ) * ( SourceSize().iWidth >> 1 ); + for( TInt w = 0; w < width; w++ ) + { + TInt sourceX = TInt( TReal32( w ) * iHSkipReal ); + TInt uvIdxW( uvIdx + ( sourceX >> 1 ) ); + + TInt ay = y[ hTimesW + sourceX ]; + TInt cb = u[ uvIdxW ] - 128; + TInt cr = v[ uvIdxW ] - 128; + + TInt greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 32 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 36 ) + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 40 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 28 ) + ) >> 16; + + TInt red = ay + cr; + TInt green = ay - greenCbCr; + TInt blue = ay + cb; + + red = clip[ red >> 4 ]; + green = clip[ green >> 4 ]; + blue = clip[ blue >> 4 ]; + + // RGB_444 + TUint32 s = green | ( red << 4 ); + s = blue | ( s << 4 ); + + w++; + sourceX = TInt( TReal32( w ) * iHSkipReal ); + uvIdxW = uvIdx + ( sourceX >> 1 ); + + ay = y[ hTimesW + sourceX ]; + cb = u[ uvIdxW ] - 128; + cr = v[ uvIdxW ] - 128; + + greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 32 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 36 ) + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 40 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 28 ) + ) >> 16; + + red = ay + cr; + green = ay - greenCbCr; + blue = ay + cb; + + red = clip[ red >> 4 ]; + green = clip[ green >> 4 ]; + blue = clip[ blue >> 4 ]; + + // RGB_444 + s |= ( ( green | ( red << 4 ) ) << 4 | blue ) << 16; + + *d++ = s; + } + } + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess4K(): for <<"), RThread().Id().operator TUint())); + + iDestination->UnlockHeap(); + } + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess4K() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess4KNoScale() +// When vertical and horizontal scaling is not required we can do two vertical +// lines in parallel in that case we need to calculate Cr and Cb values only +// once for four pixels. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess4KNoScale() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess4KNoScale() >>"), RThread().Id().operator TUint())); + + TInt height( SourceSize().iHeight >> 1 ); + TInt width( SourceSize().iWidth ); + + const TUint32* y1 = reinterpret_cast< const TUint32* >( iY ); + const TUint32* u = reinterpret_cast< const TUint32* >( iU ); + const TUint32* v = reinterpret_cast< const TUint32* >( iV ); + + iDestination->LockHeap(); + + TUint32 uintsPerDestRow = CFbsBitmap::ScanLineLength + ( DestinationSize().iWidth, EColor4K ) >> 2; + + TUint32* d1 = iDestination->DataAddress(); + + TUint32 ywidth = width >> 2; + + width >>= 3; + + TInt32 cb; + TInt32 cr; + TInt32 greenCbCr; + TInt32 yy; + TInt32 red; + TInt32 green; + TInt32 blue; + TUint32 r1; + const TUint8* clip = COFF_TBL_4K + 40; + + for( TInt y = 0; y < height; y++ ) + { + for( TInt x = 0; x < width; x++ ) + { + TUint32 u1 = *u++; + TUint32 v1 = *v++; + + for( TInt c2 = 0; c2 < 2; c2++ ) + { + TUint32 yy2 = y1[ ywidth ]; + TUint32 yy1 = *y1++; + + for( TInt c = 0; c < 2; c++ ) + { + cb = TInt32( u1 & 0xff ) - 128; + u1 >>= 8; + cr = TInt32( v1 & 0xff ) - 128; + v1 >>= 8; + + greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 32 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 36 ) + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 40 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 28 ) + ) >> 16; + + // lower left + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + red = clip[ red >> 4 ]; + green = clip[ green >> 4 ]; + blue = clip[ blue >> 4 ]; + + // RGB_444 + r1 = green | ( red << 4 ); + r1 = blue | ( r1 << 4 ); + + // lower right + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + red = clip[ red >> 4 ]; + green = clip[ green >> 4 ]; + blue = clip[ blue >> 4 ]; + + // RGB_444 + r1 |= ( ( green | ( red << 4 ) ) << 4 | blue ) << 16; + + d1[ uintsPerDestRow ] = r1; + + // upper left + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + red = clip[ red >> 4 ]; + green = clip[ green >> 4 ]; + blue = clip[ blue >> 4 ]; + + // RGB_444 + r1 = green | ( red << 4 ); + r1 = blue | ( r1 << 4 ); + + // upper right + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + red = clip[ red >> 4 ]; + green = clip[ green >> 4 ]; + blue = clip[ blue >> 4 ]; + + // RGB_444 + r1 |= ( ( green | ( red << 4 ) ) << 4 | blue ) << 16; + + *d1++ = r1; + } + } + } + + y1 += ( width << 1 ); + d1 += uintsPerDestRow; + } + + iDestination->UnlockHeap(); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess4KNoScale() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess64K() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess64K() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess64K() >>"), RThread().Id().operator TUint())); + + // Vertical scaling needed? + if( ( iVSkipReal == 1 ) && ( iHSkipReal == 1 ) ) // !!! + { + // NO: Use really fast conversion + DoProcess64KNoScale(); + return; + } + else + { + // YES: Use slower conversion method + const TUint8* y = iY; + const TUint8* u = iU; + const TUint8* v = iV; + const TUint8* clip = COFF_TBL_64K + 40; + + TInt height = DestinationSize().iHeight; + TInt width = DestinationSize().iWidth; + + iDestination->LockHeap(); + TUint32* d = iDestination->DataAddress(); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess64K(): [%d, %d] for >>"), RThread().Id().operator TUint(), width, height )); + + for( TInt h = 0; h < height; h++ ) + { + TInt sourceY = TInt( TReal32( h ) * iVSkipReal ); + TInt hTimesW = sourceY * SourceSize().iWidth; + TInt uvIdx = ( sourceY >> 1 ) * ( SourceSize().iWidth >> 1 ); + for( TInt w = 0; w < width; w++ ) + { + TInt sourceX = TInt( TReal32( w ) * iHSkipReal ); + + TInt uvIdxW( uvIdx + ( sourceX >> 1 ) ); + + TInt ay = y[ hTimesW + sourceX ]; + TInt cb = u[ uvIdxW ] - 128; + TInt cr = v[ uvIdxW ] - 128; + + TInt greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 32 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 36 ) - + 0x1200000 + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 40 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 28 ) + ) >> 16; + + TInt red = ay + cr; + TInt green = ay - greenCbCr; + TInt blue = ay + cb; + + red = clip[ red >> 3 ]; + green = clip[ green >> 2 ]; + blue = clip[ blue >> 3 ]; + + // RGB_565 + TUint32 s = green | ( red << 6 ); + s = blue | ( s << 5 ); + + w++; + sourceX = TInt( TReal32( w ) * iHSkipReal ); + + uvIdxW = uvIdx + ( sourceX >> 1 ); + + ay = y[ hTimesW + sourceX ]; + cb = u[ uvIdxW ] - 128; + cr = v[ uvIdxW ] - 128; + + greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 32 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 36 ) - + 0x1200000 + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 40 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 28 ) + ) >> 16; + + red = ay + cr; + green = ay - greenCbCr; + blue = ay + cb; + + red = clip[ red >> 3 ]; + green = clip[ green >> 2 ]; + blue = clip[ blue >> 3 ]; + + s |= ( ( green | ( red << 6 ) ) << 5 | blue ) << 16; + + *d++ = s; + } + } + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess64K(): for <<"), RThread().Id().operator TUint())); + + iDestination->UnlockHeap(); + } + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess64K() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess64KNoScale() +// Source YUV image must be even divisible by 8. +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess64KNoScale() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess64KNoScale() >>"), RThread().Id().operator TUint())); + + TInt height( SourceSize().iHeight >> 1 ); + TInt width( SourceSize().iWidth ); + + const TUint32* y1 = reinterpret_cast< const TUint32* >( iY ); + const TUint32* u = reinterpret_cast< const TUint32* >( iU ); + const TUint32* v = reinterpret_cast< const TUint32* >( iV ); + + iDestination->LockHeap(); + + TUint32 uintsPerDestRow = CFbsBitmap::ScanLineLength + ( DestinationSize().iWidth, EColor64K ) >> 2; + + TUint32* d1 = iDestination->DataAddress(); + + TUint32 ywidth = width >> 2; + + width >>= 3; + + TInt32 cb; + TInt32 cr; + TInt32 greenCbCr; + TInt32 yy; + TInt32 red; + TInt32 green; + TInt32 blue; + TUint32 r1; + const TUint8* clip = COFF_TBL_64K + 40; + + for( TInt y = 0; y < height; y++ ) + { + for( TInt x = 0; x < width; x++ ) + { + TUint32 u1 = *u++; + TUint32 v1 = *v++; + + for( TInt c2 = 0; c2 < 2; c2++ ) + { + TUint32 yy2 = y1[ ywidth ]; + TUint32 yy1 = *y1++; + + for( TInt c = 0; c < 2; c++ ) + { + cb = TInt32( u1 & 0xff ) - 128; + u1 >>= 8; + cr = TInt32( v1 & 0xff ) - 128; + v1 >>= 8; + + greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 32 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 36 ) - + 0x1200000 + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 40 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 28 ) + ) >> 16; + + // lower left + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + red = clip[ red >> 3 ]; + green = clip[ green >> 2 ]; + blue = clip[ blue >> 3 ]; + + // RGB_565 + r1 = green | ( red << 6 ); + r1 = blue | ( r1 << 5 ); + + // lower right + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + // clear lowest 3 bits + red = clip[ red >> 3 ]; + green = clip[ green >> 2 ]; + blue = clip[ blue >> 3 ]; + + // RGB_565 + r1 |= ( ( green | ( red << 6 ) ) << 5 | blue ) << 16; + + d1[ uintsPerDestRow ] = r1; + + // upper left + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + red = clip[ red >> 3 ]; + green = clip[ green >> 2 ]; + blue = clip[ blue >> 3 ]; + + // RGB_565 + r1 = green | ( red << 6 ); + r1 = blue | ( r1 << 5 ); + + // upper right + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + red = yy + cr; + green = yy - greenCbCr; + blue = yy + cb; + + red = clip[ red >> 3 ]; + green = clip[ green >> 2 ]; + blue = clip[ blue >> 3 ]; + + // RGB_565 + r1 |= ( ( green | ( red << 6 ) ) << 5 | blue ) << 16; + + *d1++ = r1; + } + } + } + + y1 += ( width << 1 ); + d1 += uintsPerDestRow; + } + + iDestination->UnlockHeap(); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess64KNoScale() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess16M() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess16M() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16M() >>"), RThread().Id().operator TUint())); + + // Vertical scaling needed? + if( ( iVSkipReal == 1 ) && ( iHSkipReal == 1 ) ) + { + // NO: Use really fast conversion + DoProcess16MNoScale(); + } + else + { + // YES: Use slower conversion method + + // YES: Use slower conversion method + const TUint8* y = iY; + const TUint8* u = iU; + const TUint8* v = iV; + const TUint8* clip = COFF_TBL_16M + 144; + + TInt height = DestinationSize().iHeight; + TInt width = DestinationSize().iWidth; + + iDestination->LockHeap(); + + TUint8* d = reinterpret_cast( iDestination->DataAddress() ); + TUint32 dPitch = iDestination->ScanLineLength( width, iDestination->DisplayMode() ); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16M(): [%d, %d] for >>"), RThread().Id().operator TUint(), width, height )); + + for( TInt h = 0; h < height; h++ ) + { + TInt sourceY = TInt( TReal32( h ) * iVSkipReal ); + TInt hTimesW = sourceY * SourceSize().iWidth; + TInt uvIdx = ( sourceY >> 1 ) * ( SourceSize().iWidth >> 1 ); + TUint8* dTemp = d; + for( TInt w = 0; w < width; w++ ) + { + TInt sourceX = TInt( TReal32( w ) * iHSkipReal ); + + TInt uvIdxW( uvIdx + ( sourceX >> 1 ) ); + + TInt ay = y[ hTimesW + sourceX ]; + TInt cb = u[ uvIdxW ] - 128; + TInt cr = v[ uvIdxW ] - 128; + + TInt greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 136 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 140 ) + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 144 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 132 ) + ) >> 16; + + *dTemp++ = clip[ ay + cb ]; + *dTemp++ = clip[ ay - greenCbCr ]; + *dTemp++ = clip[ ay + cr ]; + } + d += dPitch; + } + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16M(): for <<"), RThread().Id().operator TUint())); + + iDestination->UnlockHeap(); + } + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16M() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess16MNoScale() +// When vertical and horizontal scaling is not required we can do two vertical +// lines in parallel in that case we need to calculate Cr and Cb values only +// once for four pixels. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess16MNoScale() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MNoScale() >>"), RThread().Id().operator TUint())); + + TInt height( SourceSize().iHeight >> 1 ); + TInt width( SourceSize().iWidth ); + + const TUint32* y1 = reinterpret_cast< const TUint32* >( iY ); + const TUint32* u = reinterpret_cast< const TUint32* >( iU ); + const TUint32* v = reinterpret_cast< const TUint32* >( iV ); + + iDestination->LockHeap(); + + TUint32 bytesPerDestRow = CFbsBitmap::ScanLineLength + ( DestinationSize().iWidth, EColor16M ); + + TUint8* d1 = reinterpret_cast< TUint8* >( iDestination->DataAddress() ); + + TUint32 ywidth = width >> 2; + + width >>= 3; + + TInt32 cb; + TInt32 cr; + TInt32 greenCbCr; + TInt32 yy; + TInt32 idx1; + TInt32 idx2; + const TUint8* clip = COFF_TBL_16M + 144; + + for( TInt y = 0; y < height; y++ ) + { + idx1 = 0; + idx2 = bytesPerDestRow; + + for( TInt x = 0; x < width; x++ ) + { + TUint32 u1 = *u++; + TUint32 v1 = *v++; + + for( TInt c2 = 0; c2 < 2; c2++ ) + { + TUint32 yy2 = y1[ ywidth ]; + TUint32 yy1 = *y1++; + + for( TInt c = 0; c < 2; c++ ) + { + cb = TInt32( u1 & 0xff ) - 128; + u1 >>= 8; + cr = TInt32( v1 & 0xff ) - 128; + v1 >>= 8; + + greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 136 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 140 ) + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 144 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 132 ) + ) >> 16; + + // lower left + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + d1[ idx2++ ] = clip[ yy + cb ]; + d1[ idx2++ ] = clip[ yy - greenCbCr ]; + d1[ idx2++ ] = clip[ yy + cr ]; + + // lower right + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + d1[ idx2++ ] = clip[ yy + cb ]; + d1[ idx2++ ] = clip[ yy - greenCbCr ]; + d1[ idx2++ ] = clip[ yy + cr ]; + + // upper left + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + d1[ idx1++ ] = clip[ yy + cb ]; + d1[ idx1++ ] = clip[ yy - greenCbCr ]; + d1[ idx1++ ] = clip[ yy + cr ]; + + // upper right + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + d1[ idx1++ ] = clip[ yy + cb ]; + d1[ idx1++ ] = clip[ yy - greenCbCr ]; + d1[ idx1++ ] = clip[ yy + cr ]; + } + } + } + + y1 += ( width << 1 ); + d1 += bytesPerDestRow * 2; + } + + iDestination->UnlockHeap(); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MNoScale() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MA() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MA() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MA() >>"), RThread().Id().operator TUint())); + + // Vertical scaling needed? + if( ( iVSkipReal == 1 ) && ( iHSkipReal == 1 ) ) + { + // NO: Use really fast conversion + DoProcess16MU16MANoScale(); + } + else + { + // YES: Use slower conversion method + const TUint8* y = iY; + const TUint8* u = iU; + const TUint8* v = iV; + const TUint8* clip = COFF_TBL_16M + 144; + + TInt height = DestinationSize().iHeight; + TInt width = DestinationSize().iWidth; + + iDestination->LockHeap(); + TUint32* d = iDestination->DataAddress(); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MA(): [%d, %d] for >>"), RThread().Id().operator TUint(), width, height )); + + for( TInt h = 0; h < height; h++ ) + { + TInt sourceY = TInt( TReal32( h ) * iVSkipReal ); + TInt hTimesW = sourceY * SourceSize().iWidth; + TInt uvIdx = ( sourceY >> 1 ) * ( SourceSize().iWidth >> 1 ); + for( TInt w = 0; w < width; w++ ) + { + TInt sourceX = TInt( TReal32( w ) * iHSkipReal ); + + TInt uvIdxW( uvIdx + ( sourceX >> 1 ) ); + + TInt ay = y[ hTimesW + sourceX ]; + TInt cb = u[ uvIdxW ] - 128; + TInt cr = v[ uvIdxW ] - 128; + + TInt greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 136 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 140 ) + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 144 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 132 ) + ) >> 16; + + + // 0xffBBGG + TUint32 p = 0xff0000 | + ( clip[ ay + cr ] << 8 ) | clip[ ay - greenCbCr ]; + // 0xffBBGGRR + *d++ = clip[ ay + cb ] | ( p << 8 ); + } + } + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MA(): for <<"), RThread().Id().operator TUint())); + + iDestination->UnlockHeap(); + } + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MA() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MANoScale() +// When vertical and horizontal scaling is not required we can do two vertical +// lines in parallel in that case we need to calculate Cr and Cb values only +// once for four pixels. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MANoScale() + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MANoScale() >>"), RThread().Id().operator TUint())); + + TInt height( SourceSize().iHeight >> 1 ); + TInt width( SourceSize().iWidth ); + + const TUint32* y1 = reinterpret_cast< const TUint32* >( iY ); + const TUint32* u = reinterpret_cast< const TUint32* >( iU ); + const TUint32* v = reinterpret_cast< const TUint32* >( iV ); + + iDestination->LockHeap(); + + TUint32 uintsPerDestRow = CFbsBitmap::ScanLineLength + ( DestinationSize().iWidth, EColor16MU ) >> 2; + + TUint32* d1 = iDestination->DataAddress(); + + TUint32 ywidth = width >> 2; + + width >>= 3; + + TInt32 cb; + TInt32 cr; + TInt32 greenCbCr; + TInt32 yy; + TUint32 p; + const TUint8* clip = COFF_TBL_16M + 144; + + for( TInt y = 0; y < height; y++ ) + { + for( TInt x = 0; x < width; x++ ) + { + TUint32 u1 = *u++; + TUint32 v1 = *v++; + + for( TInt c2 = 0; c2 < 2; c2++ ) + { + TUint32 yy2 = y1[ ywidth ]; + TUint32 yy1 = *y1++; + + for( TInt c = 0; c < 2; c++ ) + { + cb = TInt32( u1 & 0xff ) - 128; + u1 >>= 8; + cr = TInt32( v1 & 0xff ) - 128; + v1 >>= 8; + + greenCbCr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 136 ) + + cb * *reinterpret_cast< const TInt32* >( clip - 140 ) + ) >> 16; + cr = + ( + cr * *reinterpret_cast< const TInt32* >( clip - 144 ) + ) >> 16; + cb = + ( + cb * *reinterpret_cast< const TInt32* >( clip - 132 ) + ) >> 16; + + // lower left + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + // 0xffBBGG + p = 0xff0000 | + ( clip[ yy + cr ] << 8 ) | clip[ yy - greenCbCr ]; + // 0xffBBGGRR + d1[ uintsPerDestRow ] = clip[ yy + cb ] | ( p << 8 ); + + // lower right + yy = ( yy2 & 0xff ); + yy2 >>= 8; + + // 0xffBBGG + p = 0xff0000 | + ( clip[ yy + cr ] << 8 ) | clip[ yy - greenCbCr ]; + // 0xffBBGGRR + d1[ uintsPerDestRow + 1 ] = clip[ yy + cb ] | ( p << 8 ); + + // upper left + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + // 0xffBBGG + p = 0xff0000 | + ( clip[ yy + cr ] << 8 ) | clip[ yy - greenCbCr ]; + // 0xffBBGGRR + *d1++ = clip[ yy + cb ] | ( p << 8 ); + + // upper right + yy = ( yy1 & 0xff ); + yy1 >>= 8; + + // 0xffBBGG + p = 0xff0000 | + ( clip[ yy + cr ] << 8 ) | clip[ yy - greenCbCr ]; + // 0xffBBGGRR + *d1++ = clip[ yy + cb ] | ( p << 8 ); + } + } + } + + y1 += ( width << 1 ); + d1 += uintsPerDestRow; + } + + iDestination->UnlockHeap(); + + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYUVPlanarFbsBitmapConverter::DoProcess16MU16MANoScale() <<"), RThread().Id().operator TUint())); + } + +// ----------------------------------------------------------------------------- +// CVTYUVPlanarFbsBitmapConverter::SetSourceL( const TDesC8& aSourceData ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVTYUVPlanarFbsBitmapConverter::SetSourceL( + const TDesC8& aSourceData ) + { + // make sure dimension and buffer size match + if( aSourceData.Length() != + ( ( SourceSize().iWidth * SourceSize().iHeight * 12 ) / 8 ) ) + { + User::Leave( KErrArgument ); + } + SetYUVPtrs( aSourceData ); + } + +// ============================ CVTIYUVFbsBitmapConverter =============================== + +// ----------------------------------------------------------------------------- +// CVTIYUVFbsBitmapConverter::NewL( const TSize& aSourceSize, +// const CFbsBitmap& aDestinationBitmap ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CVTIYUVFbsBitmapConverter* CVTIYUVFbsBitmapConverter::NewL( + const TSize& aSourceSize, + const CFbsBitmap& aDestinationBitmap ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTIYUVFbsBitmapConverter::NewL() >>"), RThread().Id().operator TUint())); + CVTIYUVFbsBitmapConverter* self = NewL( + aSourceSize, aDestinationBitmap.Handle() ); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTIYUVFbsBitmapConverter::NewL() <<"), RThread().Id().operator TUint())); + return self; + } + +// ----------------------------------------------------------------------------- +// CVTIYUVFbsBitmapConverter::NewL( const TSize& aSourceSize, +// TInt aBitmapHandle ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CVTIYUVFbsBitmapConverter* CVTIYUVFbsBitmapConverter::NewL( + const TSize& aSourceSize, + TInt aBitmapHandle ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTIYUVFbsBitmapConverter::NewL() >>"), RThread().Id().operator TUint())); + CVTIYUVFbsBitmapConverter* self = new (ELeave) + CVTIYUVFbsBitmapConverter( aSourceSize ); + CleanupStack::PushL( self ); + self->ConstructL( aBitmapHandle ); + CleanupStack::Pop(); // self + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTIYUVFbsBitmapConverter::NewL() <<"), RThread().Id().operator TUint())); + return self; + } + +// ----------------------------------------------------------------------------- +// CVTIYUVFbsBitmapConverter::SetYUVPtrs( const TDesC8& aSourceData ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTIYUVFbsBitmapConverter::SetYUVPtrs( const TDesC8& aSourceData ) + { + TInt ySize = SourceSize().iWidth * SourceSize().iHeight; + TInt ySizeDiv4 = ( ySize >> 2 ); + iY = aSourceData.Mid( 0, ySize ).Ptr(); + iU = aSourceData.Mid( ySize, ySizeDiv4 ).Ptr(); + iV = aSourceData.Mid( ySize + ySizeDiv4, ySizeDiv4 ).Ptr(); + } + +// ----------------------------------------------------------------------------- +// CVTIYUVFbsBitmapConverter::CVTIYUVFbsBitmapConverter( const TSize& +// aSourceSize ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CVTIYUVFbsBitmapConverter::CVTIYUVFbsBitmapConverter( const TSize& aSourceSize ) +: CVTYUVPlanarFbsBitmapConverter( aSourceSize ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTIYUVFbsBitmapConverter::CVTIYUVFbsBitmapConverter() >>"), RThread().Id().operator TUint())); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTIYUVFbsBitmapConverter::CVTIYUVFbsBitmapConverter() <<"), RThread().Id().operator TUint())); + } + +// ============================ CVTYV12FbsBitmapConverter =============================== + +// ----------------------------------------------------------------------------- +// CVTYV12FbsBitmapConverter::NewL( const TSize& aSourceSize, +// const CFbsBitmap& aDestinationBitmap ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CVTYV12FbsBitmapConverter* CVTYV12FbsBitmapConverter::NewL( + const TSize& aSourceSize, + const CFbsBitmap& aDestinationBitmap ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYV12FbsBitmapConverter::NewL() >>"), RThread().Id().operator TUint())); + CVTYV12FbsBitmapConverter* self = NewL( + aSourceSize, aDestinationBitmap.Handle() ); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYV12FbsBitmapConverter::NewL() <<"), RThread().Id().operator TUint())); + return self; + } + +// ----------------------------------------------------------------------------- +// CVTYV12FbsBitmapConverter::NewL( const TSize& aSourceSize, +// TInt aBitmapHandle ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CVTYV12FbsBitmapConverter* CVTYV12FbsBitmapConverter::NewL( + const TSize& aSourceSize, + TInt aBitmapHandle ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYV12FbsBitmapConverter::NewL() >>"), RThread().Id().operator TUint())); + CVTYV12FbsBitmapConverter* self = new (ELeave) + CVTYV12FbsBitmapConverter( aSourceSize ); + CleanupStack::PushL( self ); + self->ConstructL( aBitmapHandle ); + CleanupStack::Pop(); // self + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYV12FbsBitmapConverter::NewL() <<"), RThread().Id().operator TUint())); + return self; + } + +// ----------------------------------------------------------------------------- +// CVTYV12FbsBitmapConverter::SetYUVPtrs( const TDesC8& aSourceData ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVTYV12FbsBitmapConverter::SetYUVPtrs( const TDesC8& aSourceData ) + { + TInt ySize = SourceSize().iWidth * SourceSize().iHeight; + TInt ySizeDiv4 = ( ySize >> 2 ); + iY = aSourceData.Mid( 0, ySize ).Ptr(); + iV = aSourceData.Mid( ySize, ySizeDiv4 ).Ptr(); + iU = aSourceData.Mid( ySize + ySizeDiv4, ySizeDiv4 ).Ptr(); + } + +// ----------------------------------------------------------------------------- +// CVTYV12FbsBitmapConverter::CVTYV12FbsBitmapConverter( +// const TSize& aSourceSize ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CVTYV12FbsBitmapConverter::CVTYV12FbsBitmapConverter( const TSize& aSourceSize ) +: CVTYUVPlanarFbsBitmapConverter( aSourceSize ) + { + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYV12FbsBitmapConverter::CVTYV12FbsBitmapConverter() >>"), RThread().Id().operator TUint())); + __IF_DEBUG(Print(_L("VideoSource: [%d] CVTYV12FbsBitmapConverter::CVTYV12FbsBitmapConverter() <<"), RThread().Id().operator TUint())); + } + +// ============================ CVSFbsBitmapIYUVConverter =============================== + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::CVSFbsBitmapIYUVConverter() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CVSFbsBitmapIYUVConverter::CVSFbsBitmapIYUVConverter() + { + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::NewL( const CFbsBitmap& aBitmap ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CVSFbsBitmapIYUVConverter* CVSFbsBitmapIYUVConverter::NewL( + const CFbsBitmap& aBitmap ) + { + CVSFbsBitmapIYUVConverter* self = new (ELeave) CVSFbsBitmapIYUVConverter(); + CleanupStack::PushL( self ); + self->ConstructL( aBitmap ); + CleanupStack::Pop(); // self + return self; + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::~CVSFbsBitmapIYUVConverter() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CVSFbsBitmapIYUVConverter::~CVSFbsBitmapIYUVConverter() + { + delete iSource; + delete iYUVData; + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::SetSourceL( const CFbsBitmap& aBitmap ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVSFbsBitmapIYUVConverter::SetSourceL( const CFbsBitmap& aBitmap ) + { + ReConstructL( aBitmap ); + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::ProcessL() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVSFbsBitmapIYUVConverter::ProcessL() + { + switch( iSource->DisplayMode() ) + { + case EColor4K: + DoProcess( VSReadColor4K ); + break; + + case EColor64K: + DoProcess( VSReadColor64K ); + break; + + case EColor16M: + DoProcess( VSReadColor16M ); + break; + + case EColor16MU: + DoProcess( VSReadColor16MU ); + break; + + case EColor16MA: + DoProcess( VSReadColor16MA ); + break; + + default: + User::Leave( KErrNotSupported ); + break; + }; + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::YUVData() const +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C TPtrC8 CVSFbsBitmapIYUVConverter::YUVData() const + { + return *iYUVData; + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::ConstructL( const CFbsBitmap& aBitmap ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapIYUVConverter::ConstructL( const CFbsBitmap& aBitmap ) + { + iSource = new (ELeave) CFbsBitmap(); + ReConstructL( aBitmap ); + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::ReConstructL( const CFbsBitmap& aBitmap ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapIYUVConverter::ReConstructL( const CFbsBitmap& aBitmap ) + { + User::LeaveIfError( iSource->Duplicate( aBitmap.Handle() ) ); + + // make sure that source bitmap's displaymode is supported + if( ( iSource->DisplayMode() != EColor4K ) && + ( iSource->DisplayMode() != EColor64K ) && + ( iSource->DisplayMode() != EColor16M ) && + ( iSource->DisplayMode() != EColor16MU ) && + ( iSource->DisplayMode() != EColor16MA ) ) + { + User::Leave( KErrNotSupported ); + } + + if( !iYUVData || !( iSize == iSource->SizeInPixels() ) ) + { + iSize = iSource->SizeInPixels(); + delete iYUVData; iYUVData = 0; + TInt ySize = iSize.iWidth * iSize.iHeight; + iYUVData = HBufC8::NewMaxL( ySize + ( ySize >> 1 ) ); + iY.Set( iYUVData->Des().Mid( 0, ySize ) ); + iU.Set( iYUVData->Des().Mid( ySize, ySize >> 2 ) ); + iV.Set( iYUVData->Des().Mid( ySize + ( ySize >> 2 ), ySize >> 2 ) ); + } + } + +// ----------------------------------------------------------------------------- +// CVSFbsBitmapIYUVConverter::DoProcess( TVSColorReadFunc aReadFunction ) +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapIYUVConverter::DoProcess( TVSColorReadFunc aReadFunction ) + { + TUint8* pY = const_cast( iY.Ptr() ); + TUint8* pU = const_cast( iU.Ptr() ); + TUint8* pV = const_cast( iV.Ptr() ); + TVSYCrCb yuv1, yuv2; + + iSource->LockHeap(); + TAny* s = iSource->DataAddress(); + for( TInt h = 0; h < iSize.iHeight; h++ ) + { + if( h&1 ) + { + // Note! width must be even divisible by 2 + for( TInt w = 0; w < iSize.iWidth >> 1; w++ ) + { + *pY++ = RGBtoYCbCr( &yuv1, aReadFunction( s ) ); + *pY++ = RGBtoYCbCr( &yuv2, aReadFunction( s ) ); + *pU++ = static_cast( AVG( yuv1.iCb, yuv2.iCb ) ); + *pV++ = static_cast( AVG( yuv1.iCr, yuv2.iCr ) ); + } + } + else + { + // Note! width must be even divisible by 2 + for( TInt w = 0; w < iSize.iWidth >> 1; w++ ) + { + *pY++ = RGBtoYCbCr( &yuv1, aReadFunction( s ) ); + *pY++ = RGBtoYCbCr( &yuv2, aReadFunction( s ) ); + *pU++ = static_cast( + AVG( *pU, AVG( yuv1.iCb, yuv2.iCb ) ) ); + *pV++ = static_cast( + AVG( *pV, AVG( yuv1.iCr, yuv2.iCr ) ) ); + } + // if even row -> decrease pU and pV, we will calculate average for + // those on odd rows + pU -= ( iSize.iWidth >> 1 ); + pV -= ( iSize.iWidth >> 1 ); + } + } + iSource->UnlockHeap(); + } + +// End of File