vtprotocolplugins/DisplaySink/src/CVtImageRotatorImplMirrorFlip.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 "CVtImageRotatorImplMirrorFlip.h"
       
    25 #include "cvtimage.h"
       
    26 #include "CVtImageIYUV.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 // ============================ MEMBER FUNCTIONS ===============================
       
    39 
       
    40 // ======================= CVtImageRotatorImplMirrorFlip =======================
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CVtImageRotatorImplMirrorFlip::CVtImageRotatorImplMirrorFlip(
       
    44 //  const CVtImageRotator::TRotationAngle& aAngle )
       
    45 // -----------------------------------------------------------------------------
       
    46 CVtImageRotatorImplMirrorFlip::CVtImageRotatorImplMirrorFlip(
       
    47     const CVtImageRotator::TRotationAngle& aAngle ) : CVtImageRotatorImpl( aAngle )
       
    48     {
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CVtImageRotatorImplMirrorFlip::Rotate( TBool& aContinue )
       
    53 // -----------------------------------------------------------------------------
       
    54 TInt CVtImageRotatorImplMirrorFlip::Rotate( TBool& aContinue )
       
    55     {
       
    56     __IF_DEBUG( Print( _L( "ImageRotator [%d]: CVtImageRotatorImplMirrorFlip::Rotate() >>" ), RThread().Id().operator TUint() ) );
       
    57 
       
    58     TInt result( KErrNone );
       
    59 
       
    60     aContinue = EFalse;
       
    61 
       
    62     TBool isSameBitmap( iSource->DataAddress() == iTarget->DataAddress() );
       
    63 
       
    64     if( iAngle == CVtImageRotator::EFlipVerticalAxis )
       
    65         {
       
    66         // Are source and target referencing same bitmap?
       
    67         if( isSameBitmap  )
       
    68             {
       
    69             // YES: Flip inside bitmap
       
    70             Flip( *iTarget );
       
    71             }
       
    72         else
       
    73             {
       
    74             // NO: Use flipping from source to target
       
    75             Flip();
       
    76             }
       
    77         }
       
    78     else if( iAngle == CVtImageRotator::EMirrorHorizontalAxis )
       
    79         {
       
    80         // Are source and target referencing same bitmap?
       
    81         if( isSameBitmap )
       
    82             {
       
    83             // YES: Mirror inside bitmap
       
    84             Mirror( *iTarget );
       
    85             }
       
    86         else
       
    87             {
       
    88             // NO: Mirror from source to target
       
    89             Mirror();
       
    90             }
       
    91         }
       
    92     else if( iAngle == CVtImageRotator::E180DegreesClockwise )
       
    93         {
       
    94         // Are source and target referencing same bitmap?
       
    95         if( isSameBitmap )
       
    96             {
       
    97             // YES: Mirror inside bitmap
       
    98             Mirror( *iTarget );
       
    99             }
       
   100         else
       
   101             {
       
   102             // NO: Mirror from source to target
       
   103             Mirror();
       
   104             }
       
   105         Flip( *iTarget );
       
   106         }
       
   107 
       
   108     __IF_DEBUG( Print( _L( "ImageRotator [%d]: CVtImageRotatorImplMirrorFlip::Rotate() <<" ), RThread().Id().operator TUint() ) );
       
   109 
       
   110     return result;
       
   111     }
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // CVtImageRotatorImplMirrorFlip::ValidateSourceTargetL(
       
   115 //  const CVtImage& aSource, CVtImage& aTarget )
       
   116 // -----------------------------------------------------------------------------
       
   117 void CVtImageRotatorImplMirrorFlip::ValidateSourceTargetL(
       
   118     const CVtImage& aSource,
       
   119     CVtImage& aTarget )
       
   120     {
       
   121 
       
   122 
       
   123     // Sizes must match
       
   124     if( aSource.Size() != aTarget.Size() )
       
   125         {
       
   126         User::Leave( KErrNotSupported );
       
   127         }
       
   128 
       
   129     // Displaymodes must match
       
   130     if( aSource.DisplayMode() != aTarget.DisplayMode() )
       
   131         {
       
   132         User::Leave( KErrNotSupported );
       
   133         }
       
   134 
       
   135     // Check that displaymode is one of the supported
       
   136     switch( aSource.DisplayMode() )
       
   137         {
       
   138         case CVtImage::EVtColor4K:
       
   139         case CVtImage::EVtColor64K:
       
   140         case CVtImage::EVtColor16M:
       
   141         case CVtImage::EVtColor16MU:
       
   142         case CVtImage::EVtColor16MA:
       
   143         case CVtImage::EVtColorIYUV:
       
   144             break;
       
   145 
       
   146         default:
       
   147             User::Leave( KErrNotSupported );
       
   148         }
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // CVtImageRotatorImplMirrorFlip::ValidateSourceTargetL(
       
   153 //  const CVtImage& aSource, CVtImage& aTarget )
       
   154 // -----------------------------------------------------------------------------
       
   155 TBool CVtImageRotatorImplMirrorFlip::SupportsRotationAngle(
       
   156     const CVtImageRotator::TRotationAngle& aAngle )
       
   157     {
       
   158     TBool result( EFalse );
       
   159 
       
   160     if( ( aAngle == CVtImageRotator::EMirrorHorizontalAxis ) ||
       
   161         ( aAngle == CVtImageRotator::EFlipVerticalAxis ) ||
       
   162         ( aAngle == CVtImageRotator::E180DegreesClockwise ) )
       
   163         {
       
   164         result = ETrue;
       
   165         }
       
   166 
       
   167     return result;
       
   168     }
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CVtImageRotatorImplMirrorFlip::Mirror()
       
   172 // -----------------------------------------------------------------------------
       
   173 void CVtImageRotatorImplMirrorFlip::Mirror()
       
   174     {
       
   175     TInt bytesPerRow( iSource->BytesPerRow() );
       
   176 
       
   177     TInt height( iSource->Size().iHeight );
       
   178 
       
   179     TInt width( iSource->Size().iWidth );
       
   180 
       
   181     switch( iSource->DisplayMode() )
       
   182         {
       
   183         // DisplayMode: 4K and 64K
       
   184         case CVtImage::EVtColor4K:
       
   185         case CVtImage::EVtColor64K:
       
   186             {
       
   187             const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
       
   188 
       
   189             TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
       
   190 
       
   191             d += bytesPerRow;
       
   192 
       
   193             if( width & 1 )
       
   194                 {
       
   195                 d -= 2;
       
   196                 }
       
   197 
       
   198             for( TInt y = height - 1; y >= 0; y-- )
       
   199                 {
       
   200                 register const TUint16* tempS = reinterpret_cast< const TUint16* >( s );
       
   201 
       
   202                 register TUint16* tempD = reinterpret_cast< TUint16* >( d );
       
   203 
       
   204                 for( register TInt x = width - 1; x >= 0; x-- )
       
   205                     {
       
   206                     *--tempD = *tempS++;
       
   207                     }
       
   208 
       
   209                 s += bytesPerRow;
       
   210 
       
   211                 d += bytesPerRow;
       
   212                 }
       
   213             }
       
   214             break;
       
   215 
       
   216         // DisplayMode: 16M
       
   217         case CVtImage::EVtColor16M:
       
   218             {
       
   219             const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
       
   220 
       
   221             TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
       
   222 
       
   223             d += width * 3;
       
   224 
       
   225             for( TInt y = height - 1; y >= 0; y-- )
       
   226                 {
       
   227                 const TUint8* tempS = s;
       
   228 
       
   229                 TUint8* tempD = d - 3;
       
   230 
       
   231                 for( TInt x = width - 1; x >= 0; x-- )
       
   232                     {
       
   233                     tempD[ 0 ] = *tempS++;
       
   234                     tempD[ 1 ] = *tempS++;
       
   235                     tempD[ 2 ] = *tempS++;
       
   236                     tempD -= 3;
       
   237                     }
       
   238 
       
   239                 s += bytesPerRow;
       
   240 
       
   241                 d += bytesPerRow;
       
   242                 }
       
   243             }
       
   244             break;
       
   245 
       
   246         // DisplayMode: 16MU and 16MA
       
   247         case CVtImage::EVtColor16MU:
       
   248         case CVtImage::EVtColor16MA:
       
   249             {
       
   250             const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
       
   251 
       
   252             TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
       
   253 
       
   254             d += bytesPerRow;
       
   255 
       
   256             for( TInt y = height - 1; y >= 0; y-- )
       
   257                 {
       
   258                 register const TUint32* tempS = reinterpret_cast< const TUint32* >( s );
       
   259                 register TUint32* tempD = reinterpret_cast< TUint32* >( d );
       
   260 
       
   261                 for( TInt x = width - 1; x >= 0; x-- )
       
   262                     {
       
   263                     *--tempD = *tempS++;
       
   264                     }
       
   265 
       
   266                 s += bytesPerRow;
       
   267 
       
   268                 d += bytesPerRow;
       
   269                 }
       
   270             }
       
   271             break;
       
   272 
       
   273         // IYUV
       
   274         case CVtImage::EVtColorIYUV:
       
   275             MirrorIYUV( reinterpret_cast< const CVtImageIYUV& >( *iSource ), reinterpret_cast< CVtImageIYUV& >( *iTarget ) );
       
   276             break;
       
   277 
       
   278         default:
       
   279             break;
       
   280 
       
   281         }
       
   282     }
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // CVtImageRotatorImplMirrorFlip::Mirror( CVtImage& aTarget )
       
   286 // -----------------------------------------------------------------------------
       
   287 void CVtImageRotatorImplMirrorFlip::Mirror( CVtImage& aTarget )
       
   288     {
       
   289     TInt bytesPerRow( aTarget.BytesPerRow() );
       
   290 
       
   291     TInt height( aTarget.Size().iHeight );
       
   292 
       
   293     TInt width( aTarget.Size().iWidth );
       
   294 
       
   295     switch( aTarget.DisplayMode() )
       
   296         {
       
   297         // DisplayMode: 4K and 64K
       
   298         case CVtImage::EVtColor4K:
       
   299         case CVtImage::EVtColor64K:
       
   300             {
       
   301             TUint8* d = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
       
   302 
       
   303             TUint8* s = reinterpret_cast< TUint8* >( d );
       
   304 
       
   305             d += bytesPerRow;
       
   306 
       
   307             if( width & 1 )
       
   308                 {
       
   309                 d -= 2;
       
   310                 }
       
   311 
       
   312             for( TInt y = height - 1; y >= 0; y-- )
       
   313                 {
       
   314                 register TUint16* tempS = reinterpret_cast< TUint16* >( s );
       
   315 
       
   316                 register TUint16* tempD = reinterpret_cast< TUint16* >( d );
       
   317 
       
   318                 for( register TInt x = width/2 - 1; x >= 0; x-- )
       
   319                     {
       
   320                     TUint16 p = *tempS;
       
   321                     *tempS++ = *--tempD;
       
   322                     *tempD = p;
       
   323                     }
       
   324 
       
   325                 s += bytesPerRow;
       
   326 
       
   327                 d += bytesPerRow;
       
   328                 }
       
   329             }
       
   330             break;
       
   331 
       
   332         // DisplayMode: 16M
       
   333         case CVtImage::EVtColor16M:
       
   334             {
       
   335             TUint8* d = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
       
   336 
       
   337             TUint8* s = reinterpret_cast< TUint8* >( d );
       
   338 
       
   339             d += width * 3;
       
   340 
       
   341             for( TInt y = height - 1; y >= 0; y-- )
       
   342                 {
       
   343                 TUint8* tempS = s;
       
   344 
       
   345                 TUint8* tempD = d - 3;
       
   346 
       
   347                 for( TInt x = width/2 - 1; x >= 0; x-- )
       
   348                     {
       
   349                     TUint8 s = *tempS;
       
   350                     TUint8 t = *tempD;
       
   351                     *tempD++ = s;
       
   352                     *tempS++ = t;
       
   353 
       
   354                     s = *tempS;
       
   355                     t = *tempD;
       
   356                     *tempD++ = s;
       
   357                     *tempS++ = t;
       
   358 
       
   359                     s = *tempS;
       
   360                     t = *tempD;
       
   361                     *tempD++ = s;
       
   362                     *tempS++ = t;
       
   363 
       
   364                     tempD -= 6;
       
   365                     }
       
   366 
       
   367                 s += bytesPerRow;
       
   368 
       
   369                 d += bytesPerRow;
       
   370                 }
       
   371             }
       
   372             break;
       
   373 
       
   374         // DisplayMode: 16MU and 16MA
       
   375         case CVtImage::EVtColor16MU:
       
   376         case CVtImage::EVtColor16MA:
       
   377             {
       
   378             TUint8* d = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
       
   379 
       
   380             TUint8* s = reinterpret_cast< TUint8* >( d );
       
   381 
       
   382             d += bytesPerRow;
       
   383 
       
   384             for( TInt y = height - 1; y >= 0; y-- )
       
   385                 {
       
   386                 register TUint32* tempS = reinterpret_cast< TUint32* >( s );
       
   387                 register TUint32* tempD = reinterpret_cast< TUint32* >( d );
       
   388 
       
   389                 for( TInt x = width/2 - 1; x >= 0; x-- )
       
   390                     {
       
   391                     TUint32 p = *tempS;
       
   392                     *tempS++ = *--tempD;
       
   393                     *tempD = p;
       
   394                     }
       
   395 
       
   396                 s += bytesPerRow;
       
   397 
       
   398                 d += bytesPerRow;
       
   399                 }
       
   400             }
       
   401             break;
       
   402 
       
   403         // IYUV
       
   404         case CVtImage::EVtColorIYUV:
       
   405             MirrorIYUV( reinterpret_cast< const CVtImageIYUV& >( aTarget ), reinterpret_cast< CVtImageIYUV& >( aTarget ) );
       
   406             break;
       
   407 
       
   408         default:
       
   409             break;
       
   410 
       
   411         }
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CVtImageRotatorImplMirrorFlip::MirrorIYUV( const CVtImageIYUV& aSource,
       
   416 //  CVtImageIYUV& aTarget )
       
   417 // -----------------------------------------------------------------------------
       
   418 void CVtImageRotatorImplMirrorFlip::MirrorIYUV( const CVtImageIYUV& aSource,
       
   419     CVtImageIYUV& aTarget )
       
   420     {
       
   421     MirrorPlane( aSource.Y(), aTarget.Y(), aSource.Size().iWidth,
       
   422         aSource.Size().iHeight, aSource.BytesPerRow() );
       
   423     MirrorPlane( aSource.U(), aTarget.U(), aSource.UVPlaneWidth(),
       
   424         aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
       
   425     MirrorPlane( aSource.V(), aTarget.V(), aSource.UVPlaneWidth(),
       
   426         aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
       
   427     }
       
   428 
       
   429 // -----------------------------------------------------------------------------
       
   430 // CVtImageRotatorImplMirrorFlip::MirrorPlane( TUint8* aSource, TUint8* aTarget,
       
   431 //  TInt aWidth, TInt aHeight, TInt aBytesPerRow )
       
   432 // -----------------------------------------------------------------------------
       
   433 void CVtImageRotatorImplMirrorFlip::MirrorPlane( TUint8* aSource,
       
   434     TUint8* aTarget, TInt aWidth, TInt aHeight, TInt aBytesPerRow )
       
   435     {
       
   436     if( aSource != aTarget )
       
   437         {
       
   438         aTarget += aBytesPerRow;
       
   439         for( TInt y = aHeight - 1; y >= 0; y-- )
       
   440             {
       
   441             register const TUint8* tempS = aSource;
       
   442             register TUint8* tempD = aTarget;
       
   443             for( TInt x = aWidth - 1; x >= 0; x-- )
       
   444                 {
       
   445                 *--tempD = *tempS++;
       
   446                 }
       
   447             aSource += aBytesPerRow;
       
   448             aTarget += aBytesPerRow;
       
   449             }
       
   450         }
       
   451     else
       
   452         {
       
   453         aTarget += aBytesPerRow;
       
   454         for( TInt y = aHeight - 1; y >= 0; y-- )
       
   455             {
       
   456             register TUint8* tempS = aSource;
       
   457             register TUint8* tempD = aTarget;
       
   458             for( TInt x = aWidth/2 - 1; x >= 0; x-- )
       
   459                 {
       
   460                 TUint8 p = *tempS;
       
   461                 *tempS++ = *--tempD;
       
   462                 *tempD = p;
       
   463                 }
       
   464             aSource += aBytesPerRow;
       
   465             aTarget += aBytesPerRow;
       
   466             }
       
   467         }
       
   468     }
       
   469 
       
   470 // -----------------------------------------------------------------------------
       
   471 // CVtImageRotatorImplMirrorFlip::Flip()
       
   472 // -----------------------------------------------------------------------------
       
   473 void CVtImageRotatorImplMirrorFlip::Flip()
       
   474     {
       
   475     if( iSource->DisplayMode() == CVtImage::EVtColorIYUV )
       
   476         {
       
   477         FlipIYUV
       
   478             (
       
   479             reinterpret_cast< const CVtImageIYUV& >( *iSource ),
       
   480             reinterpret_cast< CVtImageIYUV& >( *iTarget )
       
   481             );
       
   482         }
       
   483     else
       
   484         {
       
   485         TInt bytesPerRow( iSource->BytesPerRow() );
       
   486 
       
   487         TInt height( iSource->Size().iHeight );
       
   488 
       
   489         const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() );
       
   490 
       
   491         TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() );
       
   492 
       
   493         d += ( height - 1 ) * bytesPerRow;
       
   494 
       
   495         for( TInt y = height - 1; y >= 0; y-- )
       
   496             {
       
   497             Mem::Copy( d, s, bytesPerRow );
       
   498             s += bytesPerRow;
       
   499             d -= bytesPerRow;
       
   500             }
       
   501         }
       
   502     }
       
   503 
       
   504 // -----------------------------------------------------------------------------
       
   505 // CVtImageRotatorImplMirrorFlip::FlipIYUV()
       
   506 // -----------------------------------------------------------------------------
       
   507 void CVtImageRotatorImplMirrorFlip::FlipIYUV
       
   508     (
       
   509     const CVtImageIYUV& aSource,
       
   510     CVtImageIYUV& aTarget
       
   511     )
       
   512     {
       
   513     FlipPlane( aSource.Y(), aTarget.Y(), aSource.Size().iHeight, aSource.BytesPerRow() );
       
   514     FlipPlane( aSource.U(), aTarget.U(), aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
       
   515     FlipPlane( aSource.V(), aTarget.V(), aSource.UVPlaneHeight(), aSource.UVPlaneWidth() );
       
   516     }
       
   517 
       
   518 // -----------------------------------------------------------------------------
       
   519 // CVtImageRotatorImplMirrorFlip::FlipPlane()
       
   520 // -----------------------------------------------------------------------------
       
   521 void CVtImageRotatorImplMirrorFlip::FlipPlane
       
   522     (
       
   523     TUint8* aSource,
       
   524     TUint8* aTarget,
       
   525     TInt aHeight,
       
   526     TInt aBytesPerRow
       
   527     )
       
   528     {
       
   529     TBool doSwap = ( aSource == aTarget );
       
   530 
       
   531     aTarget += ( aHeight - 1 ) * aBytesPerRow;
       
   532 
       
   533     if( doSwap )
       
   534         {
       
   535         for( TInt y = aHeight / 2 - 1; y >= 0; y-- )
       
   536             {
       
   537             Mem::Swap( aTarget, aSource, aBytesPerRow );
       
   538             aSource += aBytesPerRow;
       
   539             aTarget -= aBytesPerRow;
       
   540             }
       
   541         }
       
   542     else
       
   543         {
       
   544         for( TInt y = aHeight - 1; y >= 0; y-- )
       
   545             {
       
   546             Mem::Copy( aTarget, aSource, aBytesPerRow );
       
   547             aSource += aBytesPerRow;
       
   548             aTarget -= aBytesPerRow;
       
   549             }
       
   550         }
       
   551     }
       
   552 
       
   553 // -----------------------------------------------------------------------------
       
   554 // CVtImageRotatorImplMirrorFlip::Flip( CVtImage& aTarget )
       
   555 // -----------------------------------------------------------------------------
       
   556 void CVtImageRotatorImplMirrorFlip::Flip( CVtImage& aTarget )
       
   557     {
       
   558     if( iSource->DisplayMode() == CVtImage::EVtColorIYUV )
       
   559         {
       
   560         FlipIYUV
       
   561             (
       
   562             reinterpret_cast< const CVtImageIYUV& >( aTarget ),
       
   563             reinterpret_cast< CVtImageIYUV& >( aTarget )
       
   564             );
       
   565         }
       
   566     else
       
   567         {
       
   568         TInt bytesPerRow( aTarget.BytesPerRow() );
       
   569 
       
   570         TInt height( aTarget.Size().iHeight );
       
   571 
       
   572         TUint8* s = reinterpret_cast< TUint8* >( aTarget.DataAddress() );
       
   573 
       
   574         TUint8* d = s;
       
   575 
       
   576         d += ( height - 1 ) * bytesPerRow;
       
   577 
       
   578         for( TInt y = height / 2 - 1; y >= 0; y-- )
       
   579             {
       
   580             Mem::Swap( d, s, bytesPerRow );
       
   581             s += bytesPerRow;
       
   582             d -= bytesPerRow;
       
   583             }
       
   584         }
       
   585     }
       
   586 
       
   587 // End of File
       
   588 
       
   589