|
1 /* |
|
2 * Copyright (c) 2004 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: Image Transforms subsystem. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 #include <e32svr.h> |
|
22 #include <fbs.h> |
|
23 |
|
24 #include "CVtImageScalerImplNearest.h" |
|
25 #include "cvtimage.h" |
|
26 |
|
27 // MACROS |
|
28 |
|
29 #ifdef _DEBUG |
|
30 # define __IF_DEBUG(t) {RDebug::t;} |
|
31 #else |
|
32 # define __IF_DEBUG(t) |
|
33 #endif |
|
34 |
|
35 // LOCAL CONSTANTS AND MACROS |
|
36 |
|
37 const TUint32 KDecimalBits = 16; // 16.16 pseudo real format |
|
38 |
|
39 // ============================ MEMBER FUNCTIONS =============================== |
|
40 |
|
41 // ======================= CVtImageScalerImplNearest ======================= |
|
42 |
|
43 // ----------------------------------------------------------------------------- |
|
44 // CVtImageScalerImplNearest::Scale( TBool& aContinue ) |
|
45 // ----------------------------------------------------------------------------- |
|
46 TInt CVtImageScalerImplNearest::Scale( TBool& aContinue ) |
|
47 { |
|
48 TInt result( KErrNone ); |
|
49 |
|
50 aContinue = EFalse; |
|
51 |
|
52 // this implementation does not support different display modes for source |
|
53 // and target |
|
54 if( iSource->DisplayMode() != iTarget->DisplayMode() ) |
|
55 { |
|
56 return KErrNotSupported; |
|
57 } |
|
58 |
|
59 // if sizes are same, just copy the data |
|
60 if( iSource->Size() == iTarget->Size() ) |
|
61 { |
|
62 Mem::Copy( |
|
63 iTarget->DataAddress(), |
|
64 iSource->DataAddress(), |
|
65 iTarget->BytesPerRow() * iTarget->Size().iHeight ); |
|
66 } |
|
67 else if( ( iSource->Size().iHeight * 2 == iTarget->Size().iHeight ) && |
|
68 ( iSource->Size().iWidth * 2 == iTarget->Size().iWidth ) ) |
|
69 { |
|
70 switch( iSource->DisplayMode() ) |
|
71 { |
|
72 case CVtImage::EVtColor4K: |
|
73 case CVtImage::EVtColor64K: |
|
74 Scale2x4K64K(); |
|
75 break; |
|
76 |
|
77 case CVtImage::EVtColor16M: |
|
78 Scale2x16M(); |
|
79 break; |
|
80 |
|
81 case CVtImage::EVtColor16MU: |
|
82 case CVtImage::EVtColor16MA: |
|
83 Scale2x16MU16MA(); |
|
84 break; |
|
85 |
|
86 default: |
|
87 if ( iSource->Type() == CVtImage::EVtImageBitmap && |
|
88 iTarget->Type() == CVtImage::EVtImageBitmap ) |
|
89 { |
|
90 TRAPD( error, |
|
91 ScaleWithBitmapScalerL( |
|
92 CBitmapScaler::EMinimumQuality ) ); |
|
93 result = error; |
|
94 } |
|
95 else |
|
96 { |
|
97 result = KErrNotSupported; |
|
98 } |
|
99 } |
|
100 } |
|
101 else |
|
102 { |
|
103 Initialize(); |
|
104 |
|
105 switch( iSource->DisplayMode() ) |
|
106 { |
|
107 case CVtImage::EVtColor4K: |
|
108 Scale4K( |
|
109 reinterpret_cast< const TUint16* >( |
|
110 iSource->DataAddress() ), |
|
111 iSource->BytesPerRow(), |
|
112 reinterpret_cast< TUint16* >( iTarget->DataAddress() ), |
|
113 iTarget->Size().iWidth, |
|
114 iTarget->Size().iHeight, |
|
115 iU, |
|
116 iV ); |
|
117 break; |
|
118 |
|
119 case CVtImage::EVtColor64K: |
|
120 Scale64K( |
|
121 reinterpret_cast< const TUint16* >( |
|
122 iSource->DataAddress() ), |
|
123 iSource->BytesPerRow(), |
|
124 reinterpret_cast< TUint16* >( iTarget->DataAddress() ), |
|
125 iTarget->Size().iWidth, |
|
126 iTarget->Size().iHeight, |
|
127 iU, |
|
128 iV ); |
|
129 break; |
|
130 |
|
131 case CVtImage::EVtColor16M: |
|
132 Scale16M( |
|
133 reinterpret_cast< const TUint8* >( |
|
134 iSource->DataAddress() ), |
|
135 iSource->BytesPerRow(), |
|
136 reinterpret_cast< TUint8* >( iTarget->DataAddress() ), |
|
137 iTarget->Size().iWidth, |
|
138 iTarget->Size().iHeight, |
|
139 iTarget->BytesPerRow(), |
|
140 iU, |
|
141 iV ); |
|
142 break; |
|
143 |
|
144 case CVtImage::EVtColor16MU: |
|
145 case CVtImage::EVtColor16MA: |
|
146 Scale16MU16MA( |
|
147 iSource->DataAddress(), |
|
148 iSource->BytesPerRow(), |
|
149 iTarget->DataAddress(), |
|
150 iTarget->Size().iWidth, |
|
151 iTarget->Size().iHeight, |
|
152 iU, |
|
153 iV ); |
|
154 break; |
|
155 |
|
156 default: |
|
157 if ( iSource->Type() == CVtImage::EVtImageBitmap && |
|
158 iTarget->Type() == CVtImage::EVtImageBitmap ) |
|
159 { |
|
160 TRAPD( error, |
|
161 ScaleWithBitmapScalerL( |
|
162 CBitmapScaler::EMinimumQuality ) ); |
|
163 result = error; |
|
164 } |
|
165 else |
|
166 { |
|
167 result = KErrNotSupported; |
|
168 } |
|
169 } |
|
170 } |
|
171 |
|
172 return result; |
|
173 } |
|
174 |
|
175 // ----------------------------------------------------------------------------- |
|
176 // CVtImageScalerImplNearest::ValidateSourceTargetL( |
|
177 // const CVtImage& aSource, CVtImage& aTarget ) |
|
178 // ----------------------------------------------------------------------------- |
|
179 void CVtImageScalerImplNearest::ValidateSourceTargetL( |
|
180 const CVtImage& aSource, |
|
181 CVtImage& aTarget ) |
|
182 { |
|
183 if( aSource.DisplayMode() != aTarget.DisplayMode() ) |
|
184 { |
|
185 User::Leave( KErrNotSupported ); |
|
186 } |
|
187 |
|
188 switch( aSource.DisplayMode() ) |
|
189 { |
|
190 case CVtImage::EVtColor4K: |
|
191 case CVtImage::EVtColor64K: |
|
192 case CVtImage::EVtColor16M: |
|
193 case CVtImage::EVtColor16MU: |
|
194 case CVtImage::EVtColor16MA: |
|
195 break; |
|
196 |
|
197 default: |
|
198 // Scaling for bitmaps is supported for other display modes |
|
199 if ( !( aSource.Type() == CVtImage::EVtImageBitmap && |
|
200 aTarget.Type() == CVtImage::EVtImageBitmap ) ) |
|
201 { |
|
202 User::Leave( KErrNotSupported ); |
|
203 } |
|
204 } |
|
205 } |
|
206 |
|
207 // ----------------------------------------------------------------------------- |
|
208 // CVtImageScalerImplNearest::Initialize() |
|
209 // ----------------------------------------------------------------------------- |
|
210 void CVtImageScalerImplNearest::Initialize() |
|
211 { |
|
212 iU = ( 1 << KDecimalBits ) * iSource->Size().iWidth / |
|
213 iTarget->Size().iWidth + 1; |
|
214 iV = ( 1 << KDecimalBits ) * iSource->Size().iHeight / |
|
215 iTarget->Size().iHeight + 1; |
|
216 } |
|
217 |
|
218 // ----------------------------------------------------------------------------- |
|
219 // CVtImageScalerImplNearest::Scale4K( |
|
220 // const TUint16* aSrcPtr, TUint32 aSrcWidth, TUint16* aTrgPtr, |
|
221 // TUint32 aTrgWidth, TUint32 aTrgHeight, TUint32 aDx, TUint32 aDy ) |
|
222 // ----------------------------------------------------------------------------- |
|
223 void CVtImageScalerImplNearest::Scale4K( |
|
224 const TUint16* aSrcPtr, |
|
225 TUint32 aSrcWidth, |
|
226 TUint16* aTrgPtr, |
|
227 TUint32 aTrgWidth, |
|
228 TUint32 aTrgHeight, |
|
229 TUint32 aDx, |
|
230 TUint32 aDy ) |
|
231 { |
|
232 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale4K() >>" ), RThread().Id().operator TUint() ) ); |
|
233 // scaling 4K and 64K is equal procedure |
|
234 Scale64K( aSrcPtr, aSrcWidth, aTrgPtr, aTrgWidth, aTrgHeight, aDx, aDy ); |
|
235 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale4K() <<" ), RThread().Id().operator TUint() ) ); |
|
236 } |
|
237 |
|
238 // ----------------------------------------------------------------------------- |
|
239 // CVtImageScalerImplNearest::Scale64K( |
|
240 // const TUint16* aSrcPtr, TUint32 aSrcPitch, TUint16* aTrgPtr, |
|
241 // TUint32 aTrgWidth, TUint32 aTrgHeight, TUint32 aDx, TUint32 aDy ) |
|
242 // ----------------------------------------------------------------------------- |
|
243 void CVtImageScalerImplNearest::Scale64K( |
|
244 const TUint16* aSrcPtr, |
|
245 TUint32 aSrcPitch, |
|
246 TUint16* aTrgPtr, |
|
247 TUint32 aTrgWidth, |
|
248 TUint32 aTrgHeight, |
|
249 TUint32 aDx, |
|
250 TUint32 aDy ) |
|
251 { |
|
252 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale64K() >>" ), RThread().Id().operator TUint() ) ); |
|
253 |
|
254 TUint32 sy( 0 ); |
|
255 |
|
256 for( TUint32 y = 0; y < aTrgHeight; y++ ) |
|
257 { |
|
258 const TUint16* srow = |
|
259 aSrcPtr + ( sy >> KDecimalBits ) * ( aSrcPitch >> 1 ); |
|
260 |
|
261 TUint32 sx( 0 ); |
|
262 |
|
263 TUint32 x( 0 ); |
|
264 |
|
265 // loop unrolled with 8 |
|
266 for( ; x < ( aTrgWidth >> 3 ); x++ ) |
|
267 { |
|
268 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
269 sx += aDx; |
|
270 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
271 sx += aDx; |
|
272 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
273 sx += aDx; |
|
274 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
275 sx += aDx; |
|
276 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
277 sx += aDx; |
|
278 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
279 sx += aDx; |
|
280 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
281 sx += aDx; |
|
282 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
283 sx += aDx; |
|
284 } |
|
285 |
|
286 // handle remaining columns |
|
287 for( x = 0; x < ( aTrgWidth & 7 ); x++ ) |
|
288 { |
|
289 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
290 sx += aDx; |
|
291 } |
|
292 |
|
293 // if target width is not even aligning is needed |
|
294 if( aTrgWidth & 1 ) |
|
295 { |
|
296 aTrgPtr++; |
|
297 } |
|
298 |
|
299 sy += aDy; |
|
300 } |
|
301 |
|
302 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale64K() <<" ), RThread().Id().operator TUint() ) ); |
|
303 } |
|
304 |
|
305 // ----------------------------------------------------------------------------- |
|
306 // CVtImageScalerImplNearest::Scale16M( |
|
307 // const TUint8* aSrcPtr, TUint32 aSrcPitch, TUint8* aTrgPtr, |
|
308 // TUint32 aTrgWidth, TUint32 aTrgHeight, TUint32 aTrgPitch, TUint32 aDx, TUint32 aDy ) |
|
309 // ----------------------------------------------------------------------------- |
|
310 void CVtImageScalerImplNearest::Scale16M( |
|
311 const TUint8* aSrcPtr, |
|
312 TUint32 aSrcPitch, |
|
313 TUint8* aTrgPtr, |
|
314 TUint32 aTrgWidth, |
|
315 TUint32 aTrgHeight, |
|
316 TUint32 aTrgPitch, |
|
317 TUint32 aDx, |
|
318 TUint32 aDy ) |
|
319 { |
|
320 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16M() >>" ), RThread().Id().operator TUint() ) ); |
|
321 |
|
322 TUint32 sy( 0 ); |
|
323 |
|
324 for( TUint32 y = 0; y < aTrgHeight; y++ ) |
|
325 { |
|
326 const TUint8* s = aSrcPtr + ( sy >> KDecimalBits ) * aSrcPitch; |
|
327 |
|
328 TUint8* d = aTrgPtr; |
|
329 |
|
330 TUint32 sx( 0 ); |
|
331 |
|
332 TUint32 x( 0 ); |
|
333 |
|
334 for( ; x < aTrgWidth; x++ ) |
|
335 { |
|
336 const TUint8* tempSrc = s + ( sx >> KDecimalBits ) * 3; |
|
337 *d++ = *tempSrc++; |
|
338 *d++ = *tempSrc++; |
|
339 *d++ = *tempSrc++; |
|
340 sx += aDx; |
|
341 } |
|
342 |
|
343 aTrgPtr += aTrgPitch; |
|
344 |
|
345 sy += aDy; |
|
346 } |
|
347 |
|
348 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16M() <<" ), RThread().Id().operator TUint() ) ); |
|
349 } |
|
350 |
|
351 // ----------------------------------------------------------------------------- |
|
352 // CVtImageScalerImplNearest::Scale16MU16MA( const TUint32* aSrcPtr, |
|
353 // TUint32 aSrcPitch, TUint32* aTrgPtr, TUint32 aTrgWidth, TUint32 aTrgHeight, |
|
354 // TUint32 aDx, TUint32 aDy ) |
|
355 // ----------------------------------------------------------------------------- |
|
356 void CVtImageScalerImplNearest::Scale16MU16MA( |
|
357 const TUint32* aSrcPtr, |
|
358 TUint32 aSrcPitch, |
|
359 TUint32* aTrgPtr, |
|
360 TUint32 aTrgWidth, |
|
361 TUint32 aTrgHeight, |
|
362 TUint32 aDx, |
|
363 TUint32 aDy ) |
|
364 { |
|
365 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16MU16MA() >>" ), RThread().Id().operator TUint() ) ); |
|
366 |
|
367 TUint32 sy( 0 ); |
|
368 |
|
369 for( TUint32 y = 0; y < aTrgHeight; y++ ) |
|
370 { |
|
371 const TUint32* srow = |
|
372 aSrcPtr + ( sy >> KDecimalBits ) * ( aSrcPitch >> 2 ); |
|
373 |
|
374 TUint32 sx( 0 ); |
|
375 |
|
376 TUint32 x( 0 ); |
|
377 |
|
378 // loop unrolled with 8 |
|
379 for( ; x < ( aTrgWidth >> 3 ); x++ ) |
|
380 { |
|
381 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
382 sx += aDx; |
|
383 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
384 sx += aDx; |
|
385 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
386 sx += aDx; |
|
387 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
388 sx += aDx; |
|
389 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
390 sx += aDx; |
|
391 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
392 sx += aDx; |
|
393 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
394 sx += aDx; |
|
395 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
396 sx += aDx; |
|
397 } |
|
398 |
|
399 // handle remaining columns |
|
400 for( x = 0; x < ( aTrgWidth & 7 ); x++ ) |
|
401 { |
|
402 *aTrgPtr++ = srow[ sx >> KDecimalBits ]; |
|
403 sx += aDx; |
|
404 } |
|
405 |
|
406 sy += aDy; |
|
407 } |
|
408 |
|
409 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale16MU16MA() <<" ), RThread().Id().operator TUint() ) ); |
|
410 } |
|
411 |
|
412 // ----------------------------------------------------------------------------- |
|
413 // CVtImageScalerImplNearest::Scale2x4K64K() |
|
414 // ----------------------------------------------------------------------------- |
|
415 void CVtImageScalerImplNearest::Scale2x4K64K() |
|
416 { |
|
417 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x4K64K() >>" ), RThread().Id().operator TUint() ) ); |
|
418 |
|
419 TInt sheight = iSource->Size().iHeight; |
|
420 TInt swidth = iSource->Size().iWidth; |
|
421 TInt spitch = iSource->BytesPerRow(); |
|
422 TInt dpitch = iTarget->BytesPerRow(); |
|
423 |
|
424 TUint16* s = reinterpret_cast< TUint16* >( iSource->DataAddress() ); |
|
425 TUint32* d = iTarget->DataAddress(); |
|
426 |
|
427 for( TInt y = 0; y < sheight; y++ ) |
|
428 { |
|
429 TUint16* s2 = s; |
|
430 TUint32* d1 = d; |
|
431 for( TInt x = 0; x < swidth; x++ ) |
|
432 { |
|
433 TUint32 p = *s2++; |
|
434 p |= ( p << 16 ); |
|
435 *d1++ = p; |
|
436 } |
|
437 d = reinterpret_cast< TUint32* >( |
|
438 Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch ) ); |
|
439 s = reinterpret_cast< TUint16* >( |
|
440 reinterpret_cast< TUint8* >( s ) + spitch ); |
|
441 } |
|
442 |
|
443 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x4K64K() <<" ), RThread().Id().operator TUint() ) ); |
|
444 } |
|
445 |
|
446 // ----------------------------------------------------------------------------- |
|
447 // CVtImageScalerImplNearest::Scale2x16M() |
|
448 // ----------------------------------------------------------------------------- |
|
449 void CVtImageScalerImplNearest::Scale2x16M() |
|
450 { |
|
451 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16M() >>" ), RThread().Id().operator TUint() ) ); |
|
452 |
|
453 TInt sheight = iSource->Size().iHeight; |
|
454 TInt swidth = iSource->Size().iWidth; |
|
455 TInt spitch = iSource->BytesPerRow(); |
|
456 TInt dpitch = iTarget->BytesPerRow(); |
|
457 |
|
458 TUint8* s = reinterpret_cast< TUint8* >( iSource->DataAddress() ); |
|
459 TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() ); |
|
460 |
|
461 for( TInt y = 0; y < sheight; y++ ) |
|
462 { |
|
463 TUint8* s2 = s; |
|
464 TUint8* d1 = d; |
|
465 for( TInt x = 0; x < swidth; x++ ) |
|
466 { |
|
467 TUint8 g = *s2++; |
|
468 TUint8 b = *s2++; |
|
469 TUint8 r = *s2++; |
|
470 |
|
471 *d1++ = g; |
|
472 *d1++ = b; |
|
473 *d1++ = r; |
|
474 |
|
475 *d1++ = g; |
|
476 *d1++ = b; |
|
477 *d1++ = r; |
|
478 } |
|
479 d = Mem::Copy( d + dpitch, d, dpitch ); |
|
480 s += spitch; |
|
481 } |
|
482 |
|
483 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16M() <<" ), RThread().Id().operator TUint() ) ); |
|
484 } |
|
485 |
|
486 // ----------------------------------------------------------------------------- |
|
487 // CVtImageScalerImplNearest::Scale2x16MU16MA() |
|
488 // ----------------------------------------------------------------------------- |
|
489 void CVtImageScalerImplNearest::Scale2x16MU16MA() |
|
490 { |
|
491 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16MU16MA() >>" ), RThread().Id().operator TUint() ) ); |
|
492 |
|
493 TInt sheight = iSource->Size().iHeight; |
|
494 TInt swidth = iSource->Size().iWidth; |
|
495 TInt spitch = iSource->BytesPerRow(); |
|
496 TInt dpitch = iTarget->BytesPerRow(); |
|
497 |
|
498 TUint32* s = iSource->DataAddress(); |
|
499 TUint32* d = iTarget->DataAddress(); |
|
500 |
|
501 for( TInt y = 0; y < sheight; y++ ) |
|
502 { |
|
503 TUint32* s2 = s; |
|
504 TUint32* d1 = d; |
|
505 for( TInt x = 0; x < swidth; x++ ) |
|
506 { |
|
507 TUint32 p = *s2++; |
|
508 *d1++ = p; |
|
509 *d1++ = p; |
|
510 } |
|
511 d = reinterpret_cast< TUint32* >( |
|
512 Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch ) ); |
|
513 s = reinterpret_cast< TUint32* >( |
|
514 reinterpret_cast< TUint8* >( s ) + spitch ); |
|
515 } |
|
516 |
|
517 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplNearest::Scale2x16MU16MA() <<" ), RThread().Id().operator TUint() ) ); |
|
518 } |
|
519 |
|
520 // End of File |
|
521 |
|
522 |