|
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 "CVtImageScalerImplBilinear.h" |
|
25 #include "cvtimage.h" |
|
26 #include "CVtImageScalerMacros.h" |
|
27 |
|
28 // MACROS |
|
29 |
|
30 #ifdef _DEBUG |
|
31 # define __IF_DEBUG(t) {RDebug::t;} |
|
32 #else |
|
33 # define __IF_DEBUG(t) |
|
34 #endif |
|
35 |
|
36 // LOCAL CONSTANTS AND MACROS |
|
37 |
|
38 const TUint32 KDecimalBits = 14; // 18.14 pseudo real format, |
|
39 // this must be lower than 15! |
|
40 |
|
41 // ============================ MEMBER FUNCTIONS =============================== |
|
42 |
|
43 // ======================= CVtImageScalerImplBilinear ========================== |
|
44 |
|
45 // ----------------------------------------------------------------------------- |
|
46 // CVtImageScalerImplBilinear::Scale( TBool& aContinue ) |
|
47 // ----------------------------------------------------------------------------- |
|
48 TInt CVtImageScalerImplBilinear::Scale( TBool& aContinue ) |
|
49 { |
|
50 TInt result( KErrNone ); |
|
51 |
|
52 aContinue = EFalse; |
|
53 |
|
54 // this implementation does not support different display modes for source |
|
55 // and target |
|
56 if( iSource->DisplayMode() != iTarget->DisplayMode() ) |
|
57 { |
|
58 return KErrNotSupported; |
|
59 } |
|
60 |
|
61 // if sizes are same, just copy the data |
|
62 if( iSource->Size() == iTarget->Size() ) |
|
63 { |
|
64 Mem::Copy( |
|
65 iTarget->DataAddress(), |
|
66 iSource->DataAddress(), |
|
67 iTarget->BytesPerRow() * iTarget->Size().iHeight ); |
|
68 } |
|
69 else if ( ( iSource->Size().iHeight * 2 == iTarget->Size().iHeight ) |
|
70 && ( iSource->Size().iWidth * 2 == iTarget->Size().iWidth ) ) |
|
71 { |
|
72 switch( iSource->DisplayMode() ) |
|
73 { |
|
74 case CVtImage::EVtColor4K: |
|
75 Scale2x4K64K( 0xeee ); // 0000ggggbbbbrrrr -> |
|
76 break; // mask = %0000111011101110 = 0xeee |
|
77 |
|
78 case CVtImage::EVtColor64K: |
|
79 Scale2x4K64K( 0xf7de ); // bbbbbggggggrrrrr -> |
|
80 break; // mask = %1111011111011110 = 0xf7de |
|
81 |
|
82 case CVtImage::EVtColor16M: |
|
83 Scale2x16M(); |
|
84 break; |
|
85 |
|
86 case CVtImage::EVtColor16MU: |
|
87 case CVtImage::EVtColor16MA: |
|
88 Scale2x16MU16MA(); |
|
89 break; |
|
90 |
|
91 default: |
|
92 if ( iSource->Type() == CVtImage::EVtImageBitmap && |
|
93 iTarget->Type() == CVtImage::EVtImageBitmap ) |
|
94 { |
|
95 TRAPD( error, |
|
96 ScaleWithBitmapScalerL( |
|
97 CBitmapScaler::EMaximumQuality ) ); |
|
98 result = error; |
|
99 } |
|
100 else |
|
101 { |
|
102 result = KErrNotSupported; |
|
103 } |
|
104 } |
|
105 } |
|
106 else |
|
107 { |
|
108 Initialize(); |
|
109 |
|
110 switch( iSource->DisplayMode() ) |
|
111 { |
|
112 case CVtImage::EVtColor4K: |
|
113 Scale4K(); |
|
114 break; |
|
115 |
|
116 case CVtImage::EVtColor64K: |
|
117 Scale64K(); |
|
118 break; |
|
119 |
|
120 case CVtImage::EVtColor16M: |
|
121 Scale16M(); |
|
122 break; |
|
123 |
|
124 case CVtImage::EVtColor16MU: |
|
125 Scale16MU(); |
|
126 break; |
|
127 |
|
128 case CVtImage::EVtColor16MA: |
|
129 Scale16MA(); |
|
130 break; |
|
131 |
|
132 default: |
|
133 if ( iSource->Type() == CVtImage::EVtImageBitmap && |
|
134 iTarget->Type() == CVtImage::EVtImageBitmap ) |
|
135 { |
|
136 TRAPD( error, |
|
137 ScaleWithBitmapScalerL( |
|
138 CBitmapScaler::EMaximumQuality ) ); |
|
139 result = error; |
|
140 } |
|
141 else |
|
142 { |
|
143 result = KErrNotSupported; |
|
144 } |
|
145 } |
|
146 } |
|
147 |
|
148 return result; |
|
149 } |
|
150 |
|
151 // ----------------------------------------------------------------------------- |
|
152 // CVtImageScalerImplBilinear::ValidateSourceTargetL( |
|
153 // const CVtImage& aSource, CVtImage& aTarget ) |
|
154 // ----------------------------------------------------------------------------- |
|
155 void CVtImageScalerImplBilinear::ValidateSourceTargetL( |
|
156 const CVtImage& aSource, |
|
157 CVtImage& aTarget ) |
|
158 { |
|
159 if( aSource.DisplayMode() != aTarget.DisplayMode() ) |
|
160 { |
|
161 User::Leave( KErrNotSupported ); |
|
162 } |
|
163 |
|
164 switch( aSource.DisplayMode() ) |
|
165 { |
|
166 case CVtImage::EVtColor4K: |
|
167 case CVtImage::EVtColor64K: |
|
168 case CVtImage::EVtColor16M: |
|
169 case CVtImage::EVtColor16MU: |
|
170 case CVtImage::EVtColor16MA: |
|
171 break; |
|
172 |
|
173 default: |
|
174 // Scaling for bitmaps is supported for other display modes |
|
175 if ( !( aSource.Type() == CVtImage::EVtImageBitmap && |
|
176 aTarget.Type() == CVtImage::EVtImageBitmap ) ) |
|
177 { |
|
178 User::Leave( KErrNotSupported ); |
|
179 } |
|
180 } |
|
181 } |
|
182 |
|
183 // ----------------------------------------------------------------------------- |
|
184 // CVtImageScalerImplBilinear::Initialize() |
|
185 // ----------------------------------------------------------------------------- |
|
186 void CVtImageScalerImplBilinear::Initialize() |
|
187 { |
|
188 iU = ( 1 << KDecimalBits ) * iSource->Size().iWidth / |
|
189 iTarget->Size().iWidth; |
|
190 iV = ( 1 << KDecimalBits ) * iSource->Size().iHeight / |
|
191 iTarget->Size().iHeight; |
|
192 } |
|
193 |
|
194 // ----------------------------------------------------------------------------- |
|
195 // CVtImageScalerImplBilinear::Scale4K() |
|
196 // ----------------------------------------------------------------------------- |
|
197 void CVtImageScalerImplBilinear::Scale4K() |
|
198 { |
|
199 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale4K() >>" ), RThread().Id().operator TUint() ) ); |
|
200 |
|
201 TInt width = iTarget->Size().iWidth; |
|
202 |
|
203 TInt height = iTarget->Size().iHeight; |
|
204 |
|
205 TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU ); |
|
206 |
|
207 TUint16* t = reinterpret_cast< TUint16* >( iTarget->DataAddress() ); |
|
208 |
|
209 TUint32 sourceY( 0 ); |
|
210 |
|
211 TUint32 b00( 0 ); |
|
212 TUint32 g00( 0 ); |
|
213 TUint32 r00( 0 ); |
|
214 TUint32 b01( 0 ); |
|
215 TUint32 g01( 0 ); |
|
216 TUint32 r01( 0 ); |
|
217 TUint32 b10( 0 ); |
|
218 TUint32 g10( 0 ); |
|
219 TUint32 r10( 0 ); |
|
220 TUint32 b11( 0 ); |
|
221 TUint32 g11( 0 ); |
|
222 TUint32 r11( 0 ); |
|
223 |
|
224 for( TInt y = 0; y < height; y++ ) |
|
225 { |
|
226 TUint16* s = reinterpret_cast< TUint16* >( |
|
227 iSource->LineAddress( sourceY >> KDecimalBits ) ); |
|
228 TUint16* snext = reinterpret_cast< TUint16* >( |
|
229 iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ) ); |
|
230 |
|
231 TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part |
|
232 TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part |
|
233 |
|
234 TUint32 sourceX( 0 ); |
|
235 TUint32 x0prev( TUint32( -1 ) ); |
|
236 |
|
237 TInt x; |
|
238 |
|
239 for( x = 0; x < mod_width; x++ ) |
|
240 { |
|
241 TUint32 x0 = sourceX >> KDecimalBits; |
|
242 |
|
243 // If the source is still same then we don't have to fetch |
|
244 // pixels from memory and unpack them again |
|
245 if( x0 != x0prev ) |
|
246 { |
|
247 TUint32 p0 = *( s + x0 ); |
|
248 |
|
249 b00 = UNPACK_4K_BLUE( p0 ); |
|
250 g00 = UNPACK_4K_GREEN( p0 ); |
|
251 r00 = UNPACK_4K_RED( p0 ); |
|
252 |
|
253 p0 = *( s + x0 + 1 ); |
|
254 |
|
255 b01 = UNPACK_4K_BLUE( p0 ); |
|
256 g01 = UNPACK_4K_GREEN( p0 ); |
|
257 r01 = UNPACK_4K_RED( p0 ); |
|
258 |
|
259 p0 = *( snext + x0 ); |
|
260 |
|
261 b10 = UNPACK_4K_BLUE( p0 ); |
|
262 g10 = UNPACK_4K_GREEN( p0 ); |
|
263 r10 = UNPACK_4K_RED( p0 ); |
|
264 |
|
265 p0 = *( snext + x0 + 1 ); |
|
266 |
|
267 b11 = UNPACK_4K_BLUE( p0 ); |
|
268 g11 = UNPACK_4K_GREEN( p0 ); |
|
269 r11 = UNPACK_4K_RED( p0 ); |
|
270 |
|
271 x0prev = x0; |
|
272 } |
|
273 |
|
274 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
275 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
276 |
|
277 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
278 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
279 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
280 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
281 |
|
282 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
283 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
284 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
285 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
286 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
287 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
288 |
|
289 *t = 0; |
|
290 |
|
291 *t++ = PACK_4K_BGR( |
|
292 bres >> KDecimalBits, |
|
293 gres >> KDecimalBits, |
|
294 rres >> KDecimalBits ); |
|
295 |
|
296 sourceX += iU; |
|
297 } |
|
298 |
|
299 // last columns |
|
300 for( ; x < width; x++ ) |
|
301 { |
|
302 TUint32 x0 = sourceX >> KDecimalBits; |
|
303 |
|
304 // If the source is still same then we don't have to fetch pixels |
|
305 // from memory and unpack them again |
|
306 if( x0 != x0prev ) |
|
307 { |
|
308 TUint32 p0 = *( s + x0 ); |
|
309 b01 = b00 = UNPACK_4K_BLUE( p0 ); |
|
310 g01 = g00 = UNPACK_4K_GREEN( p0 ); |
|
311 r01 = r00 = UNPACK_4K_RED( p0 ); |
|
312 |
|
313 p0 = *( snext + x0 ); |
|
314 b11 = b10 = UNPACK_4K_BLUE( p0 ); |
|
315 g11 = g10 = UNPACK_4K_GREEN( p0 ); |
|
316 r11 = r10 = UNPACK_4K_RED( p0 ); |
|
317 |
|
318 x0prev = x0; |
|
319 } |
|
320 |
|
321 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
322 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
323 |
|
324 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
325 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
326 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
327 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
328 |
|
329 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
330 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
331 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
332 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
333 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
334 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
335 |
|
336 *t++ = PACK_4K_BGR( |
|
337 bres >> KDecimalBits, |
|
338 gres >> KDecimalBits, |
|
339 rres >> KDecimalBits ); |
|
340 |
|
341 sourceX += iU; |
|
342 } |
|
343 |
|
344 // if width is not even -> then we need to skip one additional byte |
|
345 if( width & 1 ) |
|
346 { |
|
347 t++; |
|
348 } |
|
349 |
|
350 sourceY += iV; |
|
351 } |
|
352 |
|
353 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale4K() <<" ), RThread().Id().operator TUint() ) ); |
|
354 } |
|
355 |
|
356 // ----------------------------------------------------------------------------- |
|
357 // CVtImageScalerImplBilinear::Scale64K() |
|
358 // ----------------------------------------------------------------------------- |
|
359 void CVtImageScalerImplBilinear::Scale64K() |
|
360 { |
|
361 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale64K() >>" ), RThread().Id().operator TUint() ) ); |
|
362 |
|
363 TInt width = iTarget->Size().iWidth; |
|
364 |
|
365 TInt height = iTarget->Size().iHeight; |
|
366 |
|
367 TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU ); |
|
368 |
|
369 TUint16* t = reinterpret_cast< TUint16* >( iTarget->DataAddress() ); |
|
370 |
|
371 TUint32 sourceY( 0 ); |
|
372 |
|
373 TUint32 b00( 0 ); |
|
374 TUint32 g00( 0 ); |
|
375 TUint32 r00( 0 ); |
|
376 TUint32 b01( 0 ); |
|
377 TUint32 g01( 0 ); |
|
378 TUint32 r01( 0 ); |
|
379 TUint32 b10( 0 ); |
|
380 TUint32 g10( 0 ); |
|
381 TUint32 r10( 0 ); |
|
382 TUint32 b11( 0 ); |
|
383 TUint32 g11( 0 ); |
|
384 TUint32 r11( 0 ); |
|
385 |
|
386 for( TInt y = 0; y < height; y++ ) |
|
387 { |
|
388 TUint16* s = reinterpret_cast< TUint16* >( |
|
389 iSource->LineAddress( sourceY >> KDecimalBits ) ); |
|
390 TUint16* snext = reinterpret_cast< TUint16* >( |
|
391 iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ) ); |
|
392 |
|
393 TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part |
|
394 TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part |
|
395 |
|
396 TUint32 sourceX( 0 ); |
|
397 TUint32 x0prev( TUint32( -1 ) ); |
|
398 |
|
399 TInt x; |
|
400 |
|
401 for( x = 0; x < mod_width; x++ ) |
|
402 { |
|
403 TUint32 x0 = sourceX >> KDecimalBits; |
|
404 |
|
405 // If the source is still same then we don't have to fetch pixels |
|
406 // from memory and unpack them again |
|
407 if( x0 != x0prev ) |
|
408 { |
|
409 TUint32 p0 = *( s + x0 ); |
|
410 |
|
411 b00 = UNPACK_64K_BLUE( p0 ); |
|
412 g00 = UNPACK_64K_GREEN( p0 ); |
|
413 r00 = UNPACK_64K_RED( p0 ); |
|
414 |
|
415 p0 = *( s + x0 + 1 ); |
|
416 |
|
417 b01 = UNPACK_64K_BLUE( p0 ); |
|
418 g01 = UNPACK_64K_GREEN( p0 ); |
|
419 r01 = UNPACK_64K_RED( p0 ); |
|
420 |
|
421 p0 = *( snext + x0 ); |
|
422 |
|
423 b10 = UNPACK_64K_BLUE( p0 ); |
|
424 g10 = UNPACK_64K_GREEN( p0 ); |
|
425 r10 = UNPACK_64K_RED( p0 ); |
|
426 |
|
427 p0 = *( snext + x0 + 1 ); |
|
428 |
|
429 b11 = UNPACK_64K_BLUE( p0 ); |
|
430 g11 = UNPACK_64K_GREEN( p0 ); |
|
431 r11 = UNPACK_64K_RED( p0 ); |
|
432 |
|
433 x0prev = x0; |
|
434 } |
|
435 |
|
436 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
437 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
438 |
|
439 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
440 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
441 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
442 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
443 |
|
444 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
445 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
446 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
447 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
448 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
449 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
450 |
|
451 *t++ = PACK_64K_BGR( |
|
452 bres >> KDecimalBits, |
|
453 gres >> KDecimalBits, |
|
454 rres >> KDecimalBits ); |
|
455 |
|
456 sourceX += iU; |
|
457 } |
|
458 |
|
459 // last columns |
|
460 for( ; x < width; x++ ) |
|
461 { |
|
462 TUint32 x0 = sourceX >> KDecimalBits; |
|
463 |
|
464 // If the source is still same then we don't have to fetch pixels |
|
465 // from memory and unpack them again |
|
466 if( x0 != x0prev ) |
|
467 { |
|
468 TUint32 p0 = *( s + x0 ); |
|
469 b01 = b00 = UNPACK_64K_BLUE( p0 ); |
|
470 g01 = g00 = UNPACK_64K_GREEN( p0 ); |
|
471 r01 = r00 = UNPACK_64K_RED( p0 ); |
|
472 |
|
473 p0 = *( snext + x0 ); |
|
474 b11 = b10 = UNPACK_64K_BLUE( p0 ); |
|
475 g11 = g10 = UNPACK_64K_GREEN( p0 ); |
|
476 r11 = r10 = UNPACK_64K_RED( p0 ); |
|
477 |
|
478 x0prev = x0; |
|
479 } |
|
480 |
|
481 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
482 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
483 |
|
484 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
485 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
486 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
487 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
488 |
|
489 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
490 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
491 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
492 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
493 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
494 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
495 |
|
496 *t++ = PACK_64K_BGR( |
|
497 bres >> KDecimalBits, |
|
498 gres >> KDecimalBits, |
|
499 rres >> KDecimalBits ); |
|
500 |
|
501 sourceX += iU; |
|
502 } |
|
503 |
|
504 // if width is not even -> then we need to skip one additional byte |
|
505 if( width & 1 ) |
|
506 { |
|
507 t++; |
|
508 } |
|
509 |
|
510 sourceY += iV; |
|
511 } |
|
512 |
|
513 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale64K() <<" ), RThread().Id().operator TUint() ) ); |
|
514 } |
|
515 |
|
516 // ----------------------------------------------------------------------------- |
|
517 // CVtImageScalerImplBilinear::Scale16M() |
|
518 // ----------------------------------------------------------------------------- |
|
519 void CVtImageScalerImplBilinear::Scale16M() |
|
520 { |
|
521 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale16M() >>" ), RThread().Id().operator TUint() ) ); |
|
522 |
|
523 TInt width = iTarget->Size().iWidth; |
|
524 |
|
525 TInt height = iTarget->Size().iHeight; |
|
526 |
|
527 TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU ); |
|
528 |
|
529 TUint32 t_pitch = iTarget->BytesPerRow(); |
|
530 |
|
531 TUint8* t = reinterpret_cast< TUint8* >( iTarget->DataAddress() ); |
|
532 |
|
533 TUint32 sourceY( 0 ); |
|
534 |
|
535 TUint32 b00( 0 ); |
|
536 TUint32 g00( 0 ); |
|
537 TUint32 r00( 0 ); |
|
538 TUint32 b01( 0 ); |
|
539 TUint32 g01( 0 ); |
|
540 TUint32 r01( 0 ); |
|
541 TUint32 b10( 0 ); |
|
542 TUint32 g10( 0 ); |
|
543 TUint32 r10( 0 ); |
|
544 TUint32 b11( 0 ); |
|
545 TUint32 g11( 0 ); |
|
546 TUint32 r11( 0 ); |
|
547 |
|
548 for( TInt y = 0; y < height; y++ ) |
|
549 { |
|
550 TUint8* s = reinterpret_cast< TUint8* >( |
|
551 iSource->LineAddress( sourceY >> KDecimalBits ) ); |
|
552 TUint8* snext = reinterpret_cast< TUint8* >( |
|
553 iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ) ); |
|
554 |
|
555 TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part |
|
556 TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part |
|
557 |
|
558 TUint32 sourceX( 0 ); |
|
559 TUint32 x0prev( TUint32( -1 ) ); |
|
560 |
|
561 TInt x; |
|
562 |
|
563 TUint8* d = t; |
|
564 |
|
565 for( x = 0; x < mod_width; x++ ) |
|
566 { |
|
567 TUint32 x0 = ( sourceX >> KDecimalBits ) * 3; |
|
568 |
|
569 if( x0 != x0prev ) |
|
570 { |
|
571 TUint8* tempSrc = s + x0; |
|
572 |
|
573 b00 = *tempSrc++; |
|
574 g00 = *tempSrc++; |
|
575 r00 = *tempSrc++; |
|
576 |
|
577 b01 = *tempSrc++; |
|
578 g01 = *tempSrc++; |
|
579 r01 = *tempSrc++; |
|
580 |
|
581 tempSrc = snext + x0; |
|
582 |
|
583 b10 = *tempSrc++; |
|
584 g10 = *tempSrc++; |
|
585 r10 = *tempSrc++; |
|
586 |
|
587 b11 = *tempSrc++; |
|
588 g11 = *tempSrc++; |
|
589 r11 = *tempSrc++; |
|
590 |
|
591 x0prev = x0; |
|
592 } |
|
593 |
|
594 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
595 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
596 |
|
597 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
598 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
599 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
600 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
601 |
|
602 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
603 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
604 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
605 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
606 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
607 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
608 |
|
609 *d++ = static_cast< TUint8 >( bres >> KDecimalBits ); |
|
610 *d++ = static_cast< TUint8 >( gres >> KDecimalBits ); |
|
611 *d++ = static_cast< TUint8 >( rres >> KDecimalBits ); |
|
612 |
|
613 sourceX += iU; |
|
614 } |
|
615 |
|
616 // last columns |
|
617 for( ; x < width; x++ ) |
|
618 { |
|
619 TUint32 x0 = ( sourceX >> KDecimalBits ) * 3; |
|
620 |
|
621 if( x0 != x0prev ) |
|
622 { |
|
623 TUint8* tempSrc = s + x0; |
|
624 |
|
625 b01 = b00 = *tempSrc++; |
|
626 g01 = g00 = *tempSrc++; |
|
627 r01 = r00 = *tempSrc++; |
|
628 |
|
629 tempSrc = snext + x0; |
|
630 |
|
631 b11 = b10 = *tempSrc++; |
|
632 g11 = g10 = *tempSrc++; |
|
633 r11 = r10 = *tempSrc++; |
|
634 |
|
635 x0prev = x0; |
|
636 } |
|
637 |
|
638 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
639 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
640 |
|
641 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
642 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
643 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
644 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
645 |
|
646 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
647 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
648 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
649 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
650 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
651 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
652 |
|
653 *d++ = static_cast< TUint8 >( bres >> KDecimalBits ); |
|
654 *d++ = static_cast< TUint8 >( gres >> KDecimalBits ); |
|
655 *d++ = static_cast< TUint8 >( rres >> KDecimalBits ); |
|
656 |
|
657 sourceX += iU; |
|
658 } |
|
659 |
|
660 t += t_pitch; |
|
661 |
|
662 sourceY += iV; |
|
663 } |
|
664 |
|
665 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale16M() <<" ), RThread().Id().operator TUint() ) ); |
|
666 } |
|
667 |
|
668 // ----------------------------------------------------------------------------- |
|
669 // CVtImageScalerImplBilinear::Scale16MU() |
|
670 // ----------------------------------------------------------------------------- |
|
671 void CVtImageScalerImplBilinear::Scale16MU() |
|
672 { |
|
673 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale16MU() >>" ), RThread().Id().operator TUint() ) ); |
|
674 |
|
675 TInt width = iTarget->Size().iWidth; |
|
676 |
|
677 TInt height = iTarget->Size().iHeight; |
|
678 |
|
679 TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU ); |
|
680 |
|
681 TUint32* t = iTarget->DataAddress(); |
|
682 |
|
683 TUint32 sourceY( 0 ); |
|
684 |
|
685 TUint32 b00( 0 ); |
|
686 TUint32 g00( 0 ); |
|
687 TUint32 r00( 0 ); |
|
688 TUint32 b01( 0 ); |
|
689 TUint32 g01( 0 ); |
|
690 TUint32 r01( 0 ); |
|
691 TUint32 b10( 0 ); |
|
692 TUint32 g10( 0 ); |
|
693 TUint32 r10( 0 ); |
|
694 TUint32 b11( 0 ); |
|
695 TUint32 g11( 0 ); |
|
696 TUint32 r11( 0 ); |
|
697 |
|
698 for( TInt y = 0; y < height; y++ ) |
|
699 { |
|
700 TUint32* s = iSource->LineAddress( sourceY >> KDecimalBits ); |
|
701 TUint32* snext = iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ); |
|
702 |
|
703 TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part |
|
704 TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part |
|
705 |
|
706 TUint32 sourceX( 0 ); |
|
707 TUint32 x0prev( TUint32( -1 ) ); |
|
708 |
|
709 TInt x; |
|
710 |
|
711 for( x = 0; x < mod_width; x++ ) |
|
712 { |
|
713 TUint32 x0 = sourceX >> KDecimalBits; |
|
714 |
|
715 // If the source is still same then we don't have to fetch pixels |
|
716 // from memory and unpack them again |
|
717 if( x0 != x0prev ) |
|
718 { |
|
719 TUint32 p0 = *( s + x0 ); |
|
720 |
|
721 b00 = UNPACK_16MU_BLUE( p0 ); |
|
722 g00 = UNPACK_16MU_GREEN( p0 ); |
|
723 r00 = UNPACK_16MU_RED( p0 ); |
|
724 |
|
725 p0 = *( s + x0 + 1 ); |
|
726 |
|
727 b01 = UNPACK_16MU_BLUE( p0 ); |
|
728 g01 = UNPACK_16MU_GREEN( p0 ); |
|
729 r01 = UNPACK_16MU_RED( p0 ); |
|
730 |
|
731 p0 = *( snext + x0 ); |
|
732 |
|
733 b10 = UNPACK_16MU_BLUE( p0 ); |
|
734 g10 = UNPACK_16MU_GREEN( p0 ); |
|
735 r10 = UNPACK_16MU_RED( p0 ); |
|
736 |
|
737 p0 = *( snext + x0 + 1 ); |
|
738 |
|
739 b11 = UNPACK_16MU_BLUE( p0 ); |
|
740 g11 = UNPACK_16MU_GREEN( p0 ); |
|
741 r11 = UNPACK_16MU_RED( p0 ); |
|
742 |
|
743 x0prev = x0; |
|
744 } |
|
745 |
|
746 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
747 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
748 |
|
749 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
750 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
751 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
752 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
753 |
|
754 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
755 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
756 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
757 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
758 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
759 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
760 |
|
761 *t++ = PACK_16MU_BGR( |
|
762 bres >> KDecimalBits, |
|
763 gres >> KDecimalBits, |
|
764 rres >> KDecimalBits ); |
|
765 |
|
766 sourceX += iU; |
|
767 } |
|
768 |
|
769 // last columns |
|
770 for( ; x < width; x++ ) |
|
771 { |
|
772 TUint32 x0 = sourceX >> KDecimalBits; |
|
773 |
|
774 // If the source is still same then we don't have to fetch pixels |
|
775 // from memory and unpack them again |
|
776 if( x0 != x0prev ) |
|
777 { |
|
778 TUint32 p0 = *( s + x0 ); |
|
779 b01 = b00 = UNPACK_16MU_BLUE( p0 ); |
|
780 g01 = g00 = UNPACK_16MU_GREEN( p0 ); |
|
781 r01 = r00 = UNPACK_16MU_RED( p0 ); |
|
782 |
|
783 p0 = *( snext + x0 ); |
|
784 b11 = b10 = UNPACK_16MU_BLUE( p0 ); |
|
785 g11 = g10 = UNPACK_16MU_GREEN( p0 ); |
|
786 r11 = r10 = UNPACK_16MU_RED( p0 ); |
|
787 |
|
788 x0prev = x0; |
|
789 } |
|
790 |
|
791 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
792 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
793 |
|
794 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
795 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
796 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
797 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
798 |
|
799 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
800 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
801 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
802 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
803 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
804 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
805 |
|
806 *t++ = PACK_16MU_BGR( |
|
807 bres >> KDecimalBits, |
|
808 gres >> KDecimalBits, |
|
809 rres >> KDecimalBits ); |
|
810 |
|
811 sourceX += iU; |
|
812 } |
|
813 |
|
814 sourceY += iV; |
|
815 } |
|
816 |
|
817 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale16MU() <<" ), RThread().Id().operator TUint() ) ); |
|
818 } |
|
819 |
|
820 // ----------------------------------------------------------------------------- |
|
821 // CVtImageScalerImplBilinear::Scale16MA() |
|
822 // ----------------------------------------------------------------------------- |
|
823 void CVtImageScalerImplBilinear::Scale16MA() |
|
824 { |
|
825 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale16MA() >>" ), RThread().Id().operator TUint() ) ); |
|
826 |
|
827 TInt width = iTarget->Size().iWidth; |
|
828 |
|
829 TInt height = iTarget->Size().iHeight; |
|
830 |
|
831 TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU ); |
|
832 |
|
833 TUint32* t = iTarget->DataAddress(); |
|
834 |
|
835 TUint32 sourceY( 0 ); |
|
836 |
|
837 TUint32 a00( 0 ); |
|
838 TUint32 b00( 0 ); |
|
839 TUint32 g00( 0 ); |
|
840 TUint32 r00( 0 ); |
|
841 TUint32 a01( 0 ); |
|
842 TUint32 b01( 0 ); |
|
843 TUint32 g01( 0 ); |
|
844 TUint32 r01( 0 ); |
|
845 TUint32 a10( 0 ); |
|
846 TUint32 b10( 0 ); |
|
847 TUint32 g10( 0 ); |
|
848 TUint32 r10( 0 ); |
|
849 TUint32 a11( 0 ); |
|
850 TUint32 b11( 0 ); |
|
851 TUint32 g11( 0 ); |
|
852 TUint32 r11( 0 ); |
|
853 |
|
854 for( TInt y = 0; y < height; y++ ) |
|
855 { |
|
856 TUint32* s = iSource->LineAddress( sourceY >> KDecimalBits ); |
|
857 TUint32* snext = iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ); |
|
858 |
|
859 TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part |
|
860 TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part |
|
861 |
|
862 TUint32 sourceX( 0 ); |
|
863 TUint32 x0prev( TUint32( -1 ) ); |
|
864 |
|
865 TInt x; |
|
866 |
|
867 for( x = 0; x < mod_width; x++ ) |
|
868 { |
|
869 TUint32 x0 = sourceX >> KDecimalBits; |
|
870 |
|
871 // If the source is still same then we don't have to fetch pixels |
|
872 // from memory and unpack them again |
|
873 if( x0 != x0prev ) |
|
874 { |
|
875 TUint32 p0 = *( s + x0 ); |
|
876 |
|
877 a00 = UNPACK_16MA_ALPHA( p0 ); |
|
878 b00 = UNPACK_16MA_BLUE( p0 ); |
|
879 g00 = UNPACK_16MA_GREEN( p0 ); |
|
880 r00 = UNPACK_16MA_RED( p0 ); |
|
881 |
|
882 p0 = *( s + x0 + 1 ); |
|
883 |
|
884 a01 = UNPACK_16MA_ALPHA( p0 ); |
|
885 b01 = UNPACK_16MA_BLUE( p0 ); |
|
886 g01 = UNPACK_16MA_GREEN( p0 ); |
|
887 r01 = UNPACK_16MA_RED( p0 ); |
|
888 |
|
889 p0 = *( snext + x0 ); |
|
890 |
|
891 a10 = UNPACK_16MA_ALPHA( p0 ); |
|
892 b10 = UNPACK_16MA_BLUE( p0 ); |
|
893 g10 = UNPACK_16MA_GREEN( p0 ); |
|
894 r10 = UNPACK_16MA_RED( p0 ); |
|
895 |
|
896 p0 = *( snext + x0 + 1 ); |
|
897 |
|
898 a11 = UNPACK_16MA_ALPHA( p0 ); |
|
899 b11 = UNPACK_16MA_BLUE( p0 ); |
|
900 g11 = UNPACK_16MA_GREEN( p0 ); |
|
901 r11 = UNPACK_16MA_RED( p0 ); |
|
902 |
|
903 x0prev = x0; |
|
904 } |
|
905 |
|
906 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
907 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
908 |
|
909 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
910 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
911 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
912 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
913 |
|
914 TUint32 ares = w1 * a00 + w2 * a01 + w3 * a10 + w4 * a11; |
|
915 ares += ( 1 << ( KDecimalBits - 1 ) ); |
|
916 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
917 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
918 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
919 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
920 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
921 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
922 |
|
923 *t++ = PACK_16MA_ABGR( |
|
924 ares >> KDecimalBits, |
|
925 bres >> KDecimalBits, |
|
926 gres >> KDecimalBits, |
|
927 rres >> KDecimalBits ); |
|
928 |
|
929 sourceX += iU; |
|
930 } |
|
931 |
|
932 // last columns |
|
933 for( ; x < width; x++ ) |
|
934 { |
|
935 TUint32 x0 = sourceX >> KDecimalBits; |
|
936 |
|
937 // If the source is still same then we don't have to fetch pixels |
|
938 // from memory and unpack them again |
|
939 if( x0 != x0prev ) |
|
940 { |
|
941 TUint32 p0 = *( s + x0 ); |
|
942 a01 = a00 = UNPACK_16MA_ALPHA( p0 ); |
|
943 b01 = b00 = UNPACK_16MA_BLUE( p0 ); |
|
944 g01 = g00 = UNPACK_16MA_GREEN( p0 ); |
|
945 r01 = r00 = UNPACK_16MA_RED( p0 ); |
|
946 |
|
947 p0 = *( snext + x0 ); |
|
948 a11 = a10 = UNPACK_16MA_ALPHA( p0 ); |
|
949 b11 = b10 = UNPACK_16MA_BLUE( p0 ); |
|
950 g11 = g10 = UNPACK_16MA_GREEN( p0 ); |
|
951 r11 = r10 = UNPACK_16MA_RED( p0 ); |
|
952 |
|
953 x0prev = x0; |
|
954 } |
|
955 |
|
956 TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal |
|
957 TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part |
|
958 |
|
959 TUint32 w1 = ( du * dv ) >> KDecimalBits; |
|
960 TUint32 w2 = ( invdu * dv ) >> KDecimalBits; |
|
961 TUint32 w3 = ( du * invdv ) >> KDecimalBits; |
|
962 TUint32 w4 = ( invdu * invdv ) >> KDecimalBits; |
|
963 |
|
964 TUint32 ares = w1 * a00 + w2 * a01 + w3 * a10 + w4 * a11; |
|
965 ares += ( 1 << ( KDecimalBits - 1 ) ); |
|
966 TUint32 bres = w1 * b00 + w2 * b01 + w3 * b10 + w4 * b11; |
|
967 bres += ( 1 << ( KDecimalBits - 1 ) ); |
|
968 TUint32 gres = w1 * g00 + w2 * g01 + w3 * g10 + w4 * g11; |
|
969 gres += ( 1 << ( KDecimalBits - 1 ) ); |
|
970 TUint32 rres = w1 * r00 + w2 * r01 + w3 * r10 + w4 * r11; |
|
971 rres += ( 1 << ( KDecimalBits - 1 ) ); |
|
972 |
|
973 *t++ = PACK_16MA_ABGR( |
|
974 ares >> KDecimalBits, |
|
975 bres >> KDecimalBits, |
|
976 gres >> KDecimalBits, |
|
977 rres >> KDecimalBits ); |
|
978 |
|
979 sourceX += iU; |
|
980 } |
|
981 |
|
982 sourceY += iV; |
|
983 } |
|
984 |
|
985 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale16MA() <<" ), RThread().Id().operator TUint() ) ); |
|
986 } |
|
987 |
|
988 |
|
989 // ----------------------------------------------------------------------------- |
|
990 // CVtImageScalerImplBilinear::Scale2x4K64K( TUint32 aMask ) |
|
991 // ----------------------------------------------------------------------------- |
|
992 void CVtImageScalerImplBilinear::Scale2x4K64K( TUint32 aMask ) |
|
993 { |
|
994 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale2x4K64K() >>" ), RThread().Id().operator TUint() ) ); |
|
995 |
|
996 TInt sheight = iSource->Size().iHeight; |
|
997 TInt swidth = iSource->Size().iWidth; |
|
998 TInt spitch = iSource->BytesPerRow(); |
|
999 TInt dpitch = iTarget->BytesPerRow(); |
|
1000 |
|
1001 TUint32* s = iSource->DataAddress(); |
|
1002 TUint32* d = iTarget->DataAddress(); |
|
1003 TInt y; |
|
1004 |
|
1005 // first average source rows |
|
1006 for( y = 0; y < sheight; y++ ) |
|
1007 { |
|
1008 TUint32* s1 = s; |
|
1009 TUint32* d1 = d; |
|
1010 |
|
1011 TUint32 p = *s1++; // 2 pixels |
|
1012 TUint32 p1 = p & 0xffff; |
|
1013 TUint32 p2 = ( p >> 16 ) & 0xffff; |
|
1014 TInt x; |
|
1015 |
|
1016 for( x = 0; x < swidth/2 - 1; x++ ) |
|
1017 { |
|
1018 TUint32 p1a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 ); |
|
1019 *d1++ = p1 | ( p1a << 16 ); |
|
1020 |
|
1021 p = *s1++; // 2 pixels |
|
1022 |
|
1023 p1 = p & 0xffff; |
|
1024 TUint32 p2a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 ); |
|
1025 *d1++ = p2 | ( p2a << 16 ); |
|
1026 |
|
1027 p2 = ( p >> 16 ) & 0xffff; |
|
1028 } |
|
1029 |
|
1030 TUint32 p1a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 ); |
|
1031 *d1++ = p1 | ( p1a << 16 ); |
|
1032 |
|
1033 if( swidth & 1 ) |
|
1034 { |
|
1035 p = *s1; // 2 pixels |
|
1036 p1 = p & 0xffff; |
|
1037 TUint32 p2a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 ); |
|
1038 *d1++ = p2 | ( p2a << 16 ); |
|
1039 |
|
1040 p = *--s1; // 2 pixels |
|
1041 p2 = ( p >> 16 ) & 0xffff; |
|
1042 *d1++ = p1 | ( p1 << 16 ); |
|
1043 } |
|
1044 else |
|
1045 { |
|
1046 p = *--s1; // 2 pixels |
|
1047 p2 = ( p >> 16 ) & 0xffff; |
|
1048 *d1++ = p2 | ( p2 << 16 ); |
|
1049 } |
|
1050 |
|
1051 d = reinterpret_cast< TUint32* > |
|
1052 ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 ); |
|
1053 s = reinterpret_cast< TUint32* > |
|
1054 ( reinterpret_cast< TUint8* >( s ) + spitch ); |
|
1055 } |
|
1056 |
|
1057 // then average rows between |
|
1058 d = iTarget->DataAddress(); |
|
1059 |
|
1060 TUint32 mask32bit = aMask | ( aMask << 16 ); |
|
1061 |
|
1062 for( y = 0; y < sheight - 1; y++ ) |
|
1063 { |
|
1064 TUint32* d1 = reinterpret_cast< TUint32* >( d ); |
|
1065 TUint32* d2 = reinterpret_cast< TUint32* > |
|
1066 ( reinterpret_cast< TUint8* >( d1 ) + dpitch ); |
|
1067 TUint32* d3 = reinterpret_cast< TUint32* > |
|
1068 ( reinterpret_cast< TUint8* >( d2 ) + dpitch ); |
|
1069 |
|
1070 for( TInt x = 0; x < swidth; x++ ) |
|
1071 { |
|
1072 TUint32 p1 = *d1++; |
|
1073 TUint32 p2 = *d3++; |
|
1074 *d2++ = ( ( ( p1 ^ p2 ) & mask32bit ) >> 1 ) + ( p1 & p2 ); |
|
1075 } |
|
1076 |
|
1077 d = reinterpret_cast< TUint32* > |
|
1078 ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 ); |
|
1079 } |
|
1080 |
|
1081 // last row is just copy of previous row, because we cannot calculate |
|
1082 // average |
|
1083 Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch ); |
|
1084 |
|
1085 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale2x4K64K() <<" ), RThread().Id().operator TUint() ) ); |
|
1086 } |
|
1087 |
|
1088 // ----------------------------------------------------------------------------- |
|
1089 // CVtImageScalerImplBilinear::Scale2x16M() |
|
1090 // ----------------------------------------------------------------------------- |
|
1091 void CVtImageScalerImplBilinear::Scale2x16M() |
|
1092 { |
|
1093 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale2x16M() >>" ), RThread().Id().operator TUint() ) ); |
|
1094 |
|
1095 TInt sheight = iSource->Size().iHeight; |
|
1096 TInt swidth = iSource->Size().iWidth; |
|
1097 TInt spitch = iSource->BytesPerRow(); |
|
1098 TInt dpitch = iTarget->BytesPerRow(); |
|
1099 |
|
1100 TUint8* s = reinterpret_cast< TUint8* >( iSource->DataAddress() ); |
|
1101 TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() ); |
|
1102 |
|
1103 TInt y; |
|
1104 |
|
1105 for( y = 0; y < sheight; y++ ) |
|
1106 { |
|
1107 TUint8* s2 = s; |
|
1108 TUint8* d1 = d; |
|
1109 |
|
1110 TUint32 g1 = 0; |
|
1111 TUint32 b1 = 0; |
|
1112 TUint32 r1 = 0; |
|
1113 |
|
1114 TUint32 g2 = 0; |
|
1115 TUint32 b2 = 0; |
|
1116 TUint32 r2 = 0; |
|
1117 |
|
1118 for( TInt x = 0; x < swidth - 1; x++ ) |
|
1119 { |
|
1120 g1 = *s2++; |
|
1121 b1 = *s2++; |
|
1122 r1 = *s2++; |
|
1123 |
|
1124 *d1++ = static_cast< TUint8 >( g1 ); |
|
1125 *d1++ = static_cast< TUint8 >( b1 ); |
|
1126 *d1++ = static_cast< TUint8 >( r1 ); |
|
1127 |
|
1128 g2 = s2[ 0 ]; |
|
1129 b2 = s2[ 1 ]; |
|
1130 r2 = s2[ 2 ]; |
|
1131 |
|
1132 *d1++ = static_cast< TUint8 >( ( g1 + g2 ) >> 1 ); |
|
1133 *d1++ = static_cast< TUint8 >( ( b1 + b2 ) >> 1 ); |
|
1134 *d1++ = static_cast< TUint8 >( ( r1 + r2 ) >> 1 ); |
|
1135 } |
|
1136 |
|
1137 *d1++ = static_cast< TUint8 >( ( g1 + g2 ) >> 1 ); |
|
1138 *d1++ = static_cast< TUint8 >( ( b1 + b2 ) >> 1 ); |
|
1139 *d1++ = static_cast< TUint8 >( ( r1 + r2 ) >> 1 ); |
|
1140 |
|
1141 *d1++ = static_cast< TUint8 >( g2 ); |
|
1142 *d1++ = static_cast< TUint8 >( b2 ); |
|
1143 *d1++ = static_cast< TUint8 >( r2 ); |
|
1144 |
|
1145 d += dpitch * 2; |
|
1146 s += spitch; |
|
1147 } |
|
1148 |
|
1149 // then average rows between |
|
1150 d = reinterpret_cast< TUint8* >( iTarget->DataAddress() ); |
|
1151 |
|
1152 for( y = 0; y < sheight - 1; y++ ) |
|
1153 { |
|
1154 TUint8* d1 = d; |
|
1155 TUint8* d2 = d1 + dpitch; |
|
1156 TUint8* d3 = d2 + dpitch; |
|
1157 |
|
1158 for( TInt x = 0; x < swidth; x++ ) |
|
1159 { |
|
1160 TUint32 g1 = *d1++; |
|
1161 TUint32 g2 = *d3++; |
|
1162 *d2++ = static_cast< TUint8 >( ( g1 + g2 ) >> 1 ); |
|
1163 |
|
1164 TUint32 b1 = *d1++; |
|
1165 TUint32 b2 = *d3++; |
|
1166 *d2++ = static_cast< TUint8 >( ( b1 + b2 ) >> 1 ); |
|
1167 |
|
1168 TUint32 r1 = *d1++; |
|
1169 TUint32 r2 = *d3++; |
|
1170 *d2++ = static_cast< TUint8 >( ( r1 + r2 ) >> 1 ); |
|
1171 |
|
1172 g1 = *d1++; |
|
1173 g2 = *d3++; |
|
1174 *d2++ = static_cast< TUint8 >( ( g1 + g2 ) >> 1 ); |
|
1175 |
|
1176 b1 = *d1++; |
|
1177 b2 = *d3++; |
|
1178 *d2++ = static_cast< TUint8 >( ( b1 + b2 ) >> 1 ); |
|
1179 |
|
1180 r1 = *d1++; |
|
1181 r2 = *d3++; |
|
1182 *d2++ = static_cast< TUint8 >( ( r1 + r2 ) >> 1 ); |
|
1183 } |
|
1184 |
|
1185 d += dpitch * 2; |
|
1186 } |
|
1187 |
|
1188 // last row is just copy of previous row, because we cannot calculate |
|
1189 // average |
|
1190 Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch ); |
|
1191 |
|
1192 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale2x16M() <<" ), RThread().Id().operator TUint() ) ); |
|
1193 } |
|
1194 |
|
1195 // ----------------------------------------------------------------------------- |
|
1196 // CVtImageScalerImplBilinear::Scale2x16MU16MA() |
|
1197 // ----------------------------------------------------------------------------- |
|
1198 void CVtImageScalerImplBilinear::Scale2x16MU16MA() |
|
1199 { |
|
1200 |
|
1201 #if defined ( __MARM_ARMI__ ) && defined ( NDEBUG ) && defined ( __USE_ASM_OPTS ) // From urel |
|
1202 |
|
1203 asm("stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, r11, r12, lr} "); |
|
1204 asm("ldr r11, .L1_671"); |
|
1205 asm("sub sp, sp, #24 "); |
|
1206 asm("mov r6, r0 "); |
|
1207 asm("ldr r1, [r6, #4] "); |
|
1208 asm("ldr r3, [r1, #0] "); |
|
1209 asm("add r0, sp, #16 "); |
|
1210 asm("ldr ip, [r3, #20] "); |
|
1211 asm("mov lr, pc "); |
|
1212 asm("bx ip "); |
|
1213 asm("ldr r7, [sp, #20] "); |
|
1214 asm("ldr r1, [r6, #4] "); |
|
1215 asm("ldr r3, [r1, #0] "); |
|
1216 asm("add r0, sp, #8 "); |
|
1217 asm("ldr ip, [r3, #20] "); |
|
1218 asm("mov lr, pc "); |
|
1219 asm("bx ip "); |
|
1220 asm("ldr r9, [sp, #8] "); |
|
1221 asm("str r9, [sp, #0] "); |
|
1222 asm("ldr r0, [r6, #4] "); |
|
1223 asm("ldr r3, [r0, #0] "); |
|
1224 asm("ldr ip, [r3, #24] "); |
|
1225 asm("mov lr, pc "); |
|
1226 asm("bx ip "); |
|
1227 asm("str r0, [sp, #4] "); |
|
1228 asm("ldr r0, [r6, #8] "); |
|
1229 asm("ldr r3, [r0, #0] "); |
|
1230 asm("ldr ip, [r3, #24] "); |
|
1231 asm("mov lr, pc "); |
|
1232 asm("bx ip "); |
|
1233 asm("mov sl, r0 "); |
|
1234 asm("ldr r0, [r6, #4] "); |
|
1235 asm("ldr r3, [r0, #0] "); |
|
1236 asm("ldr ip, [r3, #28] "); |
|
1237 asm("mov lr, pc "); |
|
1238 asm("bx ip "); |
|
1239 asm("mov r4, r0 "); |
|
1240 asm("ldr r0, [r6, #8] "); |
|
1241 asm("ldr r3, [r0, #0] "); |
|
1242 asm("ldr ip, [r3, #28] "); |
|
1243 asm("mov lr, pc "); |
|
1244 asm("bx ip "); |
|
1245 asm("mov r5, r0 "); |
|
1246 asm("subs r8, r7, #1 "); |
|
1247 asm("bmi .L1_654 "); |
|
1248 |
|
1249 asm(" .L1_656: "); |
|
1250 asm("mov ip, r5 "); |
|
1251 asm("mov lr, r4 "); |
|
1252 asm("ldr r1, [lr], #4 "); |
|
1253 asm("ldr r9, [sp, #0] "); |
|
1254 asm("cmp r9, #4"); |
|
1255 asm("bhi .L1_658_1"); |
|
1256 |
|
1257 // picture width lower or equal to 4 |
|
1258 asm("subs r0, r9, #2"); |
|
1259 asm("bmi .L1_658"); |
|
1260 |
|
1261 asm("ldr r9, [lr], #4 "); |
|
1262 asm("eor r2, r9, r1 "); |
|
1263 asm("and r2, r2, r11 "); |
|
1264 asm("and r3, r9, r1 "); |
|
1265 asm("add r3, r3, r2, lsr #1 "); |
|
1266 asm("str r1, [ip], #4"); |
|
1267 asm("str r3, [ip], #4"); |
|
1268 |
|
1269 asm("subs r0, r0, #1"); |
|
1270 asm("strmi r9, [ip], #4"); |
|
1271 asm("strmi r9, [ip], #4"); |
|
1272 asm("bmi .L1_658"); |
|
1273 |
|
1274 asm("ldr r1, [lr], #4 "); |
|
1275 asm("eor r2, r9, r1 "); |
|
1276 asm("and r2, r2, r11 "); |
|
1277 asm("and r3, r9, r1 "); |
|
1278 asm("add r3, r3, r2, lsr #1 "); |
|
1279 asm("str r9, [ip], #4"); |
|
1280 asm("str r3, [ip], #4"); |
|
1281 |
|
1282 asm("subs r0, r0, #1"); |
|
1283 asm("strmi r1, [ip], #4"); |
|
1284 asm("strmi r1, [ip], #4"); |
|
1285 asm("bmi .L1_658"); |
|
1286 |
|
1287 asm("ldr r9, [lr], #4 "); |
|
1288 asm("eor r2, r9, r1 "); |
|
1289 asm("and r2, r2, r11 "); |
|
1290 asm("and r3, r9, r1 "); |
|
1291 asm("add r3, r3, r2, lsr #1 "); |
|
1292 asm("str r1, [ip], #4"); |
|
1293 asm("str r3, [ip], #4"); |
|
1294 |
|
1295 asm("b .L1_658"); |
|
1296 |
|
1297 // picture width higher than 4 |
|
1298 asm(" .L1_658_1:"); |
|
1299 asm("mov r9, r9, lsr #1 "); |
|
1300 asm("subs r0, r9, #2 "); |
|
1301 asm("bmi .L1_658 "); |
|
1302 |
|
1303 asm(" .L1_660: "); |
|
1304 asm("ldr r9, [lr], #4 "); |
|
1305 asm("eor r2, r9, r1 "); |
|
1306 asm("and r2, r2, r11 "); |
|
1307 asm("and r3, r9, r1 "); |
|
1308 asm("add r3, r3, r2, lsr #1 "); |
|
1309 asm("stmia ip!, { r1, r3, r9 } "); |
|
1310 asm("sub r0, r0, #1 "); |
|
1311 asm("ldr r1, [lr], #4 "); |
|
1312 asm("eor r2, r9, r1 "); |
|
1313 asm("and r2, r2, r11 "); |
|
1314 asm("and r3, r9, r1 "); |
|
1315 asm("add r3, r3, r2, lsr #1 "); |
|
1316 asm("str r3, [ip], #4"); |
|
1317 asm("cmp r0,#0"); |
|
1318 asm("bge .L1_660 "); |
|
1319 |
|
1320 asm(" .L1_658: "); |
|
1321 asm("str r1, [ip], #4 "); |
|
1322 asm("str r1, [ip, #0] "); |
|
1323 asm("add r5, r5, sl, asl #1 "); |
|
1324 asm("ldr r9, [sp, #4] "); |
|
1325 asm("add r4, r4, r9 "); |
|
1326 asm("subs r8, r8, #1 "); |
|
1327 asm("bpl .L1_656 "); |
|
1328 |
|
1329 asm(" .L1_654: "); |
|
1330 asm("ldr r0, [r6, #8] "); |
|
1331 asm("ldr r3, [r0, #0] "); |
|
1332 asm("ldr ip, [r3, #28] "); |
|
1333 asm("mov lr, pc "); |
|
1334 asm("bx ip "); |
|
1335 asm("mov r5, r0 "); |
|
1336 asm("subs r8, r7, #2 "); |
|
1337 asm("bmi .L1_664 "); |
|
1338 |
|
1339 asm(" .L1_666: "); |
|
1340 asm("mov r7, r5 "); |
|
1341 asm("add r4, r5, sl "); |
|
1342 asm("add r6, r4, sl "); |
|
1343 asm("ldr r9, [sp, #0] "); |
|
1344 asm("subs lr, r9, #1 "); |
|
1345 asm("bmi .L1_668 "); |
|
1346 |
|
1347 asm(" .L1_670: "); |
|
1348 asm("ldr r1, [r7], #4 "); |
|
1349 asm("ldr r2, [r7], #4 "); |
|
1350 asm("ldr r0, [r6], #4 "); |
|
1351 asm("ldr ip, [r6], #4 "); |
|
1352 asm("eor r3, r1, r0 "); |
|
1353 asm("and r3, r3, r11 "); |
|
1354 asm("and r1, r1, r0 "); |
|
1355 asm("add r1, r1, r3, lsr #1 "); |
|
1356 asm("str r1, [r4], #4 "); |
|
1357 asm("eor r3, r2, ip "); |
|
1358 asm("and r3, r3, r11 "); |
|
1359 asm("and r2, r2, ip "); |
|
1360 asm("add r2, r2, r3, lsr #1 "); |
|
1361 asm("str r2, [r4], #4 "); |
|
1362 asm("subs lr, lr, #1 "); |
|
1363 asm("bpl .L1_670 "); |
|
1364 |
|
1365 asm(" .L1_668: "); |
|
1366 asm("add r5, r5, sl, asl #1 "); |
|
1367 asm("subs r8, r8, #1 "); |
|
1368 asm("bpl .L1_666 "); |
|
1369 |
|
1370 asm(" .L1_664: "); |
|
1371 asm("add r0, r5, sl "); |
|
1372 asm("mov r1, r5 "); |
|
1373 asm("mov r2, sl "); |
|
1374 asm("bl Copy__3MemPvPCvi "); |
|
1375 asm("add sp, sp, #24 "); |
|
1376 asm("ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, r11, r12, lr} "); |
|
1377 asm("bx lr "); |
|
1378 |
|
1379 asm(" .align 0 "); |
|
1380 asm(" .L1_671: "); |
|
1381 asm(" .word 0x00fefefe "); |
|
1382 |
|
1383 #else |
|
1384 |
|
1385 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale2x16MU16MA() >>" ), RThread().Id().operator TUint() ) ); |
|
1386 |
|
1387 TInt sheight = iSource->Size().iHeight; |
|
1388 TInt swidth = iSource->Size().iWidth; |
|
1389 TInt spitch = iSource->BytesPerRow(); |
|
1390 TInt dpitch = iTarget->BytesPerRow(); |
|
1391 |
|
1392 TUint32 mask = 0xfefefefe; |
|
1393 TUint32* s = iSource->DataAddress(); |
|
1394 TUint32* d = iTarget->DataAddress(); |
|
1395 TInt y; |
|
1396 |
|
1397 TUint32 p1; |
|
1398 TUint32 p2; |
|
1399 TUint32 p3; |
|
1400 TUint32 p4; |
|
1401 |
|
1402 // first average source rows |
|
1403 for( y = sheight - 1; y >= 0; y-- ) |
|
1404 { |
|
1405 TUint32* s1 = s; |
|
1406 TUint32* d1 = d; |
|
1407 |
|
1408 TUint32 p2 = *s1++; |
|
1409 TUint32 p1 = 0; |
|
1410 |
|
1411 for( TInt x = swidth - 2; x >= 0; x-- ) |
|
1412 { |
|
1413 *d1++ = p2; |
|
1414 p1 = p2; |
|
1415 p2 = *s1++; |
|
1416 *d1++ = ( ( ( p1 ^ p2 ) & mask ) >> 1 ) + ( p1 & p2 ); |
|
1417 } |
|
1418 |
|
1419 *d1++ = p2; |
|
1420 *d1++ = p2; |
|
1421 |
|
1422 d = reinterpret_cast< TUint32* > |
|
1423 ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 ); |
|
1424 s = reinterpret_cast< TUint32* > |
|
1425 ( reinterpret_cast< TUint8* >( s ) + spitch ); |
|
1426 } |
|
1427 |
|
1428 // then average rows between |
|
1429 d = iTarget->DataAddress(); |
|
1430 |
|
1431 for( y = sheight - 2; y >= 0; y-- ) |
|
1432 { |
|
1433 TUint32* d1 = reinterpret_cast< TUint32* >( d ); |
|
1434 TUint32* d2 = reinterpret_cast< TUint32* > |
|
1435 ( reinterpret_cast< TUint8* >( d1 ) + dpitch ); |
|
1436 TUint32* d3 = reinterpret_cast< TUint32* > |
|
1437 ( reinterpret_cast< TUint8* >( d2 ) + dpitch ); |
|
1438 |
|
1439 for( TInt x = swidth - 1; x >= 0; x-- ) |
|
1440 { |
|
1441 p1 = *d1++; |
|
1442 p2 = *d3++; |
|
1443 *d2++ = ( ( ( p1 ^ p2 ) & mask ) >> 1 ) + ( p1 & p2 ); |
|
1444 p3 = *d1++; |
|
1445 p4 = *d3++; |
|
1446 *d2++ = ( ( ( p3 ^ p4 ) & mask ) >> 1 ) + ( p3 & p4 ); |
|
1447 } |
|
1448 |
|
1449 d = reinterpret_cast< TUint32* > |
|
1450 ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 ); |
|
1451 } |
|
1452 |
|
1453 // last row is just copy of previous row, because we cannot calculate |
|
1454 // average |
|
1455 Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch ); |
|
1456 __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplBilinear::Scale2x16MU16MA() <<" ), RThread().Id().operator TUint() ) ); |
|
1457 |
|
1458 #endif |
|
1459 |
|
1460 } |
|
1461 |
|
1462 // End of File |