skins/AknSkins/srvsrc/AknsSrvChunkMaintainer2.cpp
changeset 0 05e9090e2422
equal deleted inserted replaced
-1:000000000000 0:05e9090e2422
       
     1 /*
       
     2 * Copyright (c) 2005-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:  Extension to chunk maintainer.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "AknsSrvChunkMaintainer.h"
       
    20 
       
    21 #include "AknsSrvUtils.h"
       
    22 #include "AknsSrvDescriptorFileLayout.h"
       
    23 
       
    24 #include "AknsDebug.h"
       
    25 
       
    26 // CONSTANTS
       
    27 
       
    28 // Max of 32 effects per queue and 64 params per effect should be enough
       
    29 static const TInt KAknsSrvMaxEffectCount      = 0x20;
       
    30 static const TInt KAknsSrvMaxParamGroupCount  = 0x20;
       
    31 static const TInt KAknsSrvMaxEffectParamCount = 0x40;
       
    32 
       
    33 /**
       
    34 * A wrapper class for RPointerArray cleanup.
       
    35 */
       
    36 NONSHARABLE_CLASS( CAknsSrvArrayStore ): public CBase
       
    37     {
       
    38     public:
       
    39         CAknsSrvArrayStore()
       
    40             {}
       
    41 
       
    42         ~CAknsSrvArrayStore()
       
    43             {
       
    44             while( iArray.Count() )
       
    45                 {
       
    46                 delete [] iArray[0];
       
    47                 iArray.Remove(0);
       
    48                 }
       
    49             iArray.Reset();
       
    50             }
       
    51 
       
    52     public:
       
    53         RPointerArray<TUint8> iArray;
       
    54     };
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CAknsSrvChunkMaintainer::DoMergeEffectQueueL
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 void CAknsSrvChunkMaintainer::DoMergeEffectQueueL(
       
    61     CAknsSrvFileBuffer& aFile, const TUint aOffset,
       
    62     const TAknsItemDefClass /*aClass*/,
       
    63     const TAknsSrvExclusionQuery& aExclQuery, const TBool /*aAhOverride*/ )
       
    64     {
       
    65     TAknsSrvDef itemDef;
       
    66     TInt32 major = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueMajor );
       
    67     TInt32 minor = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueMinor );
       
    68     TInt32 refmajor = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueRefMajor );
       
    69     TInt32 refminor = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueRefMinor );
       
    70     TUint8 inputlayerindex = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueInputLayerIndex);
       
    71     TUint8 inputlayermode = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueInputLayerMode);
       
    72     TUint8 outputlayerindex = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueOutputLayerIndex);
       
    73     TUint8 outputlayermode = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueOutputLayerMode);
       
    74 
       
    75     TUint16 effectcount = AknsSrvUtils::GetUInt16L( aFile, aOffset + EAknsSrvDFOEffectQueueEffectCount);
       
    76 
       
    77     if( inputlayermode > 0x08 ||
       
    78         outputlayermode > 0x08 ||
       
    79         effectcount > KAknsSrvMaxEffectCount )
       
    80         {
       
    81         User::Leave(KErrCorrupt);
       
    82         }
       
    83 
       
    84     TUint32 size = 0;
       
    85     itemDef.iID.Set(major,minor);
       
    86 
       
    87     if( aExclQuery.IsExcluded( itemDef.iID ) )
       
    88         {
       
    89         return;
       
    90         }
       
    91 
       
    92     CheckAndModifyIID( itemDef.iID, aExclQuery );
       
    93 
       
    94     itemDef.iType = EAknsITEffectQueue;
       
    95 
       
    96     if (refmajor && refminor)
       
    97         {
       
    98         TAknsSrvEffectQueueDef eq;
       
    99         eq.iEffectQueueSize = sizeof(TAknsSrvEffectQueueDef);
       
   100         eq.iEffectCount = 0;
       
   101         eq.iRefMajor = refmajor;
       
   102         eq.iRefMinor = refminor;
       
   103         UpdateDef(&itemDef,&eq,sizeof(TAknsSrvEffectQueueDef),-1);
       
   104         return;
       
   105         }
       
   106 
       
   107     CAknsSrvArrayStore* effectArray = new(ELeave) CAknsSrvArrayStore();
       
   108     CleanupStack::PushL( effectArray );
       
   109 
       
   110     TUint32 eqBase = EAknsSrvDFOEffectQueueEffects;
       
   111     TUint32 totalEffectSize = 0;
       
   112 
       
   113     // process all effect chunks inside
       
   114     totalEffectSize = DoMergeEffectCommandsL( aFile, aOffset, eqBase, effectArray->iArray, effectcount );
       
   115 
       
   116     // All effects collected, add them to the queue
       
   117     TUint8* eqBlock = new (ELeave) TUint8[sizeof(TAknsSrvEffectQueueDef)+totalEffectSize];
       
   118     // No leaves after this
       
   119 
       
   120     TAknsSrvEffectQueueDef* eqDef = (TAknsSrvEffectQueueDef*)eqBlock;
       
   121     eqDef->iEffectCount = effectcount;
       
   122     eqDef->iRefMinor = 0;
       
   123     eqDef->iRefMajor = 0;
       
   124     eqDef->iInputLayerIndex = inputlayerindex;
       
   125     eqDef->iInputLayerMode = inputlayermode;
       
   126     eqDef->iOutputLayerIndex = outputlayerindex;
       
   127     eqDef->iOutputLayerMode = outputlayermode;
       
   128     TUint32 base = sizeof(TAknsSrvEffectQueueDef);
       
   129 
       
   130     for (TInt ecount = 0; ecount < effectcount; ecount++)
       
   131         {
       
   132         TAknsSrvEffectDef* effectDef = (TAknsSrvEffectDef*)(effectArray->iArray[ecount]);
       
   133         size = effectDef->iEffectSize;
       
   134         Mem::Copy(eqBlock+base, effectDef, size);
       
   135         base+=size;
       
   136         }
       
   137     eqDef->iEffectQueueSize = sizeof(TAknsSrvEffectQueueDef)+totalEffectSize;
       
   138 
       
   139     CleanupStack::PopAndDestroy( effectArray ); // effectArray
       
   140 
       
   141     UpdateDef( &itemDef, eqDef, sizeof(TAknsSrvEffectQueueDef)+totalEffectSize, -1 );
       
   142     delete [] eqBlock;
       
   143 
       
   144     // Leaves ok as eqBlock has been deleted
       
   145     }
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // CAknsSrvChunkMaintainer::DoMergeParamL
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 TUint32 CAknsSrvChunkMaintainer::DoMergeParamsL(
       
   152     CAknsSrvFileBuffer& aFile, const TUint aOffset, TUint32& aEqBase,
       
   153     RPointerArray<TUint8>& aParamArray, const TUint16 aParamCount )
       
   154     {
       
   155     TUint32 totalparamsize = 0; // total size of all parameters
       
   156     for( TInt i = 0; i < aParamCount; i++ )
       
   157         {
       
   158         TUint16 totalparamlen = AknsSrvUtils::GetUInt16L( aFile, aOffset + aEqBase);
       
   159         TUint32 datasize = totalparamlen-4; //ParamLength(TUint16)-Reserved(TUint8)-ParamType(TUint8)
       
   160 
       
   161         // lets assume that one effect cannot be larger than 32kb (should be more than enough)
       
   162         if (datasize >= 0x8000)
       
   163             {
       
   164             User::Leave(KErrCorrupt);
       
   165             }
       
   166         TUint8 ptype = AknsSrvUtils::GetUInt8L(aFile,aOffset+aEqBase+3);
       
   167 
       
   168         TUint8* paramBlock = NULL;
       
   169         TAknsSrvEffectParameterDef* paramDef = NULL;
       
   170 
       
   171         TUint8* data = AknsSrvUtils::ReadSkinDescL(aFile, aOffset+aEqBase+4, datasize);
       
   172         CleanupStack::PushL(data);
       
   173         if (ptype == 2) // graphics param
       
   174             {
       
   175             TUint32 filenameid = *((TUint32*)(data+datasize-4)) + iCurrentFilenameID;
       
   176             TInt filenameoffset = GetFilenameOffsetByID(filenameid);
       
   177 
       
   178             paramBlock = new (ELeave) TUint8[sizeof(TAknsSrvEffectParameterDef)+datasize-4+KAknsSrvMaxFileNameLen-4];
       
   179             CleanupStack::PushL( paramBlock );
       
   180             paramDef = (TAknsSrvEffectParameterDef*)paramBlock;
       
   181             Mem::Copy(paramBlock+sizeof(TAknsSrvEffectParameterDef), data, datasize-4);
       
   182             // Convert filenameid to offset and replace the id with offset
       
   183             Mem::Copy(paramBlock+sizeof(TAknsSrvEffectParameterDef)+datasize-4,&filenameoffset, sizeof(TInt));
       
   184             paramDef->iParameterType = ptype;
       
   185             paramDef->iParameterLength = AlignToFour(sizeof(TAknsSrvEffectParameterDef)+datasize);
       
   186             }
       
   187         else // string or int param or namedref (similar to int, used in animations)
       
   188             {
       
   189             paramBlock = new (ELeave) TUint8[sizeof(TAknsSrvEffectParameterDef)+datasize];
       
   190             CleanupStack::PushL( paramBlock );
       
   191             paramDef = (TAknsSrvEffectParameterDef*)paramBlock;
       
   192             paramDef->iParameterType = ptype;
       
   193             paramDef->iParameterLength = AlignToFour(sizeof(TAknsSrvEffectParameterDef)+datasize);
       
   194             Mem::Copy(paramBlock+sizeof(TAknsSrvEffectParameterDef), data, datasize);
       
   195             }
       
   196 
       
   197         totalparamsize += paramDef->iParameterLength;
       
   198         User::LeaveIfError( aParamArray.Append(paramBlock) );
       
   199         CleanupStack::Pop( paramBlock ); // paramBlock
       
   200 
       
   201         CleanupStack::PopAndDestroy( data ); // data
       
   202 
       
   203         aEqBase += totalparamlen;
       
   204         }
       
   205 
       
   206     return totalparamsize;
       
   207     }
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // CAknsSrvChunkMaintainer::DoMergeParamGroupL
       
   211 // -----------------------------------------------------------------------------
       
   212 //
       
   213 TUint32 CAknsSrvChunkMaintainer::DoMergeParamGroupsL(
       
   214     CAknsSrvFileBuffer& aFile, const TUint aOffset, TUint32& aBase,
       
   215     RPointerArray<TUint8>& aGroupArray, const TUint16 aGroupCount )
       
   216     {
       
   217     TUint32 totalGroupsSize = 0;
       
   218     for( TInt i = 0; i < aGroupCount; i++ )
       
   219         {
       
   220         // Fetch param group header
       
   221         TUint32 valueA = AknsSrvUtils::GetInt32L( aFile, aOffset + aBase + EAknsSrvDFOAnimationParamGroupValueA );
       
   222         TUint32 valueB = AknsSrvUtils::GetInt32L( aFile, aOffset + aBase + EAknsSrvDFOAnimationParamGroupValueB );
       
   223         TUint16 pcount = AknsSrvUtils::GetUInt16L( aFile, aOffset + aBase + EAknsSrvDFOAnimationParamGroupParameterCount );
       
   224 
       
   225         if( pcount > KAknsSrvMaxEffectParamCount )
       
   226             {
       
   227             User::Leave(KErrCorrupt);
       
   228             }
       
   229 
       
   230         // Fetch parameters
       
   231         aBase = aBase + EAknsSrvDFOAnimationParamGroupParameters;
       
   232 
       
   233         CAknsSrvArrayStore* paramArray = new(ELeave) CAknsSrvArrayStore();
       
   234         CleanupStack::PushL( paramArray );
       
   235         TUint32 totalParamSize = DoMergeParamsL( aFile, aOffset, aBase, paramArray->iArray, pcount );
       
   236 
       
   237         // Construct group array block
       
   238         TUint8* block = new(ELeave) TUint8[sizeof(TAknsSrvParamGroupDef) + totalParamSize];
       
   239         CleanupStack::PushL( block );
       
   240         TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)block;
       
   241         def->iValueA = valueA;
       
   242         def->iValueB = valueB;
       
   243 
       
   244         // Copy all parameters to the param group
       
   245         TUint32 base = sizeof(TAknsSrvParamGroupDef);
       
   246         for (TInt j = 0; j < pcount; j++)
       
   247             {
       
   248             TAknsSrvEffectParameterDef* paramDef = (TAknsSrvEffectParameterDef*)(paramArray->iArray[j]);
       
   249             TUint32 size = paramDef->iParameterLength;
       
   250             Mem::Copy(block + base, paramDef, size);
       
   251             base+=size;
       
   252             }
       
   253 
       
   254         def->iGroupSize      = base;
       
   255         def->iParameterCount = pcount;
       
   256         User::LeaveIfError( aGroupArray.Append(block) );
       
   257         CleanupStack::Pop( block );
       
   258 
       
   259         CleanupStack::PopAndDestroy( paramArray );
       
   260 
       
   261         totalGroupsSize+=base;
       
   262         aBase+=1; // GODDAMN END
       
   263         }
       
   264 
       
   265     return totalGroupsSize;
       
   266     }
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CAknsSrvChunkMaintainer::DoMergeEffectCommandL
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 TUint32 CAknsSrvChunkMaintainer::DoMergeEffectCommandsL(
       
   273     CAknsSrvFileBuffer& aFile, const TUint aOffset, TUint32& aBase,
       
   274     RPointerArray<TUint8>& aEffectArray, const TUint16 aEffectCount )
       
   275     {
       
   276     TUint32 totalSize = 0;
       
   277     for( TInt i = 0; i < aEffectCount; i++)
       
   278         {
       
   279         TInt32 effectuid = AknsSrvUtils::GetInt32L( aFile, aOffset+aBase + 8  );
       
   280         TUint8 inAindex = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 12);
       
   281         TUint8 inAmode = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 13);
       
   282         TUint8 inBindex = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 14);
       
   283         TUint8 inBmode = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 15);
       
   284         TUint8 outIndex = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 16);
       
   285         TUint8 outMode = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 17);
       
   286 
       
   287         // Check that at least some values are meaningful
       
   288         if (inAmode > 0x08 || inBmode > 0x08 || outMode > 0x08 )
       
   289             {
       
   290             User::Leave(KErrCorrupt);
       
   291             }
       
   292 
       
   293         TUint16 paramcount = AknsSrvUtils::GetUInt16L( aFile, aOffset+ aBase+ 18);
       
   294         if (paramcount > KAknsSrvMaxEffectParamCount)
       
   295             {
       
   296             User::Leave(KErrCorrupt);
       
   297             }
       
   298         aBase+=20;
       
   299 
       
   300         // process all parameters inside single effect
       
   301         CAknsSrvArrayStore* paramArray = new(ELeave) CAknsSrvArrayStore();
       
   302         CleanupStack::PushL( paramArray );
       
   303         TUint32 totalparamsize = DoMergeParamsL( aFile, aOffset, aBase, paramArray->iArray, paramcount );
       
   304 
       
   305         // All data collected
       
   306         TUint8* effectBlock= new (ELeave) TUint8[sizeof(TAknsSrvEffectDef)+totalparamsize];
       
   307         CleanupStack::PushL( effectBlock );
       
   308 
       
   309         TAknsSrvEffectDef* effectdef = (TAknsSrvEffectDef*)effectBlock;
       
   310         effectdef->iEffectUid.iUid       = effectuid;
       
   311         effectdef->iEffectParameterCount = paramcount;
       
   312         effectdef->iInputLayerAIndex     = inAindex;
       
   313         effectdef->iInputLayerAMode      = inAmode;
       
   314         effectdef->iInputLayerBIndex     = inBindex;
       
   315         effectdef->iInputLayerBMode      = inBmode;
       
   316         effectdef->iOutputLayerIndex     = outIndex;
       
   317         effectdef->iOutputLayerMode      = outMode;
       
   318 
       
   319         TUint32 base = sizeof(TAknsSrvEffectDef);
       
   320         TInt pcount;
       
   321         // copy all parameters to the effect
       
   322         for (pcount = 0; pcount < paramArray->iArray.Count(); pcount++)
       
   323             {
       
   324             TAknsSrvEffectParameterDef* paramDef = (TAknsSrvEffectParameterDef*)(paramArray->iArray[pcount]);
       
   325             TUint32 size = paramDef->iParameterLength;
       
   326             Mem::Copy(effectBlock+base, paramDef, size);
       
   327             base+=size;
       
   328             }
       
   329 
       
   330         effectdef->iEffectSize = base;
       
   331         User::LeaveIfError( aEffectArray.Append(effectBlock) );
       
   332         CleanupStack::Pop( effectBlock );
       
   333 
       
   334         CleanupStack::PopAndDestroy( paramArray );
       
   335 
       
   336         totalSize+=base;
       
   337         aBase+=1;// End of commands.
       
   338         }
       
   339 
       
   340     return totalSize;
       
   341     }
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // CAknsSrvChunkMaintainer::DoMergeAnimationL
       
   345 // -----------------------------------------------------------------------------
       
   346 //
       
   347 void CAknsSrvChunkMaintainer::DoMergeAnimationL(
       
   348     CAknsSrvFileBuffer& aFile, const TUint aOffset,
       
   349     const TAknsItemDefClass /*aClass*/,
       
   350     const TAknsSrvExclusionQuery& aExclQuery, const TBool /*aAhOverride*/ )
       
   351     {
       
   352     TAknsSrvDef itemDef;
       
   353     TUint32 size = 0;
       
   354     TUint32 totalSize = 0;
       
   355 
       
   356     //---------------------------------
       
   357     // Step 1: Process animation header information
       
   358 
       
   359     // Fetch animation header
       
   360     TInt32 major = AknsSrvUtils::GetInt32L(aFile, aOffset+EAknsSrvDFOAnimationMajor);
       
   361     TInt32 minor = AknsSrvUtils::GetInt32L(aFile, aOffset+EAknsSrvDFOAnimationMinor);
       
   362     TUint8 type  = AknsSrvUtils::GetUInt8L(aFile, aOffset+EAknsSrvDFOAnimationType);
       
   363     // Reserved0 and Reserved1 skipped
       
   364     TUint8 inIndex = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationInputLayerIndex);
       
   365     TUint8 inMode = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationInputLayerMode);
       
   366     TUint8 outIndex = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationOutputLayerIndex);
       
   367     TUint8 outMode = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationOutputLayerMode);
       
   368     TInt32 minInterval = AknsSrvUtils::GetInt32L(aFile, aOffset+EAknsSrvDFOAnimationMinInterval);
       
   369 
       
   370     if( inMode > 0x08 || outMode > 0x08 )
       
   371         {
       
   372         User::Leave(KErrCorrupt);
       
   373         }
       
   374 
       
   375     itemDef.iID.Set(major,minor);
       
   376     if( aExclQuery.IsExcluded( itemDef.iID ) )
       
   377         {
       
   378         return;
       
   379         }
       
   380     CheckAndModifyIID( itemDef.iID, aExclQuery );
       
   381     itemDef.iType = EAknsITAnimation;
       
   382 
       
   383     // Morphing interval is MIN(all intervals)
       
   384     TBool isMorphing(EFalse);
       
   385     isMorphing = (TBool)type;
       
   386     if (isMorphing)
       
   387         {
       
   388         if (iMorphingMinInterval < 0)
       
   389             {
       
   390             if (minInterval > 0)
       
   391                 {
       
   392                 iMorphingMinInterval = minInterval;
       
   393                 }
       
   394             }
       
   395         else if (iMorphingMinInterval > minInterval)
       
   396             {
       
   397             iMorphingMinInterval = minInterval;
       
   398             }
       
   399         }
       
   400     else // The definition is for highlight animation
       
   401         {
       
   402         // If product variant has disabled highlight animation we simply skip
       
   403         // non-morphing animation definitions.
       
   404         if( !aExclQuery.IsHighlightAnimEnabled() )
       
   405             {
       
   406             return;
       
   407             }
       
   408         }
       
   409 
       
   410     //---------------------------------
       
   411     // Step 2: Process animation content
       
   412 
       
   413     // Because named reference is stored as parameter, effect commands and
       
   414     // animation commands can be processed with the same function. When parsing
       
   415     // animation data and creating animation definition ChunkLookup will
       
   416     // convert named reference parameters to named reference structures ->
       
   417     // named references as parameters are not visible to animation framework.
       
   418     CAknsSrvArrayStore* preprocessArray = new(ELeave) CAknsSrvArrayStore();
       
   419     CleanupStack::PushL( preprocessArray );
       
   420     CAknsSrvArrayStore* commandArray  = new(ELeave) CAknsSrvArrayStore();
       
   421     CleanupStack::PushL( commandArray );
       
   422     CAknsSrvArrayStore* valueArray = new(ELeave) CAknsSrvArrayStore();
       
   423     CleanupStack::PushL( valueArray );
       
   424     CAknsSrvArrayStore* timingArray = new(ELeave) CAknsSrvArrayStore();
       
   425     CleanupStack::PushL( timingArray );
       
   426     CAknsSrvArrayStore* sizeBoundArray = new(ELeave) CAknsSrvArrayStore();
       
   427     CleanupStack::PushL( sizeBoundArray );
       
   428 
       
   429     TUint16 preprocessCount = 0;
       
   430     TUint16 commandCount    = 0;
       
   431     TUint16 valueCount      = 0;
       
   432     TUint16 timingCount     = 0;
       
   433     TUint16 sizeBoundCount  = 0;
       
   434 
       
   435     // Process preprocess chunks
       
   436     preprocessCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + EAknsSrvDFOAnimationPreprocessCount );
       
   437     if( preprocessCount > KAknsSrvMaxEffectCount )
       
   438         {
       
   439         User::Leave(KErrCorrupt);
       
   440         }
       
   441 
       
   442     TUint32 animBase = EAknsSrvDFOAnimationContentBegin; // Skip header data
       
   443     totalSize += DoMergeEffectCommandsL( aFile, aOffset, animBase, preprocessArray->iArray, preprocessCount );
       
   444 
       
   445     // Process animation command chunks
       
   446     commandCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
       
   447     if( commandCount > KAknsSrvMaxEffectCount )
       
   448         {
       
   449         User::Leave(KErrCorrupt);
       
   450         }
       
   451     animBase += sizeof(TUint16); // Skip commandCount
       
   452     totalSize += DoMergeEffectCommandsL( aFile, aOffset, animBase, commandArray->iArray, commandCount );
       
   453 
       
   454     // Animation values, timing models and size bound parameters are stored in
       
   455     // similar data structure -> process with the same function.
       
   456 
       
   457     // Process animation value chunks
       
   458     valueCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
       
   459     if( valueCount > KAknsSrvMaxParamGroupCount )
       
   460         {
       
   461         User::Leave(KErrCorrupt);
       
   462         }
       
   463     animBase += sizeof(TUint16); // Skip valueCount
       
   464     totalSize += DoMergeParamGroupsL( aFile, aOffset, animBase, valueArray->iArray, valueCount );
       
   465 
       
   466     // Process timing model chunks
       
   467     timingCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
       
   468     if( timingCount > KAknsSrvMaxParamGroupCount )
       
   469         {
       
   470         User::Leave(KErrCorrupt);
       
   471         }
       
   472     animBase += sizeof(TUint16); // Skip timingCount
       
   473     totalSize += DoMergeParamGroupsL( aFile, aOffset, animBase, timingArray->iArray, timingCount );
       
   474 
       
   475     // Process size bound parameter chunks
       
   476     sizeBoundCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
       
   477     if( sizeBoundCount > KAknsSrvMaxParamGroupCount )
       
   478         {
       
   479         User::Leave(KErrCorrupt);
       
   480         }
       
   481     animBase += sizeof(TUint16); // Skip sizeBoundCount
       
   482     totalSize += DoMergeParamGroupsL( aFile, aOffset, animBase, sizeBoundArray->iArray, sizeBoundCount );
       
   483 
       
   484     //---------------------------------
       
   485     // Step 3: All items collected, add them to the animation
       
   486     TUint8* block = new(ELeave) TUint8[sizeof(TAknsSrvEffectAnimDef)+totalSize];
       
   487     // No leaves after this
       
   488 
       
   489     TAknsSrvEffectAnimDef* eqDef = (TAknsSrvEffectAnimDef*)block;
       
   490     eqDef->iPreprocessCount  = preprocessCount;
       
   491     eqDef->iAnimCommandCount = commandCount;
       
   492     eqDef->iAnimValueCount   = valueCount;
       
   493     eqDef->iTimingModelCount = timingCount;
       
   494     eqDef->iSizeBoundCount   = sizeBoundCount;
       
   495     eqDef->iInputLayerIndex  = inIndex;
       
   496     eqDef->iInputLayerMode   = inMode;
       
   497     eqDef->iOutputLayerIndex = outIndex;
       
   498     eqDef->iOutputLayerMode  = outMode;
       
   499     eqDef->iMinInterval      = minInterval;
       
   500     eqDef->iAnimType         = isMorphing;
       
   501 
       
   502     TUint32 base = sizeof(TAknsSrvEffectAnimDef);
       
   503 
       
   504     // Add preprocess commands
       
   505     TInt i;
       
   506     for (i = 0; i < preprocessCount; i++)
       
   507         {
       
   508         TAknsSrvEffectDef* def = (TAknsSrvEffectDef*)(preprocessArray->iArray[i]);
       
   509         size = def->iEffectSize;
       
   510         Mem::Copy( block + base, def, size);
       
   511         base += size;
       
   512         }
       
   513 
       
   514     // Add animation commands
       
   515     for (i = 0; i < commandCount; i++)
       
   516         {
       
   517         TAknsSrvEffectDef* def = (TAknsSrvEffectDef*)(commandArray->iArray[i]);
       
   518         size = def->iEffectSize;
       
   519         Mem::Copy( block + base, def, size);
       
   520         base += size;
       
   521         }
       
   522 
       
   523     // Add animation values
       
   524     for (i = 0; i < valueCount; i++)
       
   525         {
       
   526         TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)(valueArray->iArray[i]);
       
   527         size = def->iGroupSize;
       
   528         Mem::Copy( block + base, def, size);
       
   529         base += size;
       
   530         }
       
   531 
       
   532     // Add timing models
       
   533     for (i = 0; i < timingCount; i++)
       
   534         {
       
   535         TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)(timingArray->iArray[i]);
       
   536         size = def->iGroupSize;
       
   537         Mem::Copy( block + base, def, size);
       
   538         base += size;
       
   539         }
       
   540 
       
   541     // Add size bound parameters
       
   542     for (i = 0; i < sizeBoundCount; i++)
       
   543         {
       
   544         TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)(sizeBoundArray->iArray[i]);
       
   545         size = def->iGroupSize;
       
   546         Mem::Copy( block + base, def, size);
       
   547         base += size;
       
   548         }
       
   549 
       
   550     eqDef->iEffectAnimSize = sizeof(TAknsSrvEffectAnimDef)+totalSize;
       
   551 
       
   552     CleanupStack::PopAndDestroy( 5 ); // All arrays
       
   553 
       
   554     UpdateDef( &itemDef, eqDef, sizeof(TAknsSrvEffectAnimDef)+totalSize, -1 );
       
   555     delete [] block;
       
   556     // Leaves ok after this, block deleted
       
   557     }
       
   558 
       
   559 // End of file.
       
   560