diff -r 000000000000 -r 951a5db380a0 videoeditorengine/vedengine/videoprocessor/src/VedRgb2YuvConverter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/vedengine/videoprocessor/src/VedRgb2YuvConverter.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,311 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - Initial contribution +* +* Contributors: +* Ixonos Plc +* +* Description: +* +*/ + + + +// INCLUDE FILES +#include +#include +#include "VedRgb2YuvConverter.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS +#ifdef _DEBUG +# define __IF_DEBUG(t) {RDebug::t;} +#else +# define __IF_DEBUG(t) +#endif + +// LOCAL CONSTANTS AND MACROS + +// ?one_line_short_description_of_data +#define AVG(a,b) ( ( a + b ) >> 1 ) + +// MODULE DATA STRUCTURES + +/** +* ?one_line_short_description. +* ?other_description_lines +* +* @lib ?library +* @since ?Series60_version +*/ +struct TVSYCrCb + { + public: + // ?one_line_short_description_of_data + TInt iY; + + // ?one_line_short_description_of_data + TInt iCb; + + // ?one_line_short_description_of_data + TInt iCr; + }; + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +inline 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( aYuv->iY ); + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor4K( TAny*& aSource ) + { + TUint16* s = static_cast( aSource ); + TRgb rgb( TRgb::Color4K( *s++ ) ); + aSource = s; + return rgb; + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor64K( TAny*& aSource ) + { + TUint16* s = static_cast( aSource ); + TRgb rgb( TRgb::Color64K( *s++ ) ); + aSource = s; + return rgb; + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TRgb VSReadColor16M( TAny*& aSource ) + { + TUint8* s = static_cast( aSource ); + TRgb rgb( s[2], s[1], s[0] ); + aSource = s + 3; + return rgb; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ============================ CVSFbsBitmapYUV420Converter =============================== + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CVSFbsBitmapYUV420Converter* CVSFbsBitmapYUV420Converter::NewL( const CFbsBitmap& aBitmap ) + { + CVSFbsBitmapYUV420Converter* self = new (ELeave) CVSFbsBitmapYUV420Converter(); + CleanupStack::PushL( self ); + self->ConstructL( aBitmap ); + CleanupStack::Pop(); // self + return self; + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CVSFbsBitmapYUV420Converter::~CVSFbsBitmapYUV420Converter() + { + delete iSource; + delete iYUVData; + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapYUV420Converter::SetSourceL( const CFbsBitmap& aBitmap ) + { + ReConstructL( aBitmap ); + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapYUV420Converter::ProcessL() + { + switch( iSource->DisplayMode() ) + { + case EColor4K: + DoProcess( VSReadColor4K ); + break; + + case EColor64K: + DoProcess( VSReadColor64K ); + break; + + case EColor16M: + DoProcess( VSReadColor16M ); + break; + + default: + User::Leave( KErrNotSupported ); + break; + }; + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TPtrC8 CVSFbsBitmapYUV420Converter::YUVData() const + { + return *iYUVData; + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapYUV420Converter::ConstructL( const CFbsBitmap& aBitmap ) + { + iSource = new (ELeave) CFbsBitmap(); + ReConstructL( aBitmap ); + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapYUV420Converter::ReConstructL( const CFbsBitmap& aBitmap ) + { + User::LeaveIfError( iSource->Duplicate( aBitmap.Handle() ) ); + + // make sure that destination bitmap's displaymode is supported + if( ( iSource->DisplayMode() != EColor4K ) && ( iSource->DisplayMode() != EColor64K ) && ( iSource->DisplayMode() != EColor16M ) ) + { + 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 ) ); + } + } + +// ----------------------------------------------------------------------------- +// ?classname::?member_function +// ?implementation_description +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVSFbsBitmapYUV420Converter::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++ ) + { + for( TInt w = 0; w < iSize.iWidth>>1; w++ ) // Note! width must be even divisible by 2 + { + *pY++ = RGBtoYCbCr( &yuv1, aReadFunction( s ) ); + *pY++ = RGBtoYCbCr( &yuv2, aReadFunction( s ) ); + if( h&1 ) + { + *pU++ = static_cast( AVG( yuv1.iCb, yuv2.iCb ) ); + *pV++ = static_cast( AVG( yuv1.iCr, yuv2.iCr ) ); + } + else + { + *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 + if( !(h&1) ) + { + pU -= ( iSize.iWidth >> 1 ); + pV -= ( iSize.iWidth >> 1 ); + } + } + iSource->UnlockHeap(); + } + +// End of File