imageeditorengine/filters/FilterRedEye/Src/CFilterRedEye.cpp
changeset 1 edfc90759b9f
equal deleted inserted replaced
0:57d4cdd99204 1:edfc90759b9f
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "CFilterRedEye.h"
       
    21 
       
    22 
       
    23 const TInt KHueRedLimitLow	= 15;
       
    24 const TInt KHueRedLimitHigh = 245;
       
    25 const TInt KSatLimitLow		= 80; 
       
    26 
       
    27 //=============================================================================
       
    28 EXPORT_C TInt CFilterRedEye::Create()
       
    29 	{
       
    30 	CFilterRedEye * ptr = NULL;
       
    31 	TRAPD( error, ptr = NewL(); );
       
    32 	if( error != KErrNone )
       
    33 		{
       
    34 		ptr = NULL;
       
    35 		}
       
    36 	return (TInt)((MImageFilter*)ptr);
       
    37 	}
       
    38 
       
    39 //=============================================================================
       
    40 CFilterRedEye* CFilterRedEye::NewL()
       
    41 	{
       
    42 	CFilterRedEye* self = new( ELeave )CFilterRedEye();
       
    43 	CleanupStack::PushL( self );
       
    44 	self->ConstructL();
       
    45 	CleanupStack::Pop( self );
       
    46 	return self;
       
    47 	}
       
    48 
       
    49 //=============================================================================
       
    50 CFilterRedEye::~CFilterRedEye()
       
    51 	{
       
    52 	}
       
    53 
       
    54 
       
    55 //=============================================================================
       
    56 CFilterRedEye::CFilterRedEye()
       
    57 	{
       
    58 
       
    59 	}
       
    60 
       
    61 //=============================================================================
       
    62 void CFilterRedEye::ConstructL()
       
    63 	{
       
    64 
       
    65 	}
       
    66 
       
    67 //=============================================================================
       
    68 TRect CFilterRedEye::Rect()
       
    69 	{
       
    70 	return iChild->Rect();
       
    71 	}
       
    72 
       
    73 //=============================================================================
       
    74 TReal CFilterRedEye::Scale()
       
    75 	{
       
    76 	return iChild->Scale();
       
    77 	}
       
    78 
       
    79 //=============================================================================
       
    80 TSize CFilterRedEye::ViewPortSize()
       
    81 {
       
    82     return iChild->ViewPortSize();
       
    83 }
       
    84 
       
    85 //=============================================================================
       
    86 TBlock * CFilterRedEye::GetBlockL ( const TRect & aRect )
       
    87 {
       
    88     TBlock * pB = iChild->GetBlockL(aRect);
       
    89     if (!pB) return NULL;
       
    90     if ( iRedEyeRectSc.Intersects (aRect) )
       
    91     {
       
    92         TUint32 * pD = pB->iData;
       
    93         TInt column = 0;
       
    94         TInt rows = 0;
       
    95         for (TInt i = 0; i < pB->iDataLength; ++i, ++pD)
       
    96         {        
       
    97 		    TUint8 hue = Hue (*pD);
       
    98 		    TUint8 sat = Saturation (*pD);
       
    99 		    if ( ((hue < KHueRedLimitLow) || (hue > KHueRedLimitHigh)) && (sat > KSatLimitLow) )
       
   100 		    {
       
   101 				// Check if the pixel is inside the intersection of 
       
   102 				// the requested block and the red eye rect
       
   103 		        if (aRect.iTl.iX + column >= iRedEyeRectSc.iTl.iX &&
       
   104 		            aRect.iTl.iY + rows >= iRedEyeRectSc.iTl.iY &&
       
   105                     aRect.iTl.iX + column < iRedEyeRectSc.iBr.iX &&
       
   106                     aRect.iTl.iY + rows < iRedEyeRectSc.iBr.iY)
       
   107 		        {
       
   108 					// Check if the pixel is inside the cirle that fits 
       
   109 					// into the red eye rect (assuming it is square).
       
   110 					TInt r = static_cast<TInt> ( (TReal)(iRedEyeRectSc.iBr.iX - iRedEyeRectSc.iTl.iX) / 2 + 0.5);
       
   111 					TInt a = (iRedEyeRectSc.iTl.iX + r) - (aRect.iTl.iX + column);
       
   112 					TInt b = (iRedEyeRectSc.iTl.iY + r) - (aRect.iTl.iY + rows);
       
   113 					if ( (a*a + b*b) <= r*r )
       
   114 					{
       
   115 						TUint32 c = *pD;
       
   116 						TUint8 cb = (TUint8)(c & 0xFF);
       
   117 						c >>= 8;
       
   118 						TUint8 cg = (TUint8)(c & 0xFF);
       
   119 						c >>= 8;
       
   120 						TUint8 cr = (TUint8)(c & 0xFF);
       
   121 						TUint8 y = (TUint8)((306 * cr + 587 * cg + 117 * cb) >> 10);
       
   122 						*pD = (y | (y << 8) | (y << 16));
       
   123 					}
       
   124 		        }
       
   125 		    }
       
   126 
       
   127 		    ++column;
       
   128 		    if (column >= pB->iWidth)
       
   129 		    {
       
   130 		        column = 0;
       
   131 		        ++rows;
       
   132 		    }
       
   133         }
       
   134     }
       
   135     return pB;
       
   136 }
       
   137 
       
   138 
       
   139 //=============================================================================
       
   140 void CFilterRedEye::SetParent( MImageFilter* aParent )
       
   141 	{
       
   142 	iParent = aParent;
       
   143 	}
       
   144 
       
   145 //=============================================================================
       
   146 void CFilterRedEye::SetChild( MImageFilter* aChild )
       
   147 	{
       
   148 	iChild = aChild;
       
   149 	}
       
   150 
       
   151 //=============================================================================
       
   152 TInt CFilterRedEye::CmdL( const TDesC16& aCmd )
       
   153 	{
       
   154 
       
   155 	TLex lex (aCmd);
       
   156 
       
   157 	while ( !lex.Eos() )
       
   158 	{
       
   159 		TPtrC token = lex.NextToken();
       
   160 		if( token.Compare( _L("ulc") ) == 0 )
       
   161 			{
       
   162 			TReal relscale = iChild->Scale();
       
   163 			TInt param = 0;
       
   164 			lex.Inc();
       
   165 			lex.Val( param );
       
   166 			iRedEyeRect.iTl.iX = (TInt)((param / relscale) + 0.5);
       
   167 			}
       
   168 		else if( token.Compare( _L("ulr") ) == 0 )
       
   169 			{
       
   170 			TReal relscale = iChild->Scale();
       
   171 			TInt param = 0;
       
   172 			lex.Inc();
       
   173 			lex.Val( param );
       
   174 			iRedEyeRect.iTl.iY = (TInt)((param / relscale) + 0.5);
       
   175 			}
       
   176 		else if( token.Compare( _L("lrc") ) == 0 )
       
   177 			{
       
   178 			TReal relscale = iChild->Scale();
       
   179 			TInt param = 0;
       
   180 			lex.Inc();
       
   181 			lex.Val( param );
       
   182 			iRedEyeRect.iBr.iX = (TInt)((param / relscale) + 0.5);
       
   183 			}
       
   184 		else if( token.Compare( _L("lrr") ) == 0 )
       
   185 			{
       
   186 			TReal relscale = iChild->Scale();
       
   187 			TInt param = 0;
       
   188 			lex.Inc();
       
   189 			lex.Val( param );
       
   190 			iRedEyeRect.iBr.iY = (TInt)((param / relscale) + 0.5);
       
   191 			}
       
   192 		}
       
   193 
       
   194     TReal relscale = iChild->Scale();
       
   195     iRedEyeRectSc.iTl.iX = (TInt)(iRedEyeRect.iTl.iX * relscale + 0.5);
       
   196     iRedEyeRectSc.iTl.iY = (TInt)(iRedEyeRect.iTl.iY * relscale + 0.5);
       
   197     iRedEyeRectSc.iBr.iX = (TInt)(iRedEyeRect.iBr.iX * relscale + 0.5);
       
   198     iRedEyeRectSc.iBr.iY = (TInt)(iRedEyeRect.iBr.iY * relscale + 0.5);
       
   199 
       
   200     return 0;
       
   201 
       
   202 	}
       
   203 
       
   204 //=============================================================================
       
   205 const char* CFilterRedEye::Type()
       
   206 	{
       
   207 	return "negate";
       
   208 	}
       
   209 	
       
   210 //=============================================================================
       
   211 TUint8 CFilterRedEye::Hue ( TUint32 aPixel ) const
       
   212 {
       
   213 
       
   214 	TUint8 g = (TUint8)(aPixel & 0xFF); 
       
   215 	aPixel >>= 8;
       
   216 	TUint8 b = (TUint8)(aPixel & 0xFF); 
       
   217 	aPixel >>= 8;
       
   218 	TUint8 r = (TUint8)(aPixel & 0xFF);
       
   219 
       
   220 	const TInt t1 = (1 << 10);
       
   221 	const TInt t3 = (3 << 10);
       
   222 	const TInt t5 = (5 << 10);
       
   223 	const TInt t6 = (6 << 10);
       
   224 	
       
   225 	TInt h = 0;
       
   226 	TInt v = ( r > g ) ? ( (r > b) ? (r) : (b) ) : ( (g > b) ? (g) : (b) );
       
   227 	TInt m = ( r < g ) ? ( (r < b) ? (r) : (b) ) : ( (g < b) ? (g) : (b) );
       
   228 
       
   229 	if (v != m) 
       
   230 	{
       
   231 
       
   232 		TInt vm = v - m;
       
   233 
       
   234 		if (r == v) 
       
   235 		{
       
   236 			TInt g2 = ((v - g) << 10) / vm;
       
   237 			TInt b2 = ((v - b) << 10) / vm;
       
   238 			h = (g == m) ? (t5 + b2) : (t1 - g2);
       
   239 		}
       
   240 
       
   241 		else if (g == v) 
       
   242 		{
       
   243 			TInt r2 = ((v - r) << 10) / vm;
       
   244 			TInt b2 = ((v - b) << 10) / vm;
       
   245 			h = (b == m) ? (t1 + r2) : (t3 - b2);
       
   246 		}
       
   247 
       
   248 		else 
       
   249 		{
       
   250 			TInt r2 = ((v - r) << 10) / vm;
       
   251 			TInt g2 = ((v - g) << 10) / vm;
       
   252 			h = (r == m) ? (t3 + g2) : (t5 - r2);
       
   253 		}
       
   254 
       
   255 		h *= 255;
       
   256 		h /= t6;
       
   257 	}
       
   258 
       
   259 	return (TUint8)h;
       
   260 }
       
   261 
       
   262 //=============================================================================
       
   263 TUint8 CFilterRedEye::Saturation ( TUint32 aPixel ) const
       
   264 {
       
   265 	TUint8 g = (TUint8)(aPixel & 0xFF); 
       
   266 	aPixel >>= 8;
       
   267 	TUint8 b = (TUint8)(aPixel & 0xFF); 
       
   268 	aPixel >>= 8;
       
   269 	TUint8 r = (TUint8)(aPixel & 0xFF);
       
   270 
       
   271 	TInt v = ( r > g ) ? ( (r > b) ? (r) : (b) ) : ( (g > b) ? (g) : (b) );
       
   272 	TInt m = ( r < g ) ? ( (r < b) ? (r) : (b) ) : ( (g < b) ? (g) : (b) );
       
   273 	TInt l = ((m + v) >> 1);
       
   274 	TInt s = 0;
       
   275 
       
   276 	if (l > 0) 
       
   277 	{
       
   278 		s = v - m;
       
   279 
       
   280 		if (s > 0) {
       
   281 
       
   282 			s *= 255;
       
   283 
       
   284 			if (l <= 127)
       
   285 			{
       
   286 				s /= (v + m);
       
   287 			}
       
   288 			else 
       
   289 			{
       
   290 				s /= (512 - v - m);
       
   291 			}
       
   292 		}
       
   293 	}
       
   294 	else {
       
   295 		s = 0;
       
   296 	}	
       
   297 	return (TUint8)s;
       
   298 }
       
   299 
       
   300 //=============================================================================
       
   301 #if !defined(EKA2)
       
   302 GLDEF_C TInt E32Dll( TDllReason )
       
   303     {
       
   304     return KErrNone;
       
   305     }	
       
   306 #endif