vtprotocolplugins/DisplaySink/src/CVtImageScalerImplBilinear.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 "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