|
1 /* |
|
2 * Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "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 * |
|
14 * Description: Saturation provides functionality adjust image saturation. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include "AknsRlEffectPluginSaturation.h" |
|
21 #include "AknsRlEffectUtil.h" |
|
22 |
|
23 // ================= TEMPLATE IMPL. OF SATURATION ============================== |
|
24 /** |
|
25 * Template implementation of Saturation. Type defines the used data type for |
|
26 * iterating over the bitmap data. X, R, G and B define the used pixel color bit |
|
27 * layout. |
|
28 */ |
|
29 template<class Type,TInt X, TInt R, TInt G, TInt B> |
|
30 class AknsRlEffectSaturation |
|
31 { |
|
32 public: |
|
33 //------------------------------------------------------------------------ |
|
34 static void Process( const CFbsBitmap& aTarget, |
|
35 const CFbsBitmap& aSource, |
|
36 const TInt aAdjustment ) |
|
37 { |
|
38 // ScanLineLength returns bytes, but width must match the Type |
|
39 TInt width = CFbsBitmap::ScanLineLength( aSource.SizeInPixels().iWidth, |
|
40 aSource.DisplayMode() ) / sizeof(Type); |
|
41 TInt height = aSource.SizeInPixels().iHeight; |
|
42 |
|
43 TInt pixelCount = width * height; |
|
44 TInt r,g,b; |
|
45 TInt shade; |
|
46 |
|
47 aTarget.LockHeap( ETrue ); // Lock the global bitmap heap |
|
48 Type* dataT = reinterpret_cast<Type*>( aTarget.DataAddress() ); |
|
49 Type* dataS = reinterpret_cast<Type*>( aSource.DataAddress() ); |
|
50 |
|
51 for( TInt index = 0; index < pixelCount; ++index ) |
|
52 { |
|
53 r = AknsRlRgb<Type,X,R,G,B>::R8(*dataS); |
|
54 g = AknsRlRgb<Type,X,R,G,B>::G8(*dataS); |
|
55 b = AknsRlRgb<Type,X,R,G,B>::B8(*dataS); |
|
56 |
|
57 shade = AknsRlUtil::Grayscale( TUint8(r), TUint8(g), TUint8(b) ); |
|
58 |
|
59 // Note: It is assumed that arithmetic shifting is supported |
|
60 // -> negative values are shifted correctly |
|
61 r = ( AknsRlRgb<Type,X,R,G,B>::R8(*dataS) * (255 + aAdjustment) - aAdjustment * shade ) >> 8; |
|
62 g = ( AknsRlRgb<Type,X,R,G,B>::G8(*dataS) * (255 + aAdjustment) - aAdjustment * shade ) >> 8; |
|
63 b = ( AknsRlRgb<Type,X,R,G,B>::B8(*dataS) * (255 + aAdjustment) - aAdjustment * shade ) >> 8; |
|
64 |
|
65 if( r < 0 ) r = 0; else if( r > 255 ) r = 255; |
|
66 if( g < 0 ) g = 0; else if( g > 255 ) g = 255; |
|
67 if( b < 0 ) b = 0; else if( b > 255 ) b = 255; |
|
68 |
|
69 AknsRlRgb<Type,X,R,G,B>::SetRgb8( dataT, TUint8(r), TUint8(g), TUint8(b) ); |
|
70 |
|
71 dataT++; |
|
72 dataS++; |
|
73 } |
|
74 |
|
75 aTarget.UnlockHeap( ETrue ); // Unlock the global bitmap heap |
|
76 } |
|
77 }; // End of AknsRlEffectSaturation |
|
78 |
|
79 // ============================ MEMBER FUNCTIONS =============================== |
|
80 |
|
81 // ----------------------------------------------------------------------------- |
|
82 // CAknsRlEffectPluginSaturation::CAknsRlEffectPluginSaturation |
|
83 // C++ default constructor can NOT contain any code, that |
|
84 // might leave. |
|
85 // ----------------------------------------------------------------------------- |
|
86 // |
|
87 CAknsRlEffectPluginSaturation::CAknsRlEffectPluginSaturation() |
|
88 { |
|
89 } |
|
90 |
|
91 // ----------------------------------------------------------------------------- |
|
92 // Destructor |
|
93 // ----------------------------------------------------------------------------- |
|
94 // |
|
95 CAknsRlEffectPluginSaturation::~CAknsRlEffectPluginSaturation() |
|
96 { |
|
97 iContext = NULL; // Removes lint nag |
|
98 } |
|
99 |
|
100 // ----------------------------------------------------------------------------- |
|
101 // CAknsRlEffectPluginSaturation::EffectUid |
|
102 // ----------------------------------------------------------------------------- |
|
103 // |
|
104 TUid CAknsRlEffectPluginSaturation::EffectUid() const |
|
105 { |
|
106 return TUid::Uid( KAknsRlEffectPluginSaturationUID ); |
|
107 } |
|
108 |
|
109 // ----------------------------------------------------------------------------- |
|
110 // CAknsRlEffectPluginSaturation::Effect |
|
111 // ----------------------------------------------------------------------------- |
|
112 // |
|
113 MAknsRlEffect* CAknsRlEffectPluginSaturation::Effect( const TInt aInterface ) |
|
114 { |
|
115 if( aInterface == KAknsRlEffectPluginInterfaceEffect ) |
|
116 return this; |
|
117 return NULL; |
|
118 } |
|
119 |
|
120 // ----------------------------------------------------------------------------- |
|
121 // CAknsRlEffectPluginSaturation::InitializeL |
|
122 // ----------------------------------------------------------------------------- |
|
123 // |
|
124 void CAknsRlEffectPluginSaturation::InitializeL() |
|
125 { |
|
126 iContext = NULL; |
|
127 } |
|
128 |
|
129 // ----------------------------------------------------------------------------- |
|
130 // CAknsRlEffectPluginSaturation::Release |
|
131 // ----------------------------------------------------------------------------- |
|
132 // |
|
133 void CAknsRlEffectPluginSaturation::Release() |
|
134 { |
|
135 } |
|
136 |
|
137 // ----------------------------------------------------------------------------- |
|
138 // CAknsRlEffectPluginSaturation::ActivateL |
|
139 // ----------------------------------------------------------------------------- |
|
140 // |
|
141 void CAknsRlEffectPluginSaturation::ActivateL( MAknsRlEffectContext* aContext ) |
|
142 { |
|
143 if( !aContext ) // We absolutely need the context |
|
144 { |
|
145 User::Leave( KErrArgument ); |
|
146 } |
|
147 |
|
148 iContext = aContext; |
|
149 |
|
150 iAdjustment = 0; |
|
151 } |
|
152 |
|
153 // ----------------------------------------------------------------------------- |
|
154 // CAknsRlEffectPluginSaturation::Deactivate |
|
155 // ----------------------------------------------------------------------------- |
|
156 // |
|
157 void CAknsRlEffectPluginSaturation::Deactivate() |
|
158 { |
|
159 } |
|
160 |
|
161 // ----------------------------------------------------------------------------- |
|
162 // CAknsRlEffectPluginSaturation::SetParametersL |
|
163 // ----------------------------------------------------------------------------- |
|
164 // |
|
165 void CAknsRlEffectPluginSaturation::SetParametersL( MAknsRlParameterIterator& aParameters ) |
|
166 { |
|
167 // Iterate over available parameters |
|
168 while( aParameters.HasNext() ) |
|
169 { |
|
170 const TAknsRlParameterData* param = aParameters.NextL(); |
|
171 |
|
172 // Fetch adjustment value |
|
173 if( param->iName->Compare( KAknsRlEffectSaturationAdjustment ) == 0 ) |
|
174 { |
|
175 if( param->iType != EAknsRlParameterTypeNumber ) |
|
176 User::Leave( KErrArgument ); |
|
177 |
|
178 iAdjustment = param->iNumber; |
|
179 } |
|
180 } |
|
181 } |
|
182 |
|
183 // ----------------------------------------------------------------------------- |
|
184 // CAknsRlEffectPluginSaturation::GetCapabilities |
|
185 // ----------------------------------------------------------------------------- |
|
186 // |
|
187 void CAknsRlEffectPluginSaturation::GetCapabilities( TAknsRlEffectCaps& aCaps ) |
|
188 { |
|
189 aCaps.iOutputLayerSupport = KAknsRlLayerRGBOnly; |
|
190 aCaps.iInputLayerASupport = KAknsRlLayerRGBOnly; |
|
191 aCaps.iInputLayerBSupport = KAknsRlLayerNone; |
|
192 } |
|
193 |
|
194 // ----------------------------------------------------------------------------- |
|
195 // CAknsRlEffectPluginSaturation::Render |
|
196 // ----------------------------------------------------------------------------- |
|
197 // |
|
198 TInt CAknsRlEffectPluginSaturation::Render( const TAknsRlRenderOpParam& aParam ) |
|
199 { |
|
200 if( !iContext ) // We absolutely need the context |
|
201 { |
|
202 return KErrBadHandle; |
|
203 } |
|
204 |
|
205 // To do anything we need both, the output layer and input layer |
|
206 if( ( aParam.iOutputLayerStatus & KAknsRlLayerRGBOnly ) && |
|
207 ( aParam.iInputLayerAStatus & KAknsRlLayerRGBOnly ) ) |
|
208 { |
|
209 // Query the layers, uninitialized because we process the whole image |
|
210 TAknsRlLayerData dataTarget; |
|
211 TRAPD( err, iContext->GetLayerDataL( dataTarget, aParam.iOutputLayerIndex, |
|
212 aParam.iOutputLayerStatus, EFalse ) ); |
|
213 if( KErrNone != err ) |
|
214 return KErrArgument; |
|
215 |
|
216 TAknsRlLayerData dataSource; |
|
217 TRAP( err, iContext->GetLayerDataL( dataSource, aParam.iInputLayerAIndex, |
|
218 aParam.iInputLayerAStatus, EFalse ) ); |
|
219 if( KErrNone != err ) |
|
220 return KErrArgument; |
|
221 |
|
222 if( !dataTarget.iRGBBitmap ) // We need the target bitmap |
|
223 return KErrBadHandle; |
|
224 |
|
225 if( !dataSource.iRGBBitmap ) // We need the source bitmap |
|
226 return KErrBadHandle; |
|
227 |
|
228 TDisplayMode modeT = dataTarget.iRGBBitmap->DisplayMode(); |
|
229 TDisplayMode modeS = dataSource.iRGBBitmap->DisplayMode(); |
|
230 |
|
231 // Rgb -> Rgb modes |
|
232 if( EColor64K == modeS && EColor64K == modeT ) |
|
233 { |
|
234 AknsRlEffectSaturation<TUint16,0,5,6,5>::Process( |
|
235 *dataTarget.iRGBBitmap, |
|
236 *dataSource.iRGBBitmap, |
|
237 iAdjustment ); |
|
238 } |
|
239 else if( EColor16MU == modeS && EColor16MU == modeT ) |
|
240 { |
|
241 AknsRlEffectSaturation<TUint32,8,8,8,8>::Process( |
|
242 *dataTarget.iRGBBitmap, |
|
243 *dataSource.iRGBBitmap, |
|
244 iAdjustment ); |
|
245 } |
|
246 else |
|
247 { |
|
248 // Provided layers have illegal display mode combination |
|
249 return KErrArgument; |
|
250 } |
|
251 } |
|
252 else |
|
253 { |
|
254 // Required layers were not provided |
|
255 return KErrArgument; |
|
256 } |
|
257 |
|
258 return KErrNone; |
|
259 } |
|
260 |
|
261 // End of File |