skins/AknSkins/rlpluginsrc/AknsRlEffectPluginNoise.cpp
changeset 0 05e9090e2422
equal deleted inserted replaced
-1:000000000000 0:05e9090e2422
       
     1 /*
       
     2 * Copyright (c) 2004-2008 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:  Adds grayscale noise to bitmap image.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32math.h>
       
    21 
       
    22 #include "AknsRlEffectPluginNoise.h"
       
    23 #include "AknsRlEffectUtil.h"
       
    24 
       
    25 // ===================== TEMPLATED IMPL. OF NOISE ==============================
       
    26 /**
       
    27 * Template implementation of Noise. Type defines the used data type for
       
    28 * iterating over the bitmap data. X, R, G and B define the used pixel color bit
       
    29 * layout.
       
    30 *
       
    31 * Adding the noise works as the uniform noise in Paint Shop Pro (result-wise).
       
    32 *
       
    33 *         Current pixel value
       
    34 *                 |
       
    35 * -127            v               127
       
    36 *  |-------|------+------|--------|
       
    37 *
       
    38 *           \ - - - - - /
       
    39 *         current intensity value
       
    40 *   \ - - - full intensity - - - /
       
    41 *               (255)
       
    42 *
       
    43 * The current color channel value is displaced by random value in range
       
    44 * [-intensity/2, intensity/2]. Intensity value 0 will result in the original
       
    45 * image.
       
    46 */
       
    47 template<class Type,TInt X, TInt R, TInt G, TInt B>
       
    48 class AknsRlEffectNoise
       
    49     {
       
    50     public:
       
    51     //------------------------------------------------------------------------
       
    52     static void Process( const CFbsBitmap& aTarget,
       
    53                          const CFbsBitmap& aSource,
       
    54                          const TInt aSeed,
       
    55                          const TInt aIntensity )
       
    56         {
       
    57         // ScanLineLength returns bytes, but width must match the Type
       
    58         TInt width  = CFbsBitmap::ScanLineLength( aSource.SizeInPixels().iWidth,
       
    59                                                   aSource.DisplayMode() ) / sizeof(Type);
       
    60         TInt height = aSource.SizeInPixels().iHeight;
       
    61 
       
    62         TInt pixelCount = width * height;
       
    63         TInt r,g,b;
       
    64         TInt rnd;
       
    65         TInt64 seed( aSeed );
       
    66 
       
    67         aTarget.LockHeap( ETrue ); // Lock the global bitmap heap
       
    68         Type* dataT = reinterpret_cast<Type*>( aTarget.DataAddress() );
       
    69         Type* dataS = reinterpret_cast<Type*>( aSource.DataAddress() );
       
    70 
       
    71         for( TInt index = 0; index < pixelCount; ++index )
       
    72             {
       
    73             // Note: It is assumed that arithmetic shifting is supported
       
    74             // -> negative values are shifted correctly
       
    75             rnd = (((Math::Rand( seed ) % 256) * aIntensity ) >> 8) - ( aIntensity >> 1 );
       
    76 
       
    77             r = AknsRlRgb<Type,X,R,G,B>::R8(*dataS);
       
    78             g = AknsRlRgb<Type,X,R,G,B>::G8(*dataS);
       
    79             b = AknsRlRgb<Type,X,R,G,B>::B8(*dataS);
       
    80 
       
    81             r = r + rnd;
       
    82             g = g + rnd;
       
    83             b = b + rnd;
       
    84 
       
    85             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
    86             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
    87             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
    88 
       
    89             AknsRlRgb<Type,X,R,G,B>::SetRgb8( dataT, TUint8(r), TUint8(g), TUint8(b) );
       
    90 
       
    91             dataT++;
       
    92             dataS++;
       
    93             }
       
    94 
       
    95         aTarget.UnlockHeap( ETrue ); // Unlock the global bitmap heap
       
    96         }
       
    97     }; // End of AknsRlEffectNoise
       
    98 
       
    99 // ===================== GRAYSCALE IMPL. OF NOISE ==============================
       
   100 class AknsRlEffectNoiseGray
       
   101     {
       
   102     public:
       
   103     //------------------------------------------------------------------------
       
   104     static void Process( const CFbsBitmap& aTarget,
       
   105                          const CFbsBitmap& aSource,
       
   106                          const TInt aSeed,
       
   107                          const TInt aIntensity )
       
   108         {
       
   109         TInt width  = CFbsBitmap::ScanLineLength( aSource.SizeInPixels().iWidth,
       
   110                                                   aSource.DisplayMode() );
       
   111         TInt height = aSource.SizeInPixels().iHeight;
       
   112 
       
   113         TInt pixelCount = width * height;
       
   114         TInt shade, rnd;
       
   115         TInt64 seed( aSeed );
       
   116 
       
   117         aTarget.LockHeap( ETrue ); // Lock the global bitmap heap
       
   118         TUint8* dataT = reinterpret_cast<TUint8*>( aTarget.DataAddress() );
       
   119         TUint8* dataS = reinterpret_cast<TUint8*>( aSource.DataAddress() );
       
   120 
       
   121         for( TInt index = 0; index < pixelCount; ++index )
       
   122             {
       
   123             // Note: It is assumed that arithmetic shifting is supported
       
   124             // -> negative values are shifted correctly
       
   125             rnd = (((Math::Rand( seed ) % 256) * aIntensity ) >> 8) - ( aIntensity >> 1 ); //lint !e702 Arithmetic shifting assumed
       
   126 
       
   127             shade = (*dataS) + rnd;
       
   128 
       
   129             if( shade < 0 )
       
   130                 *dataT = 0;
       
   131             else if( shade > 255 )
       
   132                 *dataT = 255;
       
   133             else
       
   134                 *dataT = TUint8(shade);
       
   135 
       
   136             dataT++;
       
   137             dataS++;
       
   138             }
       
   139 
       
   140         aTarget.UnlockHeap( ETrue ); // Unlock the global bitmap heap
       
   141         }
       
   142     }; // End of AknsRlEffectNoise
       
   143 
       
   144 // ============================ MEMBER FUNCTIONS ===============================
       
   145 
       
   146 // -----------------------------------------------------------------------------
       
   147 // CAknsRlEffectPluginNoise::CAknsRlEffectPluginNoise
       
   148 // C++ default constructor can NOT contain any code, that
       
   149 // might leave.
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 CAknsRlEffectPluginNoise::CAknsRlEffectPluginNoise()
       
   153     {
       
   154     }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // Destructor
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 CAknsRlEffectPluginNoise::~CAknsRlEffectPluginNoise()
       
   161     {
       
   162     iContext = NULL;
       
   163     }
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CAknsRlEffectPluginNoise::EffectUid
       
   167 // -----------------------------------------------------------------------------
       
   168 //
       
   169 TUid CAknsRlEffectPluginNoise::EffectUid() const
       
   170     {
       
   171     return TUid::Uid( KAknsRlEffectPluginNoiseUID );
       
   172     }
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CAknsRlEffectPluginNoise::Effect
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 MAknsRlEffect* CAknsRlEffectPluginNoise::Effect( const TInt aInterface )
       
   179     {
       
   180     if( aInterface == KAknsRlEffectPluginInterfaceEffect )
       
   181         return this;
       
   182     return NULL;
       
   183     }
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // CAknsRlEffectPluginNoise::InitializeL
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 void CAknsRlEffectPluginNoise::InitializeL()
       
   190     {
       
   191     iContext = NULL;
       
   192     }
       
   193 
       
   194 // -----------------------------------------------------------------------------
       
   195 // CAknsRlEffectPluginNoise::Release
       
   196 // -----------------------------------------------------------------------------
       
   197 //
       
   198 void CAknsRlEffectPluginNoise::Release()
       
   199     {
       
   200     }
       
   201 
       
   202 // -----------------------------------------------------------------------------
       
   203 // CAknsRlEffectPluginNoise::ActivateL
       
   204 // -----------------------------------------------------------------------------
       
   205 //
       
   206 void CAknsRlEffectPluginNoise::ActivateL( MAknsRlEffectContext* aContext )
       
   207     {
       
   208     if( !aContext ) // We absolutely need the context
       
   209         {
       
   210         User::Leave( KErrArgument );
       
   211         }
       
   212 
       
   213     iContext = aContext;
       
   214 
       
   215     iSeed = 0;
       
   216     iIntensity = 127;
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CAknsRlEffectPluginNoise::Deactivate
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 void CAknsRlEffectPluginNoise::Deactivate()
       
   224     {
       
   225     }
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CAknsRlEffectPluginNoise::SetParametersL
       
   229 // -----------------------------------------------------------------------------
       
   230 //
       
   231 void CAknsRlEffectPluginNoise::SetParametersL( MAknsRlParameterIterator& aParameters )
       
   232     {
       
   233     // Iterate over available parameters
       
   234     while( aParameters.HasNext() )
       
   235         {
       
   236         const TAknsRlParameterData* param = aParameters.NextL();
       
   237 
       
   238         // Fetch seed value
       
   239         if( param->iName->Compare( KAknsRlEffectNoiseSeed ) == 0 )
       
   240             {
       
   241             if( param->iType != EAknsRlParameterTypeNumber )
       
   242                 User::Leave( KErrArgument );
       
   243 
       
   244             iSeed = param->iNumber;
       
   245             }
       
   246         // Fetch intensity value
       
   247         else if( param->iName->Compare( KAknsRlEffectNoiseIntensity ) == 0 )
       
   248             {
       
   249             if( param->iType != EAknsRlParameterTypeNumber )
       
   250                 User::Leave( KErrArgument );
       
   251 
       
   252             iIntensity = param->iNumber;
       
   253             }
       
   254         }
       
   255     }
       
   256 
       
   257 // -----------------------------------------------------------------------------
       
   258 // CAknsRlEffectPluginNoise::GetCapabilities
       
   259 // -----------------------------------------------------------------------------
       
   260 //
       
   261 void CAknsRlEffectPluginNoise::GetCapabilities( TAknsRlEffectCaps& aCaps )
       
   262     {
       
   263     aCaps.iOutputLayerSupport = KAknsRlLayerRGBOnly;
       
   264     aCaps.iInputLayerASupport = KAknsRlLayerRGBOnly;
       
   265     aCaps.iInputLayerBSupport = KAknsRlLayerNone;
       
   266     }
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CAknsRlEffectPluginNoise::Render
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 TInt CAknsRlEffectPluginNoise::Render( const TAknsRlRenderOpParam& aParam )
       
   273     {
       
   274     if( !iContext ) // We absolutely need the context
       
   275         {
       
   276         return KErrBadHandle;
       
   277         }
       
   278 
       
   279     // To do anything we need both, the output layer and input layer
       
   280     if( ( aParam.iOutputLayerStatus & KAknsRlLayerRGBOnly ) &&
       
   281         ( aParam.iInputLayerAStatus & KAknsRlLayerRGBOnly ) )
       
   282         {
       
   283         // Query the layers, uninitialized because we process the whole image
       
   284         TAknsRlLayerData dataTarget;
       
   285         TRAPD( err, iContext->GetLayerDataL( dataTarget, aParam.iOutputLayerIndex,
       
   286                                              aParam.iOutputLayerStatus, EFalse ) );
       
   287         if( KErrNone != err )
       
   288             return KErrArgument;
       
   289 
       
   290         TAknsRlLayerData dataSource;
       
   291         TRAP( err, iContext->GetLayerDataL( dataSource, aParam.iInputLayerAIndex,
       
   292                                             aParam.iInputLayerAStatus, EFalse ) );
       
   293         if( KErrNone != err )
       
   294             return KErrArgument;
       
   295 
       
   296         if( !dataTarget.iRGBBitmap ) // We need the target bitmap
       
   297             return KErrBadHandle;
       
   298 
       
   299         if( !dataSource.iRGBBitmap ) // We need the source bitmap
       
   300             return KErrBadHandle;
       
   301 
       
   302         TDisplayMode modeT = dataTarget.iRGBBitmap->DisplayMode();
       
   303         TDisplayMode modeS = dataSource.iRGBBitmap->DisplayMode();
       
   304 
       
   305         // Rgb -> Rgb modes
       
   306         if( EColor64K == modeS && EColor64K == modeT )
       
   307             {
       
   308             AknsRlEffectNoise<TUint16,0,5,6,5>::Process(
       
   309                             *dataTarget.iRGBBitmap,
       
   310                             *dataSource.iRGBBitmap,
       
   311                             iSeed,
       
   312                             iIntensity );
       
   313             }
       
   314         else if( EColor16MU == modeS && EColor16MU == modeT )
       
   315             {
       
   316             AknsRlEffectNoise<TUint32,8,8,8,8>::Process(
       
   317                             *dataTarget.iRGBBitmap,
       
   318                             *dataSource.iRGBBitmap,
       
   319                             iSeed,
       
   320                             iIntensity );
       
   321 
       
   322             }
       
   323         // Gray -> Gray mode
       
   324         else if( EGray256 == modeS && EGray256 == modeT )
       
   325             {
       
   326             AknsRlEffectNoiseGray::Process(
       
   327                             *dataTarget.iRGBBitmap,
       
   328                             *dataSource.iRGBBitmap,
       
   329                             iSeed,
       
   330                             iIntensity );
       
   331             }
       
   332         else
       
   333             {
       
   334             // Provided layers have illegal display mode combination
       
   335             return KErrArgument;
       
   336             }
       
   337         }
       
   338     else
       
   339         {
       
   340         // Required layers were not provided
       
   341         return KErrArgument;
       
   342         }
       
   343 
       
   344     return KErrNone;
       
   345     }
       
   346 
       
   347 // End of File