mmplugins/imagingplugins/codecs/JPEGCodec/JPGYCBCR.CPP
changeset 0 40261b775718
--- /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 <e32base.h>
+
+#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<TUint16*>(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