diff -r 000000000000 -r 40261b775718 mmplugins/imagingplugins/codecs/JPEGCodec/JPGYCBCR.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmplugins/imagingplugins/codecs/JPEGCodec/JPGYCBCR.CPP Tue Feb 02 01:56:55 2010 +0200 @@ -0,0 +1,175 @@ +// Copyright (c) 1997-2009 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: +// + +#include + +#include "JpegTypes.h" + +#if defined(__ARMCC__) +// use ARM instruction for performance-critical code +#pragma push +#pragma arm +#pragma O3 +#pragma Otime +#endif + +TRgb TYCbCr::YCbCrtoRGB(TInt aY,TInt aCb,TInt aCr) + { + aCb -= 128; + aCr -= 128; + + register TInt red = aY + ((KRedCrFactor * aCr) >> 16); + register TInt green = aY - ((KGreenCbFactor * aCb + KGreenCrFactor * aCr) >> 16); + register TInt blue = aY + ((KBlueCbFactor * aCb) >> 16); + + return TRgb(ClipColorComponent(red), + ClipColorComponent(green), + ClipColorComponent(blue) + ); + } +/** + Clamp and shift blue component for composing Color64K later +*/ +FORCEDINLINE TUint ClampBlue64K(TInt aValue) + { + return (aValue < 0) ? 0 : (aValue > 255) ? (255>>3) : (aValue>>3); + } + +/** + Clamp and shift green component for composing Color64K later +*/ +FORCEDINLINE TUint ClampGreen64K(TInt aValue) + { + return (aValue < 0) ? 0 : (aValue > 255) ? (0xFC<<3) : ((aValue & 0xFC)<<3); + } + +/** + Clamp and shift red component for composing Color64K later +*/ +FORCEDINLINE TUint ClampRed64K(TInt aValue) + { + return (aValue < 0) ? 0 : (aValue > 255) ? (0xF8<<8) : ((aValue & 0xF8)<<8); + } + +/*static*/ +void TYCbCr::YCbCrtoRaw64K(TInt aY,TInt aCb,TInt aCr, TRgb* aPtr) + { + aCb -= 128; + aCr -= 128; + + (reinterpret_cast(aPtr))[0]= + ClampBlue64K(aY + ((KBlueCbFactor * aCb) >> 16) ) + | ClampGreen64K(aY - ((KGreenCbFactor * aCb + KGreenCrFactor * aCr) >> 16)) + | ClampRed64K( aY + ((KRedCrFactor * aCr) >> 16) ); + } + + +void TYCbCr::YCbCrtoRawRGB(TInt aY,TInt aCb,TInt aCr, TRgb* aPtr) + { + TYCbCr::YCbCrtoRawRGBInl(aY, aCb, aCr, aPtr); + } + +/** + Calculate Y comp for every pixel and U,V as an average for 2 pixels + (Accumulate an average in RGB then go to the YUV colour space) + Scaled fixed point math is used i.e. everything which is more than 1.0 is shifted by 16 bits + y = 0.299 * R + 0.587G + 0.114 * B + cr = 0.5 * R - 0.419G - 0.081 * B + cb = 0.5 * B -0.169 * R - 0.331 * G +*/ +void TYCbCr::RGBtoYCbCr2PixUVSum(TDataUnit::TDataUnitElemType* aYPtr,TDataUnit::TDataUnitElemType* aCbPtr, + CRgbBufferPtr::TConstRgbBufferPtr aRgbBuffer) + { + + TInt red = CRgbBufferPtr::Red(aRgbBuffer); + TInt green = CRgbBufferPtr::Green(aRgbBuffer); + TInt blue = CRgbBufferPtr::Blue(aRgbBuffer); + + aYPtr[0]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 ); + + aRgbBuffer = CRgbBufferPtr::ShiftPtr(aRgbBuffer,1); + + red += CRgbBufferPtr::Red(aRgbBuffer); + green += CRgbBufferPtr::Green(aRgbBuffer); + blue += CRgbBufferPtr::Blue(aRgbBuffer); + + // blue * 0.5 de-scale and div by 2 + aCbPtr[0] = 128 + TInt16( ((blue << 15) - (KCbRedFactor * red) - (KCbGreenFactor * green) ) >> 17); + // red * 0.5 de-scale and div by 2 + aCbPtr[KJpgDCTBlockSize]= 128 + TInt16( ((red << 15) - (KCrGreenFactor * green) - (KCrBlueFactor * blue)) >> 17); + + red = CRgbBufferPtr::Red(aRgbBuffer); + green = CRgbBufferPtr::Green(aRgbBuffer); + blue = CRgbBufferPtr::Blue(aRgbBuffer); + + aYPtr[1]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 ); + + } + +/** + Calculate Y comp for every pixel and U,V as an average for 4 pixels square + (Accumulate an average in RGB then go to the YUV colour space) + using aLineStride for going to the next line + This function effectively combines two calls to RGBtoYCbCr2PixUVSum and provides with some speed + improvement due to better use of local vars rather than 2 calls to the RGBtoYCbCr2PixUVSum() + See also RGBtoYCbCr2PixUVSum() +*/ +void TYCbCr::RGBtoYCbCr4PixUVSum(TDataUnit::TDataUnitElemType* aYPtr, TDataUnit::TDataUnitElemType* aCb, + CRgbBufferPtr::TConstRgbBufferPtr aRgbBuffer, TInt aLineStride) + { + const TInt KYNextLineIdx = 8; + TInt redS = CRgbBufferPtr::Red(aRgbBuffer); + TInt greenS = CRgbBufferPtr::Green(aRgbBuffer); + TInt blueS = CRgbBufferPtr::Blue(aRgbBuffer); + + aYPtr[0]= TInt16( TUint( (KYRedFactor * redS) + (KYGreenFactor * greenS) + (KYBlueFactor * blueS) ) >> 16 ); + + aRgbBuffer = CRgbBufferPtr::ShiftPtr(aRgbBuffer, 1); + + TInt red = CRgbBufferPtr::Red(aRgbBuffer); + TInt green = CRgbBufferPtr::Green(aRgbBuffer); + TInt blue = CRgbBufferPtr::Blue(aRgbBuffer); + + redS += red; + greenS += green; + blueS += blue; + + aYPtr[1]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 ); + + aRgbBuffer = CRgbBufferPtr::ShiftPtr(aRgbBuffer, -1); + aRgbBuffer += aLineStride; + + redS += (red = CRgbBufferPtr::Red(aRgbBuffer)); + greenS += (green = CRgbBufferPtr::Green(aRgbBuffer)); + blueS += (blue = CRgbBufferPtr::Blue(aRgbBuffer)); + + aYPtr[KYNextLineIdx]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 ); + + aRgbBuffer = CRgbBufferPtr::ShiftPtr(aRgbBuffer, 1); + + redS += (red = CRgbBufferPtr::Red(aRgbBuffer)); + greenS += (green = CRgbBufferPtr::Green(aRgbBuffer)); + blueS += (blue = CRgbBufferPtr::Blue(aRgbBuffer)); + + aYPtr[KYNextLineIdx+1]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 ); + // blue * 0.5 de-scale and div by 4 + aCb[0]= 128 + TInt16( ((blueS << 15) - (KCbRedFactor * redS) - (KCbGreenFactor * greenS) ) >> 18); + // red * 0.5 de-scale and div by 4 + aCb[KJpgDCTBlockSize]= 128 + TInt16( ((redS << 15) - (KCrGreenFactor * greenS) - (KCrBlueFactor * blueS)) >> 18); + } + +#if defined(__ARMCC__) +#pragma pop +#endif