diff -r 951a5db380a0 -r e0b5df5c0969 videoeditorengine/vedengine/videoprocessor/src/yuv2rgb24.cpp --- a/videoeditorengine/vedengine/videoprocessor/src/yuv2rgb24.cpp Fri Jan 29 14:08:33 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,419 +0,0 @@ -/* -* 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: -* Implementation of class CYuv2Rgb24. -* YUV to EColor16M colorspace converter concrete classes. -* -*/ - - - - -// EXTERNAL RESOURCES - - -// Include Files - -#include -#include "yuvconverter.h" -#include "yuv2rgb24.h" -#include "brightnesscontrast.h" - - -// MEMBER FUNCTIONS - - -//============================================================================= - -/* ------------------------------------------------------------------------------ - - CYuv2Rgb24 - - CYuv2Rgb24() - - Standard C++ constructor - ------------------------------------------------------------------------------ -*/ - -CYuv2Rgb24::CYuv2Rgb24() -{ - iRgbLookupTable = 0; - iGamma = 65536; - iBrightnessContrast = KMedBrightnessContrastIndex; - -} - - - -/* ------------------------------------------------------------------------------ - - CYuv2Rgb24 - - ~CYuv2Rgb24() - - Standard C++ destructor - ------------------------------------------------------------------------------ -*/ - -CYuv2Rgb24::~CYuv2Rgb24() -{ - User::Free(iRgbLookupTable); -} - - - -/* ------------------------------------------------------------------------------ - - CYuv2Rgb24 - - ConstructL() - - Standard Symbian OS second-phase constructor. Initializes the object. - ------------------------------------------------------------------------------ -*/ - -void CYuv2Rgb24::ConstructL(TUint aWidth, TUint aHeight, TUint aMaxWidth, TUint aMaxHeight) -{ - // Remember the dimensions -// __ASSERT_ALWAYS(((aWidth & 1) == 0) && ((aHeight & 1) == 0), -// User::Leave(KErrArgument)); - iWidth = aWidth; - iHeight = aHeight; - if ( iWidth > aMaxWidth ) { - iCropWidth = (iWidth-aMaxWidth)/2; - iWidth = aMaxWidth; - } - else { - iCropWidth = 0; - } - if ( iHeight > aMaxHeight ) { - iCropHeight = (iHeight-aMaxHeight)/2; - iHeight = aMaxHeight; - } - else { - iCropHeight = 0; - } - - // Allocate the RGB saturate/gamma lookup table - iRgbLookupTable = (TUint8*) User::AllocL(ESaturateLength); - - // Initialize brightness & contrast value, this will calculate the conversion table - // Since this uses the median index, it makes no difference if the preferred - // enhancement is this or gamma. Furthermore, changes to the value will be done using - // the appropriate method. - SetBrightnessContrast(KMaxBCInputIndex/2); -} - - - -/* ------------------------------------------------------------------------------ - - CYuv2Rgb24 - - SetGamma() - - Sets the conversion gamma value and recalculates the look-up table - ------------------------------------------------------------------------------ -*/ - -void CYuv2Rgb24::SetGamma(TInt aGamma) -{ - TInt i, v; - TReal vNorm; - - // Remember gamma and convert it to floating point - iGamma = aGamma; - TReal fGamma = TReal(iGamma) / TReal(65536); - - // Calculate table entries for all possible RGB values: - for ( i = 0; i < ESaturateLength; i++ ) - { - // Actual RGB value for this table index - v = i - ESaturateOffset; - - // Saturate if <0 or >255, otherwise calculate gamma - if ( v < 0 ) - v = 0; - else if ( v > 255 ) - v = 255; - else - { - // Normalize v: - vNorm = TReal(v) / TReal(255); - - // Gamma-correct: v = v ^ gamma - Math::Pow(vNorm, vNorm, fGamma); - - // Scale back to [0..255] and clamp: - vNorm = (TReal(255) * vNorm) + 0.5; - v = (TInt) vNorm; - if ( v < 0 ) v = 0; - if ( v > 255 ) v = 255; - } - - // 24bpp RGB has range [0..255] for all components, store to table: - iRgbLookupTable[i] = (TUint8) v; - } -} - -/* ------------------------------------------------------------------------------ - - CYuv2Rgb24 - - SetBrightnessContrast() - - Sets the index to the predefined brightness&contrast lookup table - (KBrightnessContrastEnhParam) and recalculates the RGB look-up table - The algorithm was developed by IMAAMI for Kenny display. - ------------------------------------------------------------------------------ -*/ -void CYuv2Rgb24::SetBrightnessContrast(TInt aBCIndex) -{ - TInt i, v; - TReal vNorm; - - // Convert & remember brightness-contrast index. aBCIndex == 0 to KMaxBCInputIndex. - iBrightnessContrast = (aBCIndex*KMaxBrightnessContrastIndex)/KMaxBCInputIndex; - - // Calculate table entries for all possible RGB values: - for ( i = 0; i < ESaturateLength; i++ ) - { - // Actual RGB value for this table index - v = 298 * (i - ESaturateOffset - 16) / 256; - // (see Convert()) - - // Saturate if <0 or >255, otherwise calculate value - if ( v < 0 ) - v = 0; - else if ( v > 255 ) - v = 255; - else - { - - // Normalize v: - vNorm = TReal(v) / TReal(255); - - vNorm = KBrightnessContrastEnhParam[iBrightnessContrast].a * vNorm + KBrightnessContrastEnhParam[iBrightnessContrast].b; - if ( vNorm < 0 ) - vNorm = 0; - else if ( vNorm > 1 ) - vNorm = 1; - Math::Pow( vNorm, vNorm, KBrightnessContrastEnhParam[iBrightnessContrast].g ); - - // Scale back to [0..255] and clamp: - vNorm = (TReal(255) * vNorm) + 0.5; - v = (TInt) vNorm; - if ( v < 0 ) v = 0; - if ( v > 255 ) v = 255; - } - - // 24bpp RGB has range [0..255] for all components, store to table: - iRgbLookupTable[i] = (TUint8) v; - } -} - - -/* ------------------------------------------------------------------------------ - - CYuv2Rgb24 - - Convert() - - Converts a YUV frame to a EColor16M frame - ------------------------------------------------------------------------------ -*/ - -void CYuv2Rgb24::Convert(const TUint8 *aYBuf, const TUint8 *aUBuf, - const TUint8 *aVBuf, - TUint aBufWidth, TUint aBufHeight, - TUint8 *aTarget, TUint aTargetScanlineLength) -{ - TUint cols; - TUint rows = iHeight; - TUint8 *target; - TUint8 *target2; - const TUint8 *yb, *yb2; - TInt rc, gc, bc; - TInt y; - TInt uval, vval; - TUint8 val; - - - __ASSERT_ALWAYS((aBufWidth >= iWidth) && (aBufHeight >= iHeight), - User::Invariant()); - - // Cropping needed? - if ( iCropWidth > 0 ) { - //sets offset to buffers; from now on increments below will always result the same offset, since the increment is aBufWidth - aYBuf += iCropWidth; - aUBuf += iCropWidth/2; - aVBuf += iCropWidth/2; - } - if ( iCropHeight > 0 ) { - //skip lines on top - aYBuf += iCropHeight*aBufWidth; - aUBuf += (iCropHeight/2)*aBufWidth/2; - aVBuf += (iCropHeight/2)*aBufWidth/2; - } - // We don't interpolate the chrominance values at all, since that way we - // can save a lot of multiplications. This actually doesn't affect the - // subjective picture quality much, if at all, with natural images. - - // Conversion is done 2x2 pixels at a time - - // Luminance-only conversion? - if ( (aUBuf != NULL) && (aVBuf != NULL) ) - { - // Full conversion - - // Convert all rows, two at a time - while ( rows ) - { - // Convert all pixels in this row, two at a time - cols = iWidth; - target = aTarget; - target2 = aTarget + aTargetScanlineLength; - yb = aYBuf; - yb2 = aYBuf + aBufWidth; - - while ( cols ) - { - // Charles Poynton: Color FAQ - // (http://www.inforamp.net/~poynton/ColorFAQ.html) - // 30. How do I encode Y'CBCR components from computer R'G'B' ? - - // [normalized] - // R = 1.1643828125 * (Y-16) + 1.59602734375 * (Cr-128) - // G = 1.1643828125 * (Y-16) + -0.39178515625 * (Cb-128) + -0.81296875 * (Cr-128) - // B = 1.1643828125 * (Y-16) + 2.01723046875 * (Cb-128) - - // We'll use fixed-point with 16 bits of fractional part for - // accuracy. Besides, 24bpp RGB is not likely to be used in - // low-CPU devices in the near future... - - // Red chrominance part for this 2x2 block: - vval = ((TInt) aVBuf[0]) - 128; - rc = 104597 * vval; - - // Green chrominance: - uval = ((TInt) aUBuf[0]) - 128; - gc = -25676*uval - 53279*vval; - - // Blue chrominance: - bc = 132201 * uval; - - // Upper left pixel y part for all components: - y = 76309 * (((TInt) yb[0]) - 16) + 32768; // round up - - // Calculate components and store: - // Bitmap format: bbbbbbbb gggggggg rrrrrrrr - target[0] = iRgbLookupTable[((y+bc) >> 16) + ESaturateOffset]; - target[1] = iRgbLookupTable[((y+gc) >> 16) + ESaturateOffset]; - target[2] = iRgbLookupTable[((y+rc) >> 16) + ESaturateOffset]; - - // Upper right pixel: - y = 76309 * (((TInt) yb[1]) - 16) + 32768; - target[3] = iRgbLookupTable[((y+bc) >> 16) + ESaturateOffset]; - target[4] = iRgbLookupTable[((y+gc) >> 16) + ESaturateOffset]; - target[5] = iRgbLookupTable[((y+rc) >> 16) + ESaturateOffset]; - - // Lower left: - y = 76309 * (((TInt) yb2[0]) - 16) + 32768; - target2[0] = iRgbLookupTable[((y+bc) >> 16) + ESaturateOffset]; - target2[1] = iRgbLookupTable[((y+gc) >> 16) + ESaturateOffset]; - target2[2] = iRgbLookupTable[((y+rc) >> 16) + ESaturateOffset]; - - // Lower right: - y = 76309 * (((TInt) yb2[1]) - 16) + 32768; - target2[3] = iRgbLookupTable[((y+bc) >> 16) + ESaturateOffset]; - target2[4] = iRgbLookupTable[((y+gc) >> 16) + ESaturateOffset]; - target2[5] = iRgbLookupTable[((y+rc) >> 16) + ESaturateOffset]; - - // Next two pixels: - target += 6; - target2 += 6; - yb += 2; - yb2 += 2; - aUBuf++; - aVBuf++; - cols -= 2; - } - - // Next rows - rows -= 2; - aYBuf += 2*aBufWidth; - aUBuf += (aBufWidth - iWidth)/2; - aVBuf += (aBufWidth - iWidth)/2; - aTarget += 2*aTargetScanlineLength; - } - } - else - { - // No chrominance given, do a luminance-only conversion - - // Convert all rows - while ( rows ) - { - // Convert all pixels in this row, two at a time - cols = iWidth; - target = aTarget; - - while ( cols ) - { - // Do a pixel: - y = 76309 * (((TInt) aYBuf[0]) - 16) + 32768; - val = iRgbLookupTable[(y >> 16) + ESaturateOffset]; - target[0] = val; - target[1] = val; - target[2] = val; - - // And another one: - y = 76309 * (((TInt) aYBuf[1]) - 16) + 32768; - val = iRgbLookupTable[(y >> 16) + ESaturateOffset]; - target[3] = val; - target[4] = val; - target[5] = val; - - // Next two pixels: - target += 6; - aYBuf += 2; - cols -= 2; - } - - // Next row - rows--; - aYBuf += aBufWidth - iWidth; - aTarget += aTargetScanlineLength; - } - } -} - - - - - -// End of File