vtprotocolplugins/DisplaySink/src/CVtImageScalerImplWeightedAverage.cpp
changeset 0 ed9695c8bcbe
equal deleted inserted replaced
-1:000000000000 0:ed9695c8bcbe
       
     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 "CVtImageScalerImplWeightedAverage.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 = 16;        // 16.16 pseudo real format
       
    39 
       
    40 // ============================ MEMBER FUNCTIONS ===============================
       
    41 
       
    42 // ======================= CVtImageScalerImplWeightedAverage ===================
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CVtImageScalerImplWeightedAverage::Scale( TBool& aContinue )
       
    46 // -----------------------------------------------------------------------------
       
    47 TInt CVtImageScalerImplWeightedAverage::Scale( TBool& aContinue )
       
    48     {
       
    49     TInt result( KErrNone );
       
    50 
       
    51     aContinue = EFalse;
       
    52 
       
    53     // this implementation does not support different display modes for source
       
    54     // and target
       
    55     if( iSource->DisplayMode() != iTarget->DisplayMode() )
       
    56         {
       
    57         return KErrNotSupported;
       
    58         }
       
    59 
       
    60     // if sizes are same, just copy the data
       
    61     if( iSource->Size() == iTarget->Size() )
       
    62         {
       
    63         Mem::Copy(
       
    64             iTarget->DataAddress(),
       
    65             iSource->DataAddress(),
       
    66             iTarget->BytesPerRow() * iTarget->Size().iHeight );
       
    67         }
       
    68     else if ( ( iSource->Size().iHeight * 2 == iTarget->Size().iHeight )
       
    69             && ( iSource->Size().iWidth * 2 == iTarget->Size().iWidth ) )
       
    70         {
       
    71         switch( iSource->DisplayMode() )
       
    72             {
       
    73             case CVtImage::EVtColor4K:
       
    74                 Scale2x4K64K( 0xeee );  // 0000ggggbbbbrrrr ->
       
    75                 break;                  // mask = %0000111011101110 = 0xeee
       
    76 
       
    77             case CVtImage::EVtColor64K:
       
    78                 Scale2x4K64K( 0xf7de ); // bbbbbggggggrrrrr ->
       
    79                 break;                  // mask = %1111011111011110 = 0xf7de
       
    80 
       
    81             case CVtImage::EVtColor16M:
       
    82                 Scale2x16M();
       
    83                 break;
       
    84 
       
    85             case CVtImage::EVtColor16MU:
       
    86             case CVtImage::EVtColor16MA:
       
    87                 Scale2x16MU16MA();
       
    88                 break;
       
    89 
       
    90             default:
       
    91                 if ( iSource->Type() == CVtImage::EVtImageBitmap &&
       
    92                      iTarget->Type() == CVtImage::EVtImageBitmap )
       
    93                     {
       
    94                     TRAPD( error,
       
    95                         ScaleWithBitmapScalerL(
       
    96                             CBitmapScaler::EMediumQuality ) );
       
    97                     result = error;
       
    98                     }
       
    99                 else
       
   100                     {
       
   101                     result = KErrNotSupported;
       
   102                     }
       
   103             }
       
   104         }
       
   105     else
       
   106         {
       
   107         Initialize();
       
   108 
       
   109         switch( iSource->DisplayMode() )
       
   110             {
       
   111             case CVtImage::EVtColor4K:
       
   112                 Scale4K();
       
   113                 break;
       
   114 
       
   115             case CVtImage::EVtColor64K:
       
   116                 Scale64K();
       
   117                 break;
       
   118 
       
   119             case CVtImage::EVtColor16M:
       
   120                 Scale16M();
       
   121                 break;
       
   122 
       
   123             case CVtImage::EVtColor16MU:
       
   124                 Scale16MU();
       
   125                 break;
       
   126 
       
   127             case CVtImage::EVtColor16MA:
       
   128                 Scale16MA();
       
   129                 break;
       
   130 
       
   131             default:
       
   132                 if ( iSource->Type() == CVtImage::EVtImageBitmap &&
       
   133                      iTarget->Type() == CVtImage::EVtImageBitmap )
       
   134                     {
       
   135                     TRAPD( error,
       
   136                         ScaleWithBitmapScalerL(
       
   137                             CBitmapScaler::EMediumQuality ) );
       
   138                     result = error;
       
   139                     }
       
   140                 else
       
   141                     {
       
   142                     result = KErrNotSupported;
       
   143                     }
       
   144             }
       
   145         }
       
   146 
       
   147     return result;
       
   148     }
       
   149 
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // CVtImageScalerImplWeightedAverage::ValidateSourceTargetL(
       
   153 // const CVtImage& aSource, CVtImage& aTarget )
       
   154 // -----------------------------------------------------------------------------
       
   155 void CVtImageScalerImplWeightedAverage::ValidateSourceTargetL(
       
   156     const CVtImage& aSource,
       
   157     CVtImage& aTarget )
       
   158     {
       
   159     // source and target must have same displaymode
       
   160     if( aSource.DisplayMode() != aTarget.DisplayMode() )
       
   161         {
       
   162         User::Leave( KErrNotSupported );
       
   163         }
       
   164 
       
   165     // only 4K, 64K, 16M and 16MU modes are supported
       
   166     switch( aSource.DisplayMode() )
       
   167         {
       
   168         case CVtImage::EVtColor4K:
       
   169         case CVtImage::EVtColor64K:
       
   170         case CVtImage::EVtColor16M:
       
   171         case CVtImage::EVtColor16MU:
       
   172         case CVtImage::EVtColor16MA:
       
   173             break;
       
   174 
       
   175         default:
       
   176             // Scaling for bitmaps is supported for other display modes
       
   177             if ( !( aSource.Type() == CVtImage::EVtImageBitmap &&
       
   178                  aTarget.Type() == CVtImage::EVtImageBitmap ) )
       
   179                 {
       
   180                 User::Leave( KErrNotSupported );
       
   181                 }
       
   182         }
       
   183     }
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // CVtImageScalerImplWeightedAverage::Initialize()
       
   187 // -----------------------------------------------------------------------------
       
   188 void CVtImageScalerImplWeightedAverage::Initialize()
       
   189     {
       
   190     iU = ( 1 << KDecimalBits ) * iSource->Size().iWidth /
       
   191         iTarget->Size().iWidth;
       
   192     iV = ( 1 << KDecimalBits ) * iSource->Size().iHeight /
       
   193         iTarget->Size().iHeight;
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CVtImageScalerImplWeightedAverage::Scale4K()
       
   198 // -----------------------------------------------------------------------------
       
   199 void CVtImageScalerImplWeightedAverage::Scale4K()
       
   200     {
       
   201     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale4K() >>" ), RThread().Id().operator TUint() ) );
       
   202 
       
   203     TInt width = iTarget->Size().iWidth;
       
   204 
       
   205     TInt height = iTarget->Size().iHeight;
       
   206 
       
   207     TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU );
       
   208 
       
   209     TUint16* t = reinterpret_cast< TUint16* >( iTarget->DataAddress() );
       
   210 
       
   211     TUint32 sourceY( 0 );
       
   212 
       
   213     TUint32 b00( 0 );
       
   214     TUint32 g00( 0 );
       
   215     TUint32 r00( 0 );
       
   216     TUint32 b01( 0 );
       
   217     TUint32 g01( 0 );
       
   218     TUint32 r01( 0 );
       
   219     TUint32 b10( 0 );
       
   220     TUint32 g10( 0 );
       
   221     TUint32 r10( 0 );
       
   222 
       
   223     for( TInt y = 0; y < height; y++ )
       
   224         {
       
   225         TUint16* s = reinterpret_cast< TUint16* >(
       
   226             iSource->LineAddress( sourceY >> KDecimalBits ) );
       
   227         TUint16* snext = reinterpret_cast< TUint16* >(
       
   228             iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ) );
       
   229 
       
   230         TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part
       
   231         TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part
       
   232 
       
   233         TUint32 sourceX( 0 );
       
   234 
       
   235         TInt x;
       
   236 
       
   237         TUint32 x0prev( TUint32( -1 ) );
       
   238 
       
   239         for( x = 0; x < mod_width; x++ )
       
   240             {
       
   241             TUint32 x0 = sourceX >> KDecimalBits;
       
   242 
       
   243             if( x0 != x0prev )
       
   244                 {
       
   245                 TUint32 p0 = *( s + x0 );
       
   246 
       
   247                 b00 = UNPACK_4K_BLUE( p0 );
       
   248                 g00 = UNPACK_4K_GREEN( p0 );
       
   249                 r00 = UNPACK_4K_RED( p0 );
       
   250 
       
   251                 p0 = *( s + x0 + 1 );
       
   252 
       
   253                 b01 = UNPACK_4K_BLUE( p0 );
       
   254                 g01 = UNPACK_4K_GREEN( p0 );
       
   255                 r01 = UNPACK_4K_RED( p0 );
       
   256 
       
   257                 p0 = *( snext + x0 );
       
   258 
       
   259                 b10 = UNPACK_4K_BLUE( p0 );
       
   260                 g10 = UNPACK_4K_GREEN( p0 );
       
   261                 r10 = UNPACK_4K_RED( p0 );
       
   262 
       
   263                 x0prev = x0;
       
   264                 }
       
   265 
       
   266             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 );
       
   267             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   268 
       
   269             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   270             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   271             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   272 
       
   273             *t++ = PACK_4K_BGR(
       
   274                 bres >> ( KDecimalBits + 1 ),
       
   275                 gres >> ( KDecimalBits + 1 ),
       
   276                 rres >> ( KDecimalBits + 1 ) );
       
   277 
       
   278             sourceX += iU;
       
   279             }
       
   280 
       
   281         // handle last columns
       
   282         for( ; x < width; x++ )
       
   283             {
       
   284             TUint32 x0 = sourceX >> KDecimalBits;
       
   285 
       
   286             if( x0 != x0prev )
       
   287                 {
       
   288                 TUint32 p0 = *( s + x0 );
       
   289                 b01 = b00 = UNPACK_4K_BLUE( p0 );
       
   290                 g01 = g00 = UNPACK_4K_GREEN( p0 );
       
   291                 r01 = r00 = UNPACK_4K_RED( p0 );
       
   292 
       
   293                 p0 = *( snext + x0 );
       
   294                 b10 = UNPACK_4K_BLUE( p0 );
       
   295                 g10 = UNPACK_4K_GREEN( p0 );
       
   296                 r10 = UNPACK_4K_RED( p0 );
       
   297 
       
   298                 x0prev = x0;
       
   299                 }
       
   300 
       
   301             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal
       
   302             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   303 
       
   304             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   305             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   306             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   307 
       
   308             *t++ = PACK_4K_BGR(
       
   309                 bres >> ( KDecimalBits + 1 ),
       
   310                 gres >> ( KDecimalBits + 1 ),
       
   311                 rres >> ( KDecimalBits + 1 ) );
       
   312 
       
   313             sourceX += iU;
       
   314             }
       
   315 
       
   316         // if width is not even -> then we need to skip one additional byte
       
   317         if( width & 1 )
       
   318             {
       
   319             t++;
       
   320             }
       
   321 
       
   322         sourceY += iV;
       
   323         }
       
   324 
       
   325     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale4K() <<" ), RThread().Id().operator TUint() ) );
       
   326     }
       
   327 
       
   328 // -----------------------------------------------------------------------------
       
   329 // CVtImageScalerImplWeightedAverage::Scale64K()
       
   330 // -----------------------------------------------------------------------------
       
   331 void CVtImageScalerImplWeightedAverage::Scale64K()
       
   332     {
       
   333     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale64K() >>" ), RThread().Id().operator TUint() ) );
       
   334 
       
   335     TInt width = iTarget->Size().iWidth;
       
   336 
       
   337     TInt height = iTarget->Size().iHeight;
       
   338 
       
   339     TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU );
       
   340 
       
   341     TUint16* t = reinterpret_cast< TUint16* >( iTarget->DataAddress() );
       
   342 
       
   343     TUint32 sourceY( 0 );
       
   344 
       
   345     TUint32 b00( 0 );
       
   346     TUint32 g00( 0 );
       
   347     TUint32 r00( 0 );
       
   348     TUint32 b01( 0 );
       
   349     TUint32 g01( 0 );
       
   350     TUint32 r01( 0 );
       
   351     TUint32 b10( 0 );
       
   352     TUint32 g10( 0 );
       
   353     TUint32 r10( 0 );
       
   354 
       
   355     for( TInt y = 0; y < height; y++ )
       
   356         {
       
   357         TUint16* s = reinterpret_cast< TUint16* >
       
   358             ( iSource->LineAddress( sourceY >> KDecimalBits ) );
       
   359         TUint16* snext = reinterpret_cast< TUint16* >
       
   360             ( iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ) );
       
   361 
       
   362         TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part
       
   363         TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part
       
   364 
       
   365         TUint32 sourceX( 0 );
       
   366 
       
   367         TInt x;
       
   368 
       
   369         TUint32 x0prev( TUint32( -1 ) );
       
   370 
       
   371         for( x = 0; x < mod_width; x++ )
       
   372             {
       
   373             TUint32 x0 = sourceX >> KDecimalBits;
       
   374 
       
   375             if( x0 != x0prev )
       
   376                 {
       
   377                 TUint32 p0 = *( s + x0 );
       
   378 
       
   379                 b00 = UNPACK_64K_BLUE( p0 );
       
   380                 g00 = UNPACK_64K_GREEN( p0 );
       
   381                 r00 = UNPACK_64K_RED( p0 );
       
   382 
       
   383                 p0 = *( s + x0 + 1 );
       
   384 
       
   385                 b01 = UNPACK_64K_BLUE( p0 );
       
   386                 g01 = UNPACK_64K_GREEN( p0 );
       
   387                 r01 = UNPACK_64K_RED( p0 );
       
   388 
       
   389                 p0 = *( snext + x0 );
       
   390 
       
   391                 b10 = UNPACK_64K_BLUE( p0 );
       
   392                 g10 = UNPACK_64K_GREEN( p0 );
       
   393                 r10 = UNPACK_64K_RED( p0 );
       
   394 
       
   395                 x0prev = x0;
       
   396                 }
       
   397 
       
   398             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 );
       
   399             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   400 
       
   401             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   402             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   403             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   404 
       
   405             *t++ = PACK_64K_BGR(
       
   406                 bres >> ( KDecimalBits + 1 ),
       
   407                 gres >> ( KDecimalBits + 1 ),
       
   408                 rres >> ( KDecimalBits + 1 ) );
       
   409 
       
   410             sourceX += iU;
       
   411             }
       
   412 
       
   413         // handle last columns
       
   414         for( ; x < width; x++ )
       
   415             {
       
   416             TUint32 x0 = sourceX >> KDecimalBits;
       
   417 
       
   418             if( x0 != x0prev )
       
   419                 {
       
   420                 TUint32 p0 = *( s + x0 );
       
   421                 b01 = b00 = UNPACK_64K_BLUE( p0 );
       
   422                 g01 = g00 = UNPACK_64K_GREEN( p0 );
       
   423                 r01 = r00 = UNPACK_64K_RED( p0 );
       
   424 
       
   425                 p0 = *( snext + x0 );
       
   426                 b10 = UNPACK_64K_BLUE( p0 );
       
   427                 g10 = UNPACK_64K_GREEN( p0 );
       
   428                 r10 = UNPACK_64K_RED( p0 );
       
   429 
       
   430                 x0prev = x0;
       
   431                 }
       
   432 
       
   433             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal
       
   434             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   435 
       
   436             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   437             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   438             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   439 
       
   440             *t++ = PACK_64K_BGR(
       
   441                 bres >> ( KDecimalBits + 1 ),
       
   442                 gres >> ( KDecimalBits + 1 ),
       
   443                 rres >> ( KDecimalBits + 1 ) );
       
   444 
       
   445             sourceX += iU;
       
   446             }
       
   447 
       
   448         // if width is not even -> then we need to skip one additional byte
       
   449         if( width & 1 )
       
   450             {
       
   451             t++;
       
   452             }
       
   453 
       
   454         sourceY += iV;
       
   455         }
       
   456 
       
   457     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale64K() <<" ), RThread().Id().operator TUint() ) );
       
   458     }
       
   459 
       
   460 // -----------------------------------------------------------------------------
       
   461 // CVtImageScalerImplWeightedAverage::Scale16M()
       
   462 // -----------------------------------------------------------------------------
       
   463 void CVtImageScalerImplWeightedAverage::Scale16M()
       
   464     {
       
   465     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale16M() >>" ), RThread().Id().operator TUint() ) );
       
   466 
       
   467     TInt width = iTarget->Size().iWidth;
       
   468 
       
   469     TInt height = iTarget->Size().iHeight;
       
   470 
       
   471     TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU );
       
   472 
       
   473     TUint32 t_pitch = iTarget->BytesPerRow();
       
   474 
       
   475     TUint8* t = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
       
   476 
       
   477     TUint32 sourceY( 0 );
       
   478 
       
   479     TUint32 b00( 0 );
       
   480     TUint32 g00( 0 );
       
   481     TUint32 r00( 0 );
       
   482     TUint32 b01( 0 );
       
   483     TUint32 g01( 0 );
       
   484     TUint32 r01( 0 );
       
   485     TUint32 b10( 0 );
       
   486     TUint32 g10( 0 );
       
   487     TUint32 r10( 0 );
       
   488 
       
   489     for( TInt y = 0; y < height; y++ )
       
   490         {
       
   491         TUint8* s = reinterpret_cast< TUint8* >(
       
   492             iSource->LineAddress( sourceY >> KDecimalBits ) );
       
   493         TUint8* snext = reinterpret_cast< TUint8* >(
       
   494             iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 ) );
       
   495 
       
   496         TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part
       
   497         TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part
       
   498 
       
   499         TUint32 sourceX( 0 );
       
   500 
       
   501         TInt x;
       
   502 
       
   503         TUint32 x0prev( TUint32( -1 ) );
       
   504 
       
   505         TUint8* d = t;
       
   506 
       
   507         // first columns
       
   508         for( x = 0; x < mod_width; x++ )
       
   509             {
       
   510             TUint32 x0 = ( sourceX >> KDecimalBits ) * 3;
       
   511 
       
   512             if( x0 != x0prev )
       
   513                 {
       
   514                 TUint8* tempSrc = s + x0;
       
   515 
       
   516                 b00 = *tempSrc++;
       
   517                 g00 = *tempSrc++;
       
   518                 r00 = *tempSrc++;
       
   519 
       
   520                 b01 = *tempSrc++;
       
   521                 g01 = *tempSrc++;
       
   522                 r01 = *tempSrc++;
       
   523 
       
   524                 tempSrc = snext + x0;
       
   525 
       
   526                 b10 = *tempSrc++;
       
   527                 g10 = *tempSrc++;
       
   528                 r10 = *tempSrc++;
       
   529 
       
   530                 x0prev = x0;
       
   531                 }
       
   532 
       
   533             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal
       
   534             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   535 
       
   536             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   537             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   538             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   539 
       
   540             *d++ = static_cast< TUint8 >( bres >> ( KDecimalBits + 1 ) );
       
   541             *d++ = static_cast< TUint8 >( gres >> ( KDecimalBits + 1 ) );
       
   542             *d++ = static_cast< TUint8 >( rres >> ( KDecimalBits + 1 ) );
       
   543 
       
   544             sourceX += iU;
       
   545             }
       
   546 
       
   547         // handle last columns
       
   548         for( ; x < width; x++ )
       
   549             {
       
   550             TUint32 x0 = ( sourceX >> KDecimalBits ) * 3;
       
   551 
       
   552             if( x0 != x0prev )
       
   553                 {
       
   554                 TUint8* tempSrc = s + x0;
       
   555 
       
   556                 b01 = b00 = *tempSrc++;
       
   557                 g01 = g00 = *tempSrc++;
       
   558                 r01 = r00 = *tempSrc++;
       
   559 
       
   560                 tempSrc = snext + x0;
       
   561 
       
   562                 b10 = *tempSrc++;
       
   563                 g10 = *tempSrc++;
       
   564                 r10 = *tempSrc++;
       
   565 
       
   566                 x0prev = x0;
       
   567                 }
       
   568 
       
   569             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal
       
   570             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   571 
       
   572             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   573             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   574             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   575 
       
   576             *d++ = static_cast< TUint8 >( bres >> ( KDecimalBits + 1 ) );
       
   577             *d++ = static_cast< TUint8 >( gres >> ( KDecimalBits + 1 ) );
       
   578             *d++ = static_cast< TUint8 >( rres >> ( KDecimalBits + 1 ) );
       
   579 
       
   580             sourceX += iU;
       
   581             }
       
   582 
       
   583         t += t_pitch;
       
   584 
       
   585         sourceY += iV;
       
   586         }
       
   587 
       
   588     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale16M() <<" ), RThread().Id().operator TUint() ) );
       
   589     }
       
   590 
       
   591 // -----------------------------------------------------------------------------
       
   592 // CVtImageScalerImplWeightedAverage::Scale16MU()
       
   593 // -----------------------------------------------------------------------------
       
   594 void CVtImageScalerImplWeightedAverage::Scale16MU()
       
   595     {
       
   596     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale16MU() >>" ), RThread().Id().operator TUint() ) );
       
   597 
       
   598     TInt width = iTarget->Size().iWidth;
       
   599 
       
   600     TInt height = iTarget->Size().iHeight;
       
   601 
       
   602     TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU );
       
   603 
       
   604     TUint32* t = iTarget->DataAddress();
       
   605 
       
   606     TUint32 sourceY( 0 );
       
   607 
       
   608     TUint32 b00( 0 );
       
   609     TUint32 g00( 0 );
       
   610     TUint32 r00( 0 );
       
   611     TUint32 b01( 0 );
       
   612     TUint32 g01( 0 );
       
   613     TUint32 r01( 0 );
       
   614     TUint32 b10( 0 );
       
   615     TUint32 g10( 0 );
       
   616     TUint32 r10( 0 );
       
   617 
       
   618     for( TInt y = 0; y < height; y++ )
       
   619         {
       
   620         TUint32* s = iSource->LineAddress( sourceY >> KDecimalBits );
       
   621         TUint32* snext = iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 );
       
   622 
       
   623         TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part
       
   624         TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part
       
   625 
       
   626         TUint32 sourceX( 0 );
       
   627 
       
   628         TInt x;
       
   629 
       
   630         TUint32 x0prev( TUint32( -1 ) );
       
   631 
       
   632         for( x = 0; x < mod_width; x++ )
       
   633             {
       
   634             TUint32 x0 = sourceX >> KDecimalBits;
       
   635 
       
   636             if( x0 != x0prev )
       
   637                 {
       
   638                 TUint32 p0 = *( s + x0 );
       
   639 
       
   640                 b00 = UNPACK_16MU_BLUE( p0 );
       
   641                 g00 = UNPACK_16MU_GREEN( p0 );
       
   642                 r00 = UNPACK_16MU_RED( p0 );
       
   643 
       
   644                 p0 = *( s + x0 + 1 );
       
   645 
       
   646                 b01 = UNPACK_16MU_BLUE( p0 );
       
   647                 g01 = UNPACK_16MU_GREEN( p0 );
       
   648                 r01 = UNPACK_16MU_RED( p0 );
       
   649 
       
   650                 p0 = *( snext + x0 );
       
   651 
       
   652                 b10 = UNPACK_16MU_BLUE( p0 );
       
   653                 g10 = UNPACK_16MU_GREEN( p0 );
       
   654                 r10 = UNPACK_16MU_RED( p0 );
       
   655 
       
   656                 x0prev = x0;
       
   657                 }
       
   658 
       
   659             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 );
       
   660             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   661 
       
   662             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   663             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   664             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   665 
       
   666             *t++ = PACK_16MU_BGR(
       
   667                 bres >> ( KDecimalBits + 1 ),
       
   668                 gres >> ( KDecimalBits + 1 ),
       
   669                 rres >> ( KDecimalBits + 1 ) );
       
   670 
       
   671             sourceX += iU;
       
   672             }
       
   673 
       
   674         // handle last columns
       
   675         for( ; x < width; x++ )
       
   676             {
       
   677             TUint32 x0 = sourceX >> KDecimalBits;
       
   678 
       
   679             if( x0 != x0prev )
       
   680                 {
       
   681                 TUint32 p0 = *( s + x0 );
       
   682                 b01 = b00 = UNPACK_16MU_BLUE( p0 );
       
   683                 g01 = g00 = UNPACK_16MU_GREEN( p0 );
       
   684                 r01 = r00 = UNPACK_16MU_RED( p0 );
       
   685 
       
   686                 p0 = *( snext + x0 );
       
   687                 b10 = UNPACK_16MU_BLUE( p0 );
       
   688                 g10 = UNPACK_16MU_GREEN( p0 );
       
   689                 r10 = UNPACK_16MU_RED( p0 );
       
   690 
       
   691                 x0prev = x0;
       
   692                 }
       
   693 
       
   694             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal
       
   695             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   696 
       
   697             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   698             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   699             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   700 
       
   701             *t++ = PACK_16MU_BGR(
       
   702                 bres >> ( KDecimalBits + 1 ),
       
   703                 gres >> ( KDecimalBits + 1 ),
       
   704                 rres >> ( KDecimalBits + 1 ) );
       
   705 
       
   706             sourceX += iU;
       
   707             }
       
   708 
       
   709         sourceY += iV;
       
   710         }
       
   711     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale16MU() <<" ), RThread().Id().operator TUint() ) );
       
   712     }
       
   713 
       
   714 // -----------------------------------------------------------------------------
       
   715 // CVtImageScalerImplWeightedAverage::Scale16MA()
       
   716 // -----------------------------------------------------------------------------
       
   717 void CVtImageScalerImplWeightedAverage::Scale16MA()
       
   718     {
       
   719     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale16MA() >>" ), RThread().Id().operator TUint() ) );
       
   720 
       
   721     TInt width = iTarget->Size().iWidth;
       
   722 
       
   723     TInt height = iTarget->Size().iHeight;
       
   724 
       
   725     TInt mod_width = width - ( ( 1 << KDecimalBits ) / iU );
       
   726 
       
   727     TUint32* t = iTarget->DataAddress();
       
   728 
       
   729     TUint32 sourceY( 0 );
       
   730 
       
   731     TUint32 a00( 0 );
       
   732     TUint32 b00( 0 );
       
   733     TUint32 g00( 0 );
       
   734     TUint32 r00( 0 );
       
   735     TUint32 a01( 0 );
       
   736     TUint32 b01( 0 );
       
   737     TUint32 g01( 0 );
       
   738     TUint32 r01( 0 );
       
   739     TUint32 a10( 0 );
       
   740     TUint32 b10( 0 );
       
   741     TUint32 g10( 0 );
       
   742     TUint32 r10( 0 );
       
   743 
       
   744     for( TInt y = 0; y < height; y++ )
       
   745         {
       
   746         TUint32* s = iSource->LineAddress( sourceY >> KDecimalBits );
       
   747         TUint32* snext = iSource->LineAddress( ( sourceY >> KDecimalBits ) + 1 );
       
   748 
       
   749         TUint32 invdv = sourceY & ( ( 1 << KDecimalBits ) - 1 ); // decimal part
       
   750         TUint32 dv = ( 1 << KDecimalBits ) - invdv; // 1 - decimal part
       
   751 
       
   752         TUint32 sourceX( 0 );
       
   753 
       
   754         TInt x;
       
   755 
       
   756         TUint32 x0prev( TUint32( -1 ) );
       
   757 
       
   758         for( x = 0; x < mod_width; x++ )
       
   759             {
       
   760             TUint32 x0 = sourceX >> KDecimalBits;
       
   761 
       
   762             if( x0 != x0prev )
       
   763                 {
       
   764                 TUint32 p0 = *( s + x0 );
       
   765 
       
   766                 a00 = UNPACK_16MA_ALPHA( p0 );
       
   767                 b00 = UNPACK_16MA_BLUE( p0 );
       
   768                 g00 = UNPACK_16MA_GREEN( p0 );
       
   769                 r00 = UNPACK_16MA_RED( p0 );
       
   770 
       
   771                 p0 = *( s + x0 + 1 );
       
   772 
       
   773                 a01 = UNPACK_16MA_ALPHA( p0 );
       
   774                 b01 = UNPACK_16MA_BLUE( p0 );
       
   775                 g01 = UNPACK_16MA_GREEN( p0 );
       
   776                 r01 = UNPACK_16MA_RED( p0 );
       
   777 
       
   778                 p0 = *( snext + x0 );
       
   779 
       
   780                 a10 = UNPACK_16MA_ALPHA( p0 );
       
   781                 b10 = UNPACK_16MA_BLUE( p0 );
       
   782                 g10 = UNPACK_16MA_GREEN( p0 );
       
   783                 r10 = UNPACK_16MA_RED( p0 );
       
   784 
       
   785                 x0prev = x0;
       
   786                 }
       
   787 
       
   788             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 );
       
   789             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   790 
       
   791             TUint32 ares = ( du + dv ) * a00 + invdu * a01 + invdv * a10;
       
   792             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   793             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   794             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   795 
       
   796             *t++ = PACK_16MA_ABGR(
       
   797                 ares >> ( KDecimalBits + 1 ),
       
   798                 bres >> ( KDecimalBits + 1 ),
       
   799                 gres >> ( KDecimalBits + 1 ),
       
   800                 rres >> ( KDecimalBits + 1 ) );
       
   801 
       
   802             sourceX += iU;
       
   803             }
       
   804 
       
   805         // handle last columns
       
   806         for( ; x < width; x++ )
       
   807             {
       
   808             TUint32 x0 = sourceX >> KDecimalBits;
       
   809 
       
   810             if( x0 != x0prev )
       
   811                 {
       
   812                 TUint32 p0 = *( s + x0 );
       
   813                 a01 = a00 = UNPACK_16MA_ALPHA( p0 );
       
   814                 b01 = b00 = UNPACK_16MA_BLUE( p0 );
       
   815                 g01 = g00 = UNPACK_16MA_GREEN( p0 );
       
   816                 r01 = r00 = UNPACK_16MA_RED( p0 );
       
   817 
       
   818                 p0 = *( snext + x0 );
       
   819                 a10 = UNPACK_16MA_ALPHA( p0 );
       
   820                 b10 = UNPACK_16MA_BLUE( p0 );
       
   821                 g10 = UNPACK_16MA_GREEN( p0 );
       
   822                 r10 = UNPACK_16MA_RED( p0 );
       
   823 
       
   824                 x0prev = x0;
       
   825                 }
       
   826 
       
   827             TUint32 invdu = sourceX & ( ( 1 << KDecimalBits ) - 1 ); // decimal
       
   828             TUint32 du = ( 1 << KDecimalBits ) - invdu; // 1 - decimal part
       
   829 
       
   830             TUint32 ares = ( du + dv ) * a00 + invdu * a01 + invdv * a10;
       
   831             TUint32 bres = ( du + dv ) * b00 + invdu * b01 + invdv * b10;
       
   832             TUint32 gres = ( du + dv ) * g00 + invdu * g01 + invdv * g10;
       
   833             TUint32 rres = ( du + dv ) * r00 + invdu * r01 + invdv * r10;
       
   834 
       
   835             *t++ = PACK_16MA_ABGR(
       
   836                 ares >> ( KDecimalBits + 1 ),
       
   837                 bres >> ( KDecimalBits + 1 ),
       
   838                 gres >> ( KDecimalBits + 1 ),
       
   839                 rres >> ( KDecimalBits + 1 ) );
       
   840 
       
   841             sourceX += iU;
       
   842             }
       
   843 
       
   844         sourceY += iV;
       
   845         }
       
   846     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale16MA() <<" ), RThread().Id().operator TUint() ) );
       
   847     }
       
   848 
       
   849 // -----------------------------------------------------------------------------
       
   850 // CVtImageScalerImplWeightedAverage::Scale2x4K64K( TUint32 aMask )
       
   851 // -----------------------------------------------------------------------------
       
   852 void CVtImageScalerImplWeightedAverage::Scale2x4K64K( TUint32 aMask )
       
   853     {
       
   854     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale2x4K64K() >>" ), RThread().Id().operator TUint() ) );
       
   855 
       
   856     TInt sheight = iSource->Size().iHeight;
       
   857     TInt swidth = iSource->Size().iWidth;
       
   858     TInt spitch = iSource->BytesPerRow();
       
   859     TInt dpitch = iTarget->BytesPerRow();
       
   860 
       
   861     TUint32* s = iSource->DataAddress();
       
   862     TUint32* d = iTarget->DataAddress();
       
   863     TInt y;
       
   864 
       
   865     // first average source rows
       
   866     for( y = 0; y < sheight; y++ )
       
   867         {
       
   868         TUint32* s1 = s;
       
   869         TUint32* d1 = d;
       
   870 
       
   871         TUint32 p = *s1++; // 2 pixels
       
   872         TUint32 p1 = p & 0xffff;
       
   873         TUint32 p2 = ( p >> 16 ) & 0xffff;
       
   874         TInt x;
       
   875 
       
   876         for( x = 0; x < swidth/2 - 1; x++ )
       
   877             {
       
   878             TUint32 p1a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 );
       
   879             p1a = ( ( ( p1 ^ p1a ) & aMask ) >> 1 ) + ( p1 & p1a );
       
   880             *d1++ = p1 | ( p1a << 16 );
       
   881 
       
   882             p = *s1++; // 2 pixels
       
   883 
       
   884             p1 = p & 0xffff;
       
   885             TUint32 p2a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 );
       
   886             p2a = ( ( ( p2a ^ p2 ) & aMask ) >> 1 ) + ( p2a & p2 );
       
   887             *d1++ = p2 | ( p2a << 16 );
       
   888 
       
   889             p2 = ( p >> 16 ) & 0xffff;
       
   890             }
       
   891 
       
   892         TUint32 p1a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 );
       
   893         p1a = ( ( ( p1 ^ p1a ) & aMask ) >> 1 ) + ( p1 & p1a );
       
   894         *d1++ = p1 | ( p1a << 16 );
       
   895 
       
   896         if( swidth & 1 )
       
   897             {
       
   898             p = *s1; // 2 pixels
       
   899             p1 = p & 0xffff;
       
   900             TUint32 p2a = ( ( ( p1 ^ p2 ) & aMask ) >> 1 ) + ( p1 & p2 );
       
   901             p2a = ( ( ( p2a ^ p2 ) & aMask ) >> 1 ) + ( p2a & p2 );
       
   902             *d1++ = p2 | ( p2a << 16 );
       
   903 
       
   904             p = *--s1; // 2 pixels
       
   905             p2 = ( p >> 16 ) & 0xffff;
       
   906             *d1++ = p1 | ( p1 << 16 );
       
   907             }
       
   908         else
       
   909             {
       
   910             p = *--s1; // 2 pixels
       
   911             p2 = ( p >> 16 ) & 0xffff;
       
   912             *d1++ = p2 | ( p2 << 16 );
       
   913             }
       
   914 
       
   915         d = reinterpret_cast< TUint32* >
       
   916             ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 );
       
   917         s = reinterpret_cast< TUint32* >
       
   918             ( reinterpret_cast< TUint8* >( s ) + spitch );
       
   919         }
       
   920 
       
   921     // then average rows between
       
   922     d = iTarget->DataAddress();
       
   923 
       
   924     for( y = 0; y < sheight - 1; y++ )
       
   925         {
       
   926         TUint32* d1 = reinterpret_cast< TUint32* >( d );
       
   927         TUint32* d2 = reinterpret_cast< TUint32* >
       
   928             ( reinterpret_cast< TUint8* >( d1 ) + dpitch );
       
   929         TUint32* d3 = reinterpret_cast< TUint32* >
       
   930             ( reinterpret_cast< TUint8* >( d2 ) + dpitch );
       
   931 
       
   932         TUint32 p1 = *d1++;
       
   933         for( TInt x = 0; x < swidth - 1; x++ )
       
   934             {
       
   935             TUint32 p11 = p1 & 0xffff;
       
   936             TUint32 p3 = *d3++;
       
   937             TUint32 p31 = p3 & 0xffff;
       
   938 
       
   939             TUint32 r1 = ( ( ( p11 ^ p31 ) & aMask ) >> 1 ) + ( p11 & p31 );
       
   940             r1 = ( ( ( p11 ^ r1 ) & aMask ) >> 1 ) + ( p11 & r1 );
       
   941 
       
   942             p1 = *d1++; // read ahead
       
   943             TUint32 p21 = p1 & 0xffff;
       
   944             TUint32 r2 = ( ( ( p21 ^ p31 ) & aMask ) >> 1 ) + ( p21 & p31 );
       
   945             r2 = ( ( ( p11 ^ r2 ) & aMask ) >> 1 ) + ( p11 & r2 );
       
   946 
       
   947             *d2++ = r1 | ( r2 << 16 );
       
   948             }
       
   949 
       
   950         TUint32 p11 = p1 & 0xffff;
       
   951         TUint32 p3 = *d3++;
       
   952         TUint32 p31 = p3 & 0xffff;
       
   953         TUint32 r1 = ( ( ( p11 ^ p31 ) & aMask ) >> 1 ) + ( p11 & p31 );
       
   954         r1 = ( ( ( p11 ^ r1 ) & aMask ) >> 1 ) + ( p11 & r1 );
       
   955         *d2++ = r1 | ( r1 << 16 );
       
   956 
       
   957         d = reinterpret_cast< TUint32* >
       
   958             ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 );
       
   959         }
       
   960 
       
   961     // last row is just copy of previous row, because we cannot calculate
       
   962     // average
       
   963     Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch );
       
   964 
       
   965     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale2x4K64K() <<" ), RThread().Id().operator TUint() ) );
       
   966     }
       
   967 
       
   968 // -----------------------------------------------------------------------------
       
   969 // CVtImageScalerImplWeightedAverage::Scale2x16M()
       
   970 // -----------------------------------------------------------------------------
       
   971 void CVtImageScalerImplWeightedAverage::Scale2x16M()
       
   972     {
       
   973     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale2x16M() >>" ), RThread().Id().operator TUint() ) );
       
   974 
       
   975     TInt sheight = iSource->Size().iHeight;
       
   976     TInt swidth = iSource->Size().iWidth;
       
   977     TInt spitch = iSource->BytesPerRow();
       
   978     TInt dpitch = iTarget->BytesPerRow();
       
   979 
       
   980     TUint8* s = reinterpret_cast< TUint8* >( iSource->DataAddress() );
       
   981     TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
       
   982 
       
   983     TInt y;
       
   984 
       
   985     for( y = 0; y < sheight; y++ )
       
   986         {
       
   987         TUint8* s2 = s;
       
   988         TUint8* d1 = d;
       
   989 
       
   990         TUint32 g1 = 0;
       
   991         TUint32 b1 = 0;
       
   992         TUint32 r1 = 0;
       
   993 
       
   994         TUint32 g2 = 0;
       
   995         TUint32 b2 = 0;
       
   996         TUint32 r2 = 0;
       
   997 
       
   998         for( TInt x = 0; x < swidth - 1; x++ )
       
   999             {
       
  1000             g1 = *s2++;
       
  1001             b1 = *s2++;
       
  1002             r1 = *s2++;
       
  1003 
       
  1004             *d1++ = static_cast< TUint8 >( g1 );
       
  1005             *d1++ = static_cast< TUint8 >( b1 );
       
  1006             *d1++ = static_cast< TUint8 >( r1 );
       
  1007 
       
  1008             g2 = s2[ 0 ];
       
  1009             b2 = s2[ 1 ];
       
  1010             r2 = s2[ 2 ];
       
  1011 
       
  1012             *d1++ = static_cast< TUint8 >( ( g1 + ( ( g1 + g2 ) >> 1 ) ) >> 1 );
       
  1013             *d1++ = static_cast< TUint8 >( ( b1 + ( ( b1 + b2 ) >> 1 ) ) >> 1 );
       
  1014             *d1++ = static_cast< TUint8 >( ( r1 + ( ( r1 + r2 ) >> 1 ) ) >> 1 );
       
  1015             }
       
  1016 
       
  1017         *d1++ = static_cast< TUint8 >( ( g1 + g2 ) >> 1 );
       
  1018         *d1++ = static_cast< TUint8 >( ( b1 + b2 ) >> 1 );
       
  1019         *d1++ = static_cast< TUint8 >( ( r1 + r2 ) >> 1 );
       
  1020 
       
  1021         *d1++ = static_cast< TUint8 >( g2 );
       
  1022         *d1++ = static_cast< TUint8 >( b2 );
       
  1023         *d1++ = static_cast< TUint8 >( r2 );
       
  1024 
       
  1025         d += dpitch * 2;
       
  1026         s += spitch;
       
  1027         }
       
  1028 
       
  1029     // then average rows between
       
  1030     d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
       
  1031 
       
  1032     for( y = 0; y < sheight - 1; y++ )
       
  1033         {
       
  1034         TUint8* d1 = d;
       
  1035         TUint8* d2 = d1 + dpitch;
       
  1036         TUint8* d3 = d2 + dpitch;
       
  1037 
       
  1038         for( TInt x = 0; x < swidth; x++ )
       
  1039             {
       
  1040             TUint32 g1 = *d1++;
       
  1041             TUint32 g2 = *d3++;
       
  1042             *d2++ = static_cast< TUint8 >( ( g1 + g2 ) >> 1 );
       
  1043 
       
  1044             TUint32 b1 = *d1++;
       
  1045             TUint32 b2 = *d3++;
       
  1046             *d2++ = static_cast< TUint8 >( ( b1 + b2 ) >> 1 );
       
  1047 
       
  1048             TUint32 r1 = *d1++;
       
  1049             TUint32 r2 = *d3++;
       
  1050             *d2++ = static_cast< TUint8 >( ( r1 + r2 ) >> 1 );
       
  1051 
       
  1052             g1 = *d1++;
       
  1053             g2 = *d3++;
       
  1054             *d2++ = static_cast< TUint8 >( ( g1 + g2 ) >> 1 );
       
  1055 
       
  1056             b1 = *d1++;
       
  1057             b2 = *d3++;
       
  1058             *d2++ = static_cast< TUint8 >( ( b1 + b2 ) >> 1 );
       
  1059 
       
  1060             r1 = *d1++;
       
  1061             r2 = *d3++;
       
  1062             *d2++ = static_cast< TUint8 >( ( r1 + r2 ) >> 1 );
       
  1063             }
       
  1064 
       
  1065         d += dpitch * 2;
       
  1066         }
       
  1067 
       
  1068     // last row is just copy of previous row, because we cannot calculate
       
  1069     // average
       
  1070     Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch );
       
  1071 
       
  1072     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale2x16M() <<" ), RThread().Id().operator TUint() ) );
       
  1073     }
       
  1074 
       
  1075 // -----------------------------------------------------------------------------
       
  1076 // CVtImageScalerImplWeightedAverage::Scale2x16MU16MA()
       
  1077 // -----------------------------------------------------------------------------
       
  1078 void CVtImageScalerImplWeightedAverage::Scale2x16MU16MA()
       
  1079     {
       
  1080     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale2x16MU16MA() >>" ), RThread().Id().operator TUint() ) );
       
  1081 
       
  1082     TInt sheight = iSource->Size().iHeight;
       
  1083     TInt swidth = iSource->Size().iWidth;
       
  1084     TInt spitch = iSource->BytesPerRow();
       
  1085     TInt dpitch = iTarget->BytesPerRow();
       
  1086 
       
  1087     TUint32 mask = 0xfefefefe;
       
  1088     TUint32* s = iSource->DataAddress();
       
  1089     TUint32* d = iTarget->DataAddress();
       
  1090     TInt y;
       
  1091 
       
  1092     // first average source rows
       
  1093     for( y = 0; y < sheight; y++ )
       
  1094         {
       
  1095         TInt x;
       
  1096         TUint32* s1 = s;
       
  1097         TUint32* d1 = d;
       
  1098         TUint32 p2 = *s1++;
       
  1099         TUint32 p1 = 0;
       
  1100         for( x = 0; x < swidth - 1; x++ )
       
  1101             {
       
  1102             p1 = p2;
       
  1103             *d1++ = p1;
       
  1104             p2 = *s1++;
       
  1105             TUint32 p1a = ( ( ( p1 ^ p2 ) & mask ) >> 1 ) + ( p1 & p2 );
       
  1106             p1a = ( ( ( p1 ^ p1a ) & mask ) >> 1 ) + ( p1 & p1a );
       
  1107             *d1++ = p1a;
       
  1108             }
       
  1109 
       
  1110         if( swidth & 1 )
       
  1111             {
       
  1112             TUint32 p2a = ( ( ( p1 ^ p2 ) & mask ) >> 1 ) + ( p1 & p2 );
       
  1113             p2a = ( ( ( p2a ^ p2 ) & mask ) >> 1 ) + ( p2a & p2 );
       
  1114             *d1++ = p2a;
       
  1115             *d1++ = p2;
       
  1116             }
       
  1117         else
       
  1118             {
       
  1119             p2 = *--s1;
       
  1120             *d1++ = p2;
       
  1121             *d1++ = p2;
       
  1122             }
       
  1123 
       
  1124         d = reinterpret_cast< TUint32* >
       
  1125             ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 );
       
  1126         s = reinterpret_cast< TUint32* >
       
  1127             ( reinterpret_cast< TUint8* >( s ) + spitch );
       
  1128         }
       
  1129 
       
  1130     // then average rows between
       
  1131     d = iTarget->DataAddress();
       
  1132 
       
  1133     for( y = 0; y < sheight - 1; y++ )
       
  1134         {
       
  1135         TUint32* d1 = reinterpret_cast< TUint32* >( d );
       
  1136         TUint32* d2 = reinterpret_cast< TUint32* >
       
  1137             ( reinterpret_cast< TUint8* >( d1 ) + dpitch );
       
  1138         TUint32* d3 = reinterpret_cast< TUint32* >
       
  1139             ( reinterpret_cast< TUint8* >( d2 ) + dpitch );
       
  1140 
       
  1141         TUint32 p1 = *d1++;
       
  1142 
       
  1143         for( TInt x = 0; x < swidth - 1; x++ )
       
  1144             {
       
  1145             TUint32 p3 = *d3++;
       
  1146             d3++;
       
  1147 
       
  1148             TUint32 r1 = ( ( ( p1 ^ p3 ) & mask ) >> 1 ) + ( p1 & p3 );
       
  1149             r1 = ( ( ( p1 ^ r1 ) & mask ) >> 1 ) + ( p1 & r1 );
       
  1150 
       
  1151             *d2++ = r1;
       
  1152 
       
  1153             d1++;
       
  1154             TUint32 p2 = *d1++;
       
  1155 
       
  1156             TUint32 r2 = ( ( ( p2 ^ p3 ) & mask ) >> 1 ) + ( p2 & p3 );
       
  1157             r2 = ( ( ( p1 ^ r2 ) & mask ) >> 1 ) + ( p1 & r2 );
       
  1158 
       
  1159             *d2++ = r2;
       
  1160 
       
  1161             p1 = p2;
       
  1162             }
       
  1163 
       
  1164         TUint32 p3 = *d3++;
       
  1165         TUint32 r1 = ( ( ( p1 ^ p3 ) & mask ) >> 1 ) + ( p1 & p3 );
       
  1166         r1 = ( ( ( p1 ^ r1 ) & mask ) >> 1 ) + ( p1 & r1 );
       
  1167         *d2++ = r1;
       
  1168         *d2++ = r1;
       
  1169 
       
  1170         d = reinterpret_cast< TUint32* >
       
  1171             ( reinterpret_cast< TUint8* >( d ) + dpitch * 2 );
       
  1172         }
       
  1173 
       
  1174     // last row is just copy of previous row, because we cannot calculate
       
  1175     // average
       
  1176     Mem::Copy( reinterpret_cast< TUint8* >( d ) + dpitch, d, dpitch );
       
  1177 
       
  1178     __IF_DEBUG( Print( _L( "ImageScaler [%d]: CVtImageScalerImplWeightedAverage::Scale2x16MU16MA() <<" ), RThread().Id().operator TUint() ) );
       
  1179     }
       
  1180 
       
  1181 // End of File
       
  1182 
       
  1183