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