|
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 |
|
21 // INCLUDE FILES |
|
22 #include <e32svr.h> |
|
23 #include <fbs.h> |
|
24 #include "VedRgb2YuvConverter.h" |
|
25 |
|
26 // EXTERNAL DATA STRUCTURES |
|
27 |
|
28 // EXTERNAL FUNCTION PROTOTYPES |
|
29 |
|
30 // CONSTANTS |
|
31 |
|
32 // MACROS |
|
33 #ifdef _DEBUG |
|
34 # define __IF_DEBUG(t) {RDebug::t;} |
|
35 #else |
|
36 # define __IF_DEBUG(t) |
|
37 #endif |
|
38 |
|
39 // LOCAL CONSTANTS AND MACROS |
|
40 |
|
41 // ?one_line_short_description_of_data |
|
42 #define AVG(a,b) ( ( a + b ) >> 1 ) |
|
43 |
|
44 // MODULE DATA STRUCTURES |
|
45 |
|
46 /** |
|
47 * ?one_line_short_description. |
|
48 * ?other_description_lines |
|
49 * |
|
50 * @lib ?library |
|
51 * @since ?Series60_version |
|
52 */ |
|
53 struct TVSYCrCb |
|
54 { |
|
55 public: |
|
56 // ?one_line_short_description_of_data |
|
57 TInt iY; |
|
58 |
|
59 // ?one_line_short_description_of_data |
|
60 TInt iCb; |
|
61 |
|
62 // ?one_line_short_description_of_data |
|
63 TInt iCr; |
|
64 }; |
|
65 |
|
66 // LOCAL FUNCTION PROTOTYPES |
|
67 |
|
68 // FORWARD DECLARATIONS |
|
69 |
|
70 // ============================= LOCAL FUNCTIONS =============================== |
|
71 |
|
72 // ----------------------------------------------------------------------------- |
|
73 // ?classname::?member_function |
|
74 // ?implementation_description |
|
75 // (other items were commented in a header). |
|
76 // ----------------------------------------------------------------------------- |
|
77 // |
|
78 inline TUint8 RGBtoYCbCr( TVSYCrCb* aYuv, const TRgb& aColor ) |
|
79 { |
|
80 const TInt YRedFactor = 19595; // 0.299 << 16 |
|
81 const TInt YGreenFactor = 38470; // 0.587 << 16 |
|
82 const TInt YBlueFactor = 7471; // 0.114 << 16 |
|
83 const TInt CbRedFactor = 11056; // 0.1687 << 16 |
|
84 const TInt CbGreenFactor = 21712; // 0.3313 << 16 |
|
85 const TInt CrGreenFactor = 27440; // 0.4187 << 16 |
|
86 const TInt CrBlueFactor = 5328; // 0.0813 << 16 |
|
87 |
|
88 TInt red = aColor.Red(); |
|
89 TInt green = aColor.Green(); |
|
90 TInt blue = aColor.Blue(); |
|
91 |
|
92 aYuv->iY = (YRedFactor * red) + (YGreenFactor * green) + (YBlueFactor * blue); |
|
93 aYuv->iCb = - (CbRedFactor * red) - (CbGreenFactor * green) + (blue << 15); |
|
94 aYuv->iCr = (red << 15) - (CrGreenFactor * green) - (CrBlueFactor * blue); |
|
95 |
|
96 aYuv->iY >>= 16; |
|
97 aYuv->iCb >>= 16; |
|
98 aYuv->iCr >>= 16; |
|
99 |
|
100 aYuv->iCb += 128; |
|
101 aYuv->iCr += 128; |
|
102 |
|
103 return static_cast<TUint8>( aYuv->iY ); |
|
104 } |
|
105 |
|
106 // ----------------------------------------------------------------------------- |
|
107 // ?classname::?member_function |
|
108 // ?implementation_description |
|
109 // (other items were commented in a header). |
|
110 // ----------------------------------------------------------------------------- |
|
111 // |
|
112 TRgb VSReadColor4K( TAny*& aSource ) |
|
113 { |
|
114 TUint16* s = static_cast<TUint16*>( aSource ); |
|
115 TRgb rgb( TRgb::Color4K( *s++ ) ); |
|
116 aSource = s; |
|
117 return rgb; |
|
118 } |
|
119 |
|
120 // ----------------------------------------------------------------------------- |
|
121 // ?classname::?member_function |
|
122 // ?implementation_description |
|
123 // (other items were commented in a header). |
|
124 // ----------------------------------------------------------------------------- |
|
125 // |
|
126 TRgb VSReadColor64K( TAny*& aSource ) |
|
127 { |
|
128 TUint16* s = static_cast<TUint16*>( aSource ); |
|
129 TRgb rgb( TRgb::Color64K( *s++ ) ); |
|
130 aSource = s; |
|
131 return rgb; |
|
132 } |
|
133 |
|
134 // ----------------------------------------------------------------------------- |
|
135 // ?classname::?member_function |
|
136 // ?implementation_description |
|
137 // (other items were commented in a header). |
|
138 // ----------------------------------------------------------------------------- |
|
139 // |
|
140 TRgb VSReadColor16M( TAny*& aSource ) |
|
141 { |
|
142 TUint8* s = static_cast<TUint8*>( aSource ); |
|
143 TRgb rgb( s[2], s[1], s[0] ); |
|
144 aSource = s + 3; |
|
145 return rgb; |
|
146 } |
|
147 |
|
148 // ============================ MEMBER FUNCTIONS =============================== |
|
149 |
|
150 // ============================ CVSFbsBitmapYUV420Converter =============================== |
|
151 |
|
152 // ----------------------------------------------------------------------------- |
|
153 // ?classname::?member_function |
|
154 // ?implementation_description |
|
155 // (other items were commented in a header). |
|
156 // ----------------------------------------------------------------------------- |
|
157 // |
|
158 CVSFbsBitmapYUV420Converter* CVSFbsBitmapYUV420Converter::NewL( const CFbsBitmap& aBitmap ) |
|
159 { |
|
160 CVSFbsBitmapYUV420Converter* self = new (ELeave) CVSFbsBitmapYUV420Converter(); |
|
161 CleanupStack::PushL( self ); |
|
162 self->ConstructL( aBitmap ); |
|
163 CleanupStack::Pop(); // self |
|
164 return self; |
|
165 } |
|
166 |
|
167 // ----------------------------------------------------------------------------- |
|
168 // ?classname::?member_function |
|
169 // ?implementation_description |
|
170 // (other items were commented in a header). |
|
171 // ----------------------------------------------------------------------------- |
|
172 // |
|
173 CVSFbsBitmapYUV420Converter::~CVSFbsBitmapYUV420Converter() |
|
174 { |
|
175 delete iSource; |
|
176 delete iYUVData; |
|
177 } |
|
178 |
|
179 // ----------------------------------------------------------------------------- |
|
180 // ?classname::?member_function |
|
181 // ?implementation_description |
|
182 // (other items were commented in a header). |
|
183 // ----------------------------------------------------------------------------- |
|
184 // |
|
185 void CVSFbsBitmapYUV420Converter::SetSourceL( const CFbsBitmap& aBitmap ) |
|
186 { |
|
187 ReConstructL( aBitmap ); |
|
188 } |
|
189 |
|
190 // ----------------------------------------------------------------------------- |
|
191 // ?classname::?member_function |
|
192 // ?implementation_description |
|
193 // (other items were commented in a header). |
|
194 // ----------------------------------------------------------------------------- |
|
195 // |
|
196 void CVSFbsBitmapYUV420Converter::ProcessL() |
|
197 { |
|
198 switch( iSource->DisplayMode() ) |
|
199 { |
|
200 case EColor4K: |
|
201 DoProcess( VSReadColor4K ); |
|
202 break; |
|
203 |
|
204 case EColor64K: |
|
205 DoProcess( VSReadColor64K ); |
|
206 break; |
|
207 |
|
208 case EColor16M: |
|
209 DoProcess( VSReadColor16M ); |
|
210 break; |
|
211 |
|
212 default: |
|
213 User::Leave( KErrNotSupported ); |
|
214 break; |
|
215 }; |
|
216 } |
|
217 |
|
218 // ----------------------------------------------------------------------------- |
|
219 // ?classname::?member_function |
|
220 // ?implementation_description |
|
221 // (other items were commented in a header). |
|
222 // ----------------------------------------------------------------------------- |
|
223 // |
|
224 TPtrC8 CVSFbsBitmapYUV420Converter::YUVData() const |
|
225 { |
|
226 return *iYUVData; |
|
227 } |
|
228 |
|
229 // ----------------------------------------------------------------------------- |
|
230 // ?classname::?member_function |
|
231 // ?implementation_description |
|
232 // (other items were commented in a header). |
|
233 // ----------------------------------------------------------------------------- |
|
234 // |
|
235 void CVSFbsBitmapYUV420Converter::ConstructL( const CFbsBitmap& aBitmap ) |
|
236 { |
|
237 iSource = new (ELeave) CFbsBitmap(); |
|
238 ReConstructL( aBitmap ); |
|
239 } |
|
240 |
|
241 // ----------------------------------------------------------------------------- |
|
242 // ?classname::?member_function |
|
243 // ?implementation_description |
|
244 // (other items were commented in a header). |
|
245 // ----------------------------------------------------------------------------- |
|
246 // |
|
247 void CVSFbsBitmapYUV420Converter::ReConstructL( const CFbsBitmap& aBitmap ) |
|
248 { |
|
249 User::LeaveIfError( iSource->Duplicate( aBitmap.Handle() ) ); |
|
250 |
|
251 // make sure that destination bitmap's displaymode is supported |
|
252 if( ( iSource->DisplayMode() != EColor4K ) && ( iSource->DisplayMode() != EColor64K ) && ( iSource->DisplayMode() != EColor16M ) ) |
|
253 { |
|
254 User::Leave( KErrNotSupported ); |
|
255 } |
|
256 |
|
257 if( !iYUVData || !( iSize == iSource->SizeInPixels() ) ) |
|
258 { |
|
259 iSize = iSource->SizeInPixels(); |
|
260 delete iYUVData; iYUVData = 0; |
|
261 TInt ySize = iSize.iWidth * iSize.iHeight; |
|
262 iYUVData = HBufC8::NewMaxL( ySize + ( ySize >> 1 ) ); |
|
263 iY.Set( iYUVData->Des().Mid( 0, ySize ) ); |
|
264 iU.Set( iYUVData->Des().Mid( ySize, ySize >> 2 ) ); |
|
265 iV.Set( iYUVData->Des().Mid( ySize + ( ySize >> 2 ), ySize >> 2 ) ); |
|
266 } |
|
267 } |
|
268 |
|
269 // ----------------------------------------------------------------------------- |
|
270 // ?classname::?member_function |
|
271 // ?implementation_description |
|
272 // (other items were commented in a header). |
|
273 // ----------------------------------------------------------------------------- |
|
274 // |
|
275 void CVSFbsBitmapYUV420Converter::DoProcess( TVSColorReadFunc aReadFunction ) |
|
276 { |
|
277 TUint8* pY = const_cast<TUint8*>( iY.Ptr() ); |
|
278 TUint8* pU = const_cast<TUint8*>( iU.Ptr() ); |
|
279 TUint8* pV = const_cast<TUint8*>( iV.Ptr() ); |
|
280 TVSYCrCb yuv1, yuv2; |
|
281 |
|
282 iSource->LockHeap(); |
|
283 TAny* s = iSource->DataAddress(); |
|
284 for( TInt h = 0; h < iSize.iHeight; h++ ) |
|
285 { |
|
286 for( TInt w = 0; w < iSize.iWidth>>1; w++ ) // Note! width must be even divisible by 2 |
|
287 { |
|
288 *pY++ = RGBtoYCbCr( &yuv1, aReadFunction( s ) ); |
|
289 *pY++ = RGBtoYCbCr( &yuv2, aReadFunction( s ) ); |
|
290 if( h&1 ) |
|
291 { |
|
292 *pU++ = static_cast<TUint8>( AVG( yuv1.iCb, yuv2.iCb ) ); |
|
293 *pV++ = static_cast<TUint8>( AVG( yuv1.iCr, yuv2.iCr ) ); |
|
294 } |
|
295 else |
|
296 { |
|
297 *pU++ = static_cast<TUint8>( AVG( *pU, AVG( yuv1.iCb, yuv2.iCb ) ) ); |
|
298 *pV++ = static_cast<TUint8>( AVG( *pV, AVG( yuv1.iCr, yuv2.iCr ) ) ); |
|
299 } |
|
300 } |
|
301 // if even row -> decrease pU and pV, we will calculate average for those on odd rows |
|
302 if( !(h&1) ) |
|
303 { |
|
304 pU -= ( iSize.iWidth >> 1 ); |
|
305 pV -= ( iSize.iWidth >> 1 ); |
|
306 } |
|
307 } |
|
308 iSource->UnlockHeap(); |
|
309 } |
|
310 |
|
311 // End of File |