mmplugins/imagingplugins/codecs/JPEGCodec/JPGYCBCR.CPP
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32base.h>
       
    17 
       
    18 #include "JpegTypes.h"
       
    19 
       
    20 #if defined(__ARMCC__)
       
    21 // use ARM instruction for performance-critical code
       
    22 #pragma push
       
    23 #pragma arm 
       
    24 #pragma O3 
       
    25 #pragma Otime
       
    26 #endif
       
    27 
       
    28 TRgb TYCbCr::YCbCrtoRGB(TInt aY,TInt aCb,TInt aCr)
       
    29 	{
       
    30 	aCb -= 128;
       
    31 	aCr -= 128;
       
    32 
       
    33 	register TInt red = aY + ((KRedCrFactor * aCr) >> 16);
       
    34 	register TInt green = aY - ((KGreenCbFactor * aCb + KGreenCrFactor * aCr) >> 16);
       
    35 	register TInt blue = aY + ((KBlueCbFactor * aCb) >> 16);
       
    36 
       
    37 	return TRgb(ClipColorComponent(red),
       
    38 		        ClipColorComponent(green),
       
    39 		        ClipColorComponent(blue)
       
    40 		        );
       
    41 	}
       
    42 /**
       
    43 	Clamp and shift blue component for composing Color64K later
       
    44 */
       
    45 FORCEDINLINE TUint ClampBlue64K(TInt aValue)
       
    46 	{
       
    47 	return (aValue < 0) ? 0 : (aValue > 255) ? (255>>3) : (aValue>>3);
       
    48 	}
       
    49 	
       
    50 /**
       
    51 	Clamp and shift green component for composing Color64K later
       
    52 */
       
    53 FORCEDINLINE TUint ClampGreen64K(TInt aValue)
       
    54 	{
       
    55 	return (aValue < 0) ? 0 : (aValue > 255) ? (0xFC<<3) : ((aValue & 0xFC)<<3);
       
    56 	}
       
    57 	
       
    58 /**
       
    59 	Clamp and shift red component for composing Color64K later
       
    60 */
       
    61 FORCEDINLINE TUint ClampRed64K(TInt aValue)
       
    62 	{
       
    63 	return (aValue < 0) ? 0 : (aValue > 255) ? (0xF8<<8) : ((aValue & 0xF8)<<8);
       
    64 	}
       
    65 
       
    66 /*static*/
       
    67 void TYCbCr::YCbCrtoRaw64K(TInt aY,TInt aCb,TInt aCr, TRgb* aPtr)
       
    68 	{
       
    69 	aCb -= 128;
       
    70 	aCr -= 128;
       
    71 	
       
    72 	(reinterpret_cast<TUint16*>(aPtr))[0]=
       
    73 								ClampBlue64K(aY + ((KBlueCbFactor * aCb) >> 16) ) 
       
    74 								| ClampGreen64K(aY - ((KGreenCbFactor * aCb + KGreenCrFactor * aCr) >> 16))
       
    75 								| ClampRed64K( aY + ((KRedCrFactor * aCr) >> 16) );	
       
    76 	}
       
    77 
       
    78 
       
    79 void TYCbCr::YCbCrtoRawRGB(TInt aY,TInt aCb,TInt aCr, TRgb* aPtr)
       
    80 	{
       
    81 	TYCbCr::YCbCrtoRawRGBInl(aY, aCb, aCr, aPtr);
       
    82 	}
       
    83 
       
    84 /**
       
    85     Calculate Y comp for every pixel and  U,V as an average for 2 pixels
       
    86     (Accumulate an average in RGB then go to the YUV colour space)
       
    87     Scaled fixed point math is used i.e. everything which is more than 1.0 is shifted by 16 bits
       
    88     y  = 0.299 * R + 0.587G + 0.114 * B
       
    89     cr = 0.5 * R - 0.419G - 0.081 * B
       
    90     cb = 0.5 * B -0.169 * R - 0.331 * G
       
    91 */
       
    92 void TYCbCr::RGBtoYCbCr2PixUVSum(TDataUnit::TDataUnitElemType* aYPtr,TDataUnit::TDataUnitElemType* aCbPtr, 
       
    93                                                     CRgbBufferPtr::TConstRgbBufferPtr aRgbBuffer)
       
    94 	{
       
    95 
       
    96 	TInt red 	= CRgbBufferPtr::Red(aRgbBuffer);
       
    97 	TInt green 	= CRgbBufferPtr::Green(aRgbBuffer);
       
    98 	TInt blue 	= CRgbBufferPtr::Blue(aRgbBuffer);
       
    99 
       
   100 	aYPtr[0]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 );
       
   101 	
       
   102 	aRgbBuffer 	= CRgbBufferPtr::ShiftPtr(aRgbBuffer,1);
       
   103 
       
   104 	red 	+= CRgbBufferPtr::Red(aRgbBuffer);
       
   105 	green 	+= CRgbBufferPtr::Green(aRgbBuffer);
       
   106 	blue 	+= CRgbBufferPtr::Blue(aRgbBuffer);	
       
   107 
       
   108     //                                        blue * 0.5                                                      de-scale and div by 2 
       
   109 	aCbPtr[0]               = 128 + TInt16( ((blue << 15) - (KCbRedFactor * red) - (KCbGreenFactor * green) ) >> 17);
       
   110     //                                        red * 0.5                                                      de-scale and div by 2 	
       
   111 	aCbPtr[KJpgDCTBlockSize]= 128 + TInt16( ((red << 15) - (KCrGreenFactor * green) - (KCrBlueFactor * blue)) >> 17);
       
   112 		
       
   113 	red 		= CRgbBufferPtr::Red(aRgbBuffer);
       
   114 	green 		= CRgbBufferPtr::Green(aRgbBuffer);
       
   115 	blue 		= CRgbBufferPtr::Blue(aRgbBuffer);	
       
   116 	
       
   117 	aYPtr[1]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 );
       
   118 
       
   119 	}
       
   120 	
       
   121 /**
       
   122     Calculate Y comp for every pixel and  U,V as an average for 4 pixels square
       
   123     (Accumulate an average in RGB then go to the YUV colour space)
       
   124     using aLineStride for going to the next line
       
   125     This function effectively combines two calls to RGBtoYCbCr2PixUVSum and provides with some speed
       
   126     improvement due to better use of local vars rather than 2 calls to the RGBtoYCbCr2PixUVSum()
       
   127     See also RGBtoYCbCr2PixUVSum()
       
   128 */
       
   129 void TYCbCr::RGBtoYCbCr4PixUVSum(TDataUnit::TDataUnitElemType* aYPtr, TDataUnit::TDataUnitElemType* aCb, 
       
   130                                     CRgbBufferPtr::TConstRgbBufferPtr aRgbBuffer, TInt aLineStride)
       
   131 	{
       
   132 	const TInt KYNextLineIdx = 8;
       
   133 	TInt redS 	= CRgbBufferPtr::Red(aRgbBuffer);
       
   134 	TInt greenS	= CRgbBufferPtr::Green(aRgbBuffer);
       
   135 	TInt blueS 	= CRgbBufferPtr::Blue(aRgbBuffer);
       
   136 
       
   137 	aYPtr[0]= TInt16( TUint( (KYRedFactor * redS) + (KYGreenFactor * greenS) + (KYBlueFactor * blueS) ) >> 16 );
       
   138 	
       
   139 	aRgbBuffer 	= CRgbBufferPtr::ShiftPtr(aRgbBuffer, 1);
       
   140 	
       
   141 	TInt red 	= CRgbBufferPtr::Red(aRgbBuffer);
       
   142 	TInt green  = CRgbBufferPtr::Green(aRgbBuffer);
       
   143 	TInt blue   = CRgbBufferPtr::Blue(aRgbBuffer);	
       
   144 
       
   145 	redS 	+= red;
       
   146 	greenS 	+= green;
       
   147 	blueS 	+= blue;	
       
   148 	
       
   149 	aYPtr[1]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 );
       
   150 	
       
   151 	aRgbBuffer = CRgbBufferPtr::ShiftPtr(aRgbBuffer, -1);
       
   152 	aRgbBuffer += aLineStride;
       
   153 	
       
   154 	redS 	+= (red = CRgbBufferPtr::Red(aRgbBuffer));
       
   155 	greenS 	+= (green = CRgbBufferPtr::Green(aRgbBuffer));
       
   156 	blueS 	+= (blue = CRgbBufferPtr::Blue(aRgbBuffer));
       
   157 
       
   158     aYPtr[KYNextLineIdx]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 );
       
   159     
       
   160 	aRgbBuffer = CRgbBufferPtr::ShiftPtr(aRgbBuffer, 1);
       
   161 	
       
   162 	redS 	+= (red = CRgbBufferPtr::Red(aRgbBuffer));
       
   163 	greenS 	+= (green = CRgbBufferPtr::Green(aRgbBuffer));
       
   164 	blueS 	+= (blue = CRgbBufferPtr::Blue(aRgbBuffer));
       
   165 	
       
   166 	aYPtr[KYNextLineIdx+1]= TInt16( TUint( (KYRedFactor * red) + (KYGreenFactor * green) + (KYBlueFactor * blue) ) >> 16 );
       
   167 	//                       blue * 0.5                                                      de-scale and div by 4
       
   168 	aCb[0]= 128 + TInt16( ((blueS << 15) - (KCbRedFactor * redS) - (KCbGreenFactor * greenS) ) >> 18);
       
   169 	//                                       red * 0.5                                                   de-scale and div by 4
       
   170 	aCb[KJpgDCTBlockSize]= 128 + TInt16( ((redS << 15) - (KCrGreenFactor * greenS) - (KCrBlueFactor * blueS)) >> 18);
       
   171 	}	
       
   172 
       
   173 #if defined(__ARMCC__)
       
   174 #pragma pop
       
   175 #endif