imagingmodules/jp2kcodec/Src/JP2KPacket.cpp
changeset 0 469c91dae73b
child 4 3993b8f65362
equal deleted inserted replaced
-1:000000000000 0:469c91dae73b
       
     1 /*
       
     2 * Copyright (c) 2003, 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:  JP2KPacket class used to collect packet related
       
    15 *                information such as tag tree and list of codeblocks.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <icl/imagecodec.h>
       
    22 #include "JP2KImageUtils.h"
       
    23 #include "JP2KStreamReader.h"
       
    24 #include "JP2KTileInfo.h"
       
    25 #include "JP2KImageInfo.h"
       
    26 #include "JP2KCodeBlock.h"
       
    27 #include "JP2KPacket.h"
       
    28 #include "JP2KSubband.h"
       
    29 #include "JP2KComponentInfo.h"
       
    30 
       
    31 // EXTERNAL DATA STRUCTURES
       
    32 
       
    33 // EXTERNAL FUNCTION PROTOTYPES  
       
    34 
       
    35 // CONSTANTS
       
    36 
       
    37 // MACROS
       
    38 
       
    39 // LOCAL CONSTANTS AND MACROS
       
    40 
       
    41 // MODULE DATA STRUCTURES
       
    42 
       
    43 // LOCAL FUNCTION PROTOTYPES
       
    44 
       
    45 // FORWARD DECLARATIONS
       
    46 
       
    47 // ============================ MEMBER FUNCTIONS ===============================
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // CJ2kPacket::CJ2kPacket
       
    51 // C++ default constructor can NOT contain any code, that
       
    52 // might leave.
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 CJ2kPacket::CJ2kPacket( TUint16 aLayer ) : 
       
    56     iTagTreeLevel(1),
       
    57     iLayer(aLayer), 
       
    58     iCodeBlockList(1)
       
    59     {
       
    60     }
       
    61 
       
    62 // Destructor
       
    63 CJ2kPacket::~CJ2kPacket()
       
    64     {
       
    65     delete iIncluded;
       
    66     iIncluded = 0;
       
    67 
       
    68     delete iTagTreeInfo;
       
    69     iTagTreeInfo = 0;
       
    70 
       
    71     delete iIncTagTreeValue;
       
    72     iIncTagTreeValue = 0;
       
    73 
       
    74     delete iIncTagTreeState;
       
    75     iIncTagTreeState = 0;
       
    76 
       
    77     delete iMsbTagTreeValue;
       
    78     iMsbTagTreeValue = 0;
       
    79 
       
    80     delete iMsbTagTreeState;
       
    81     iMsbTagTreeState = 0;
       
    82 
       
    83     iCodeBlockList.ResetAndDestroy();
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CJ2kPacket::SetPacketCanvas
       
    88 // Set the canvas of the packet
       
    89 // (other items were commented in a header).
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 void CJ2kPacket::SetPacketCanvas( TInt32 aX, TInt32 aY, TInt32 aWidth, TInt32 aHeight )
       
    93     {
       
    94     iPacketCanvas.iTl = TPoint( aX, aY );
       
    95     iPacketCanvas.SetWidth( aWidth );
       
    96     iPacketCanvas.SetHeight( aHeight );
       
    97     }
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // CJ2kPacket::SetNumOfBlocks
       
   101 // Set the number of blocks
       
   102 // (other items were commented in a header).
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 void CJ2kPacket::SetNumOfBlocks( TSize& aCodeBlock )
       
   106     {
       
   107     TInt32 x0 = TJ2kUtils::Floor( iPacketCanvas.iTl.iX, aCodeBlock.iWidth ) * aCodeBlock.iWidth;
       
   108     TInt32 y0 = TJ2kUtils::Floor( iPacketCanvas.iTl.iY, aCodeBlock.iHeight ) * aCodeBlock.iHeight;
       
   109     TInt32 x1 = TJ2kUtils::Ceil( iPacketCanvas.iTl.iX + iPacketCanvas.Width(), aCodeBlock.iWidth ) * aCodeBlock.iWidth;
       
   110     TInt32 y1 = TJ2kUtils::Ceil( iPacketCanvas.iTl.iY + iPacketCanvas.Height(), aCodeBlock.iHeight ) * aCodeBlock.iHeight;
       
   111     iCodeBlockSize.iWidth  = ( x1 - x0 ) / aCodeBlock.iWidth;
       
   112     iCodeBlockSize.iHeight = ( y1 - y0 ) / aCodeBlock.iHeight;
       
   113     }
       
   114 
       
   115 // -----------------------------------------------------------------------------
       
   116 // CJ2kPacket::BuildInclusiveInfoL
       
   117 // Build the inclusive information of the packet
       
   118 // (other items were commented in a header).
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 void CJ2kPacket::BuildInclusiveInfoL()
       
   122     {
       
   123     TInt entries = ( iLayer % 8 ) ? ( ( iLayer / 8 ) + 1 ) : ( iLayer / 8 );
       
   124     iIncluded = HBufC8::NewMaxL( entries );
       
   125     iIncluded->Des().FillZ();
       
   126     }
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CJ2kPacket::BuildCodeBlocksL
       
   130 // Build the codeblocks in the packet
       
   131 // (other items were commented in a header).
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 void CJ2kPacket::BuildCodeBlocksL( TInt32 aX, TInt32 aY, TSize& aCodeBlock )
       
   135     {
       
   136     TUint16 numOfBlocks = NumOfBlocks();
       
   137 
       
   138     if ( numOfBlocks )
       
   139         {
       
   140         BuildTagtreeL();
       
   141 
       
   142         TInt32 x0 = 0;
       
   143         TInt32 y0 = 0;
       
   144         TInt32 x1 = 0;
       
   145         TInt32 y1 = 0;
       
   146         TInt32 origX = aX;
       
   147         TUint16 index = 0;
       
   148 
       
   149         while ( index < numOfBlocks )
       
   150             {
       
   151             x0 = Max( aX, iPacketCanvas.iTl.iX );
       
   152             y0 = Max( aY, iPacketCanvas.iTl.iY );
       
   153             x1 = Min( aX + aCodeBlock.iWidth, iPacketCanvas.iTl.iX + iPacketCanvas.Width() ) - x0;
       
   154             y1 = Min( aY + aCodeBlock.iHeight, iPacketCanvas.iTl.iY + iPacketCanvas.Height() ) - y0;
       
   155             if ( x1 > 0 && y1 > 0 )
       
   156                 {
       
   157                 CJ2kCodeBlock *block = new ( ELeave ) CJ2kCodeBlock;
       
   158                 CleanupStack::PushL( block );
       
   159                 User::LeaveIfError( iCodeBlockList.Append( block ) );
       
   160                 CleanupStack::Pop( 1 );
       
   161                 iCodeBlockList[index]->SetCodeBlockCanvas( x0, y0, x1, y1 );
       
   162 
       
   163                 // Initialize the codeblock
       
   164                 iCodeBlockList[index]->InitializeL( iLayer );
       
   165                 ++index;
       
   166                 }
       
   167 
       
   168             aX += aCodeBlock.iWidth;
       
   169             if ( aX >= iPacketCanvas.iTl.iX + iPacketCanvas.Width() )
       
   170                 {
       
   171                 aX = origX;
       
   172                 aY += aCodeBlock.iHeight;
       
   173                 }
       
   174             }
       
   175         }
       
   176     }
       
   177 
       
   178 // -----------------------------------------------------------------------------
       
   179 // CJ2kPacket::ReadPacketHeaderL
       
   180 // Read the packet header
       
   181 // (other items were commented in a header).
       
   182 // -----------------------------------------------------------------------------
       
   183 //
       
   184 TUint8 CJ2kPacket::ReadPacketHeaderL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband )
       
   185     {
       
   186     if ( IsIncludedL( aTile.LastLayerProcessed() ) )
       
   187         {
       
   188         return EFalse;
       
   189         }
       
   190 
       
   191     TUint8 incomplete = ETrue;
       
   192     if ( LastCodeBlockProcessed() == 0 )
       
   193         {
       
   194         if ( ReadSOP_EPHMarker( aComponent, aTile ) )
       
   195             {
       
   196             return incomplete;
       
   197             }
       
   198         }
       
   199 
       
   200     TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
       
   201     TUint8 *rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
       
   202 
       
   203     if ( !StartReadBit( aTile ) )
       
   204         {
       
   205         TUint8 bit = 0;
       
   206 
       
   207         if ( LastCodeBlockProcessed() == 0 )
       
   208             {
       
   209             if ( !IsRecoverFromIncomplete() )
       
   210                 {
       
   211                 ReadBit( bit, aTile );
       
   212                 if ( bit == 0 )
       
   213                     {
       
   214                     // Empty packet
       
   215                     incomplete = EFalse;
       
   216                     }
       
   217                 }
       
   218             }
       
   219 
       
   220         if ( incomplete )
       
   221             {
       
   222             // Packet header has not been processed yet
       
   223             if ( !IsHeader() )
       
   224                 {
       
   225                 TUint8 isBackup = IsBackupNeeded( aTile );
       
   226 
       
   227                 CJ2kSubband *subband = &aSubband;
       
   228                 if ( subband->SubbandResLevel() > 0 )
       
   229                     {
       
   230                     if ( subband->LastSubbandProcessed() == CJ2kSubband::EBandLL )
       
   231                         {
       
   232                         subband->SetLastSubbandProcessed( CJ2kSubband::EBandHL );
       
   233                         }
       
   234                     else
       
   235                         {
       
   236                         // Move to last subband processed
       
   237                         while ( subband->SubbandType() != aSubband.LastSubbandProcessed() )
       
   238                             {
       
   239                             subband = subband->NextSubbandRaster();
       
   240                             }
       
   241                         }
       
   242                     }
       
   243 
       
   244                 TUint16 bandIndex = 0;
       
   245                 TUint16 cbIndex = 0;
       
   246                 TUint16 cbYIndex = 0;
       
   247                 TUint16 xIndex = 0;
       
   248                 TUint16 yIndex = 0;
       
   249                 TUint16 incValue = 0;
       
   250                 TUint16 msbValue = 0;
       
   251                 TUint16 index = 0;
       
   252                 TUint16 layer = aTile.LastLayerProcessed();
       
   253                 TUint16 numPass = 0;
       
   254                 TUint16 codePass = 0;
       
   255                 TUint16 numSegment = 0;
       
   256                 TUint8  recoverIncTag = 0;
       
   257                 TUint8  recoverMsbTag = 0;
       
   258                 TUint8  firstRecovery = ETrue;
       
   259                 TUint8  recoverData = 0;
       
   260                 TUint8  recoverPos = 0;
       
   261                 TUint8  recoverNextPos = 0;
       
   262                 TUint8  origPassIndex = 0;
       
   263                 TUint8  origLengthBits = 0;
       
   264                 TInt8   origLastPass = 0;
       
   265                 TUint32 origDataLength = 0;
       
   266 
       
   267                 HBufC16 *recoverIncTagTreeValue = 0;
       
   268                 HBufC16 *recoverIncTagTreeState = 0;
       
   269                 HBufC16 *recoverMsbTagTreeValue = 0;
       
   270                 HBufC16 *recoverMsbTagTreeState = 0;
       
   271 
       
   272                 if ( IsRecoverFromIncomplete() )
       
   273                     {
       
   274                     recoverData = reader.iData;
       
   275                     recoverPos = reader.iPos;
       
   276                     recoverNextPos = reader.iNextPos;
       
   277                     }
       
   278 
       
   279                 CJ2kPacket *packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
       
   280                 CJ2kCodeBlock *codeBlock;
       
   281                 incomplete = EFalse;
       
   282                 do
       
   283                     {
       
   284                     if ( aComponent.QuantizationStyle() != 1 )
       
   285                         {
       
   286                         bandIndex = subband->SubbandTreeIndex();
       
   287                         }
       
   288                     
       
   289                     for ( yIndex = 0; yIndex < packet->NumOfBlocksY(); ++yIndex )
       
   290                         {
       
   291                         cbYIndex = (TUint16)( yIndex * packet->NumOfBlocksX() );
       
   292                         for ( xIndex = 0; xIndex < packet->NumOfBlocksX(); ++xIndex )
       
   293                             {
       
   294                             cbIndex = (TUint16)( cbYIndex + xIndex );
       
   295                             if ( cbIndex < packet->LastCodeBlockProcessed() ||
       
   296                                 ( packet->IsMatch() && cbIndex == packet->LastCodeBlockProcessed() ) )
       
   297                                 {
       
   298                                 // Has been processed, skip to the next codeblock
       
   299                                 continue;   //lint !e960    Using continue saves a lot of code here.
       
   300                                 }
       
   301                             else
       
   302                                 {
       
   303                                 packet->ResetMatch();
       
   304                                 recoverIncTag = recoverMsbTag = EFalse;
       
   305                                 codeBlock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( cbIndex ) );
       
   306 
       
   307                                 TPtr16 numSegPtr = codeBlock->iNumSegment->Des();
       
   308 
       
   309                                 origPassIndex = codeBlock->iPassIndex;
       
   310                                 origLastPass  = codeBlock->iLastPass;
       
   311                                 if ( codeBlock->iLastPass < 0 && codeBlock->iPassIndex == 0 )
       
   312                                     {
       
   313                                     if ( isBackup )
       
   314                                         {
       
   315                                         packet->BackupIncTagtreeL( recoverIncTagTreeValue, recoverIncTagTreeState );
       
   316                                         recoverIncTag = ETrue;
       
   317                                         }
       
   318                                     msbValue = (TUint16)0;
       
   319                                     incomplete = packet->DecodeIncTagtree( aTile, xIndex, yIndex, incValue );
       
   320                                     if ( !incomplete )
       
   321                                         {
       
   322                                         if ( incValue <= layer )
       
   323                                             {
       
   324                                             if ( isBackup )
       
   325                                                 {
       
   326                                                 packet->BackupMsbTagtreeL( recoverMsbTagTreeValue, recoverMsbTagTreeState );
       
   327                                                 recoverMsbTag = ETrue;
       
   328                                                 }
       
   329                                             incomplete = packet->DecodeMsbTagtree( aTile, xIndex, yIndex, msbValue );
       
   330                                             }
       
   331                                         else
       
   332                                             {
       
   333                                             packet->SetLastCodeBlockProcessed( cbIndex );
       
   334                                             firstRecovery  = EFalse;
       
   335                                             recoverData    = reader.iData;
       
   336                                             recoverPos     = reader.iPos;
       
   337                                             recoverNextPos = reader.iNextPos;
       
   338                                             recoverIncTag = recoverMsbTag = EFalse;
       
   339                                             rollbackPtr   =  CONST_CAST( TUint8*, reader.iPtr );
       
   340 
       
   341                                             // Move on to the next codeblock
       
   342                                             continue;   //lint !e960    Using continue saves a lot of code here.
       
   343                                             }
       
   344                                         }
       
   345 
       
   346                                     if ( incomplete )
       
   347                                         {
       
   348                                         // Underflow, should backup the iterator position
       
   349                                         if ( cbIndex > packet->LastCodeBlockProcessed() )
       
   350                                             {
       
   351                                             // Next read should match the codeblock index
       
   352                                             packet->SetMatch();
       
   353                                             }
       
   354                                         
       
   355                                         if ( !firstRecovery )
       
   356                                             {
       
   357                                             SetRecoverFromIncomplete();
       
   358                                             reader.iData    = recoverData;
       
   359                                             reader.iPos     = recoverPos;
       
   360                                             reader.iNextPos = recoverNextPos;
       
   361                                             }
       
   362                                         else
       
   363                                             {
       
   364                                             if ( IsRecoverFromIncomplete() )
       
   365                                                 {
       
   366                                                 reader.iData    = recoverData;
       
   367                                                 reader.iPos     = recoverPos;
       
   368                                                 reader.iNextPos = recoverNextPos;
       
   369                                                 }
       
   370                                             }
       
   371                                         
       
   372                                         if ( isBackup )
       
   373                                             {
       
   374                                             if ( recoverIncTag )
       
   375                                                 {
       
   376                                                 packet->RestoreIncTagtree( recoverIncTagTreeValue, recoverIncTagTreeState );
       
   377                                                 }
       
   378                                             if ( recoverMsbTag )
       
   379                                                 {
       
   380                                                 packet->RestoreMsbTagtree( recoverMsbTagTreeValue, recoverMsbTagTreeState );
       
   381                                                 }
       
   382                                             // Release memory
       
   383                                             packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
       
   384                                                                        recoverMsbTagTreeValue, recoverMsbTagTreeState );
       
   385                                             }
       
   386                                         reader.iPtr = rollbackPtr;
       
   387 
       
   388                                         // Return from the packet header decoding
       
   389                                         return incomplete;
       
   390                                         }
       
   391 
       
   392                                     codeBlock->iLastPass = 0;
       
   393                                     numSegPtr[layer] = 1;
       
   394 
       
   395                                     codeBlock->iEmptyBitplane = (TUint8)msbValue;
       
   396 
       
   397                                     if ( aComponent.RoiShift() > 0 )
       
   398                                         {
       
   399                                         numPass = (TUint16)( ( aComponent.MagnitudeBits( bandIndex ) + aComponent.RoiShift() ) * 3 + 1 );
       
   400                                         }
       
   401                                     else
       
   402                                         {
       
   403                                         numPass = (TUint16)( ( aComponent.MagnitudeBits( bandIndex ) - msbValue  ) * 3 + 1 );
       
   404                                         }
       
   405 
       
   406                                     if ( codeBlock->iDataSize == 0 || codeBlock->iDataSize->Length() < numPass )
       
   407                                         {
       
   408                                         if ( codeBlock->iDataSize == 0 )
       
   409                                             {
       
   410                                             codeBlock->iDataSize = HBufC16::NewMaxL( numPass );
       
   411                                             codeBlock->iDataSize->Des().FillZ();
       
   412                                             codeBlock->iPassesPerSegment = HBufC16::NewMaxL( numPass );
       
   413                                             codeBlock->iPassesPerSegment->Des().FillZ();
       
   414                                             }
       
   415                                         else
       
   416                                             {
       
   417                                             incValue = ( TUint16 )( numPass - codeBlock->iDataSize->Length() );
       
   418                                             codeBlock->iDataSize = codeBlock->iDataSize->ReAllocL( numPass );
       
   419                                             codeBlock->iPassesPerSegment = codeBlock->iPassesPerSegment->ReAllocL( numPass );
       
   420                                             while ( incValue-- )
       
   421                                                 {
       
   422                                                 codeBlock->iDataSize->Des().Append( 0 );
       
   423                                                 codeBlock->iPassesPerSegment->Des().Append( 0 );
       
   424                                                 }
       
   425                                             }
       
   426                                         }
       
   427                                     }
       
   428                                 else
       
   429                                     {
       
   430                                     incomplete = ReadBit( bit, aTile );
       
   431                                     if ( incomplete )
       
   432                                         {
       
   433                                         // Underflow, should backup the iterator position
       
   434                                         if ( cbIndex > packet->LastCodeBlockProcessed() )
       
   435                                             {
       
   436                                             // Next read should match the codeblock index
       
   437                                             packet->SetMatch();
       
   438                                             }
       
   439                                         
       
   440                                         if ( !firstRecovery )
       
   441                                             {
       
   442                                             SetRecoverFromIncomplete();
       
   443                                             reader.iData = recoverData;
       
   444                                             reader.iPos = recoverPos;
       
   445                                             reader.iNextPos = recoverNextPos;
       
   446                                             }
       
   447                                         else
       
   448                                             {
       
   449                                             if ( IsRecoverFromIncomplete() )
       
   450                                                 {
       
   451                                                 reader.iData    = recoverData;
       
   452                                                 reader.iPos     = recoverPos;
       
   453                                                 reader.iNextPos = recoverNextPos;
       
   454                                                 }
       
   455                                             }
       
   456                                         
       
   457                                         if ( isBackup )
       
   458                                             {
       
   459                                             // Release memory
       
   460                                             packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
       
   461                                                                        recoverMsbTagTreeValue, recoverMsbTagTreeState );
       
   462                                             }
       
   463                                         reader.iPtr = rollbackPtr;
       
   464 
       
   465                                         // Return from the packet header decoding
       
   466                                         return incomplete;
       
   467                                         }
       
   468 
       
   469                                     numSegPtr[layer] = bit;
       
   470 
       
   471                                     if ( bit == 0 )
       
   472                                         {
       
   473                                         packet->SetLastCodeBlockProcessed( cbIndex );
       
   474                                         firstRecovery  = EFalse;
       
   475                                         recoverData = reader.iData;
       
   476                                         recoverPos  = reader.iPos;
       
   477                                         recoverNextPos = reader.iNextPos;
       
   478                                         recoverIncTag = recoverMsbTag = EFalse;
       
   479                                         rollbackPtr   =  CONST_CAST( TUint8*, reader.iPtr );
       
   480 
       
   481                                         // Move on to the next codeblock
       
   482                                         continue;   //lint !e960    Using continue saves a lot of code here.
       
   483                                         }
       
   484                                     }
       
   485 
       
   486                                 incomplete = ReadBit( bit, aTile );
       
   487                                 codePass = (TUint16)0;
       
   488                                 if ( !incomplete )
       
   489                                     {
       
   490                                     if ( bit ) // 1
       
   491                                         {
       
   492                                         incomplete = ReadBit( bit, aTile );
       
   493                                         if ( !incomplete )
       
   494                                             {
       
   495                                             if ( bit ) // 11
       
   496                                                 {
       
   497                                                 incomplete = ReadBits( bit, 2, aTile );
       
   498                                                 if ( !incomplete )
       
   499                                                     {
       
   500                                                     if ( bit == 0x03 ) // 1111
       
   501                                                         {
       
   502                                                         incomplete = ReadBits( bit, 5, aTile );
       
   503                                                         if ( !incomplete )
       
   504                                                             {
       
   505                                                             if ( bit == 0x1f ) // 1111 11111
       
   506                                                                 {
       
   507                                                                 incomplete = ReadBits( bit, 7, aTile );
       
   508                                                                 if ( !incomplete )
       
   509                                                                     {
       
   510                                                                     codePass = (TUint16)( 0x25 + bit );
       
   511                                                                     }
       
   512                                                                 }
       
   513                                                             else
       
   514                                                                 {
       
   515                                                                 // 1111 XXXXX, at least one of them is not 1
       
   516                                                                 codePass = (TUint16)( 6 + bit );
       
   517                                                                 }
       
   518                                                             }
       
   519                                                         }
       
   520                                                     else
       
   521                                                         {
       
   522                                                         // 11XX
       
   523                                                         codePass = (TUint16)( 3 + bit );
       
   524                                                         }
       
   525                                                     }
       
   526                                                 }
       
   527                                             else
       
   528                                                 {
       
   529                                                 // 10
       
   530                                                 codePass = 2;
       
   531                                                 }
       
   532                                             }
       
   533                                         }
       
   534                                     else
       
   535                                         {
       
   536                                         // 0
       
   537                                         codePass = 1;
       
   538                                         }
       
   539                                     }
       
   540 
       
   541                                 if ( incomplete )
       
   542                                     {
       
   543                                     // Underflow, restore the original codeblock information
       
   544                                     codeBlock->iPassIndex = origPassIndex;
       
   545                                     codeBlock->iLastPass = origLastPass;
       
   546 
       
   547                                     // Underflow, should backup the iterator position
       
   548                                     if ( cbIndex > packet->LastCodeBlockProcessed() )
       
   549                                         {
       
   550                                         // Next read should match the codeblock index
       
   551                                         packet->SetMatch();
       
   552                                         }
       
   553                                     
       
   554                                     if ( !firstRecovery )
       
   555                                         {
       
   556                                         SetRecoverFromIncomplete();
       
   557                                         reader.iData = recoverData;
       
   558                                         reader.iPos = recoverPos;
       
   559                                         reader.iNextPos = recoverNextPos;
       
   560                                         }                                    
       
   561                                     else
       
   562                                         {
       
   563                                         if ( IsRecoverFromIncomplete() )
       
   564                                             {
       
   565                                             reader.iData = recoverData;
       
   566                                             reader.iPos  = recoverPos;
       
   567                                             reader.iNextPos = recoverNextPos;
       
   568                                             }
       
   569                                         }
       
   570 
       
   571                                     if ( isBackup )
       
   572                                         {
       
   573                                         if ( recoverIncTag )
       
   574                                             {
       
   575                                             packet->RestoreIncTagtree( recoverIncTagTreeValue, 
       
   576                                                                        recoverIncTagTreeState );
       
   577                                             }
       
   578                                         if ( recoverMsbTag )
       
   579                                             {
       
   580                                             packet->RestoreMsbTagtree( recoverMsbTagTreeValue, 
       
   581                                                                        recoverMsbTagTreeState );
       
   582                                             }
       
   583                                         // Release memory
       
   584                                         packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
       
   585                                                                    recoverMsbTagTreeValue, recoverMsbTagTreeState );
       
   586                                         }
       
   587                                     reader.iPtr = rollbackPtr;
       
   588                                     
       
   589                                     // Return from the packet header decoding
       
   590                                     return incomplete;
       
   591                                     }
       
   592 
       
   593                                 if ( codeBlock->iPassIndex == 0 )
       
   594                                     {
       
   595                                     codeBlock->iLastPass = -1;
       
   596                                     }
       
   597 
       
   598                                 numSegment = 1;
       
   599 
       
   600                                 if ( aComponent.IsTermination() )
       
   601                                     {
       
   602                                     numSegment = codePass;
       
   603                                     }
       
   604                                 else if ( aComponent.IsACByPass() )
       
   605                                     {
       
   606                                     if ( ( codeBlock->iLastPass + codePass ) >= KFirstLazyPassIndex )
       
   607                                         {
       
   608                                         for ( index = 1; index < codePass; ++index )
       
   609                                             {
       
   610                                             if ( ( index + codeBlock->iLastPass ) >= KFirstLazyPassIndex )
       
   611                                                 {
       
   612                                                 if ( ( ( index + codeBlock->iLastPass ) % 3 ) != 1 )
       
   613                                                     {
       
   614                                                     ++numSegment;
       
   615                                                     }
       
   616                                                 }
       
   617                                             }
       
   618                                         }
       
   619                                     }
       
   620 
       
   621                                 numSegPtr[layer] = numSegment;   //lint !e961    no else is needed here at the end of if...else if
       
   622 
       
   623                                 origLengthBits = codeBlock->iLengthBits;
       
   624                                 origDataLength = codeBlock->iDataLength;
       
   625                                 incomplete = ReadBit( bit, aTile );
       
   626                                 if ( !incomplete )
       
   627                                     {
       
   628                                     // Skip all 1 bits
       
   629                                     while ( bit )
       
   630                                         {
       
   631                                         ++codeBlock->iLengthBits;
       
   632                                         incomplete = ReadBit( bit, aTile );
       
   633                                         if ( incomplete )
       
   634                                             {
       
   635                                             // Underflow
       
   636                                             // Set bit to zero to break from the while-loop
       
   637                                             bit = 0;
       
   638                                             }
       
   639                                         }
       
   640                                     }
       
   641 
       
   642                                 if ( !incomplete )
       
   643                                     {
       
   644                                     TUint8 bits = 0;
       
   645                                     TUint32 tmpBits = 0;
       
   646                                     TPtr16 numPassesPerSegPtr = codeBlock->iPassesPerSegment->Des();
       
   647                                     TPtr16 numDataSizePtr = codeBlock->iDataSize->Des();
       
   648 
       
   649                                     if ( numSegment == 1 )
       
   650                                         {
       
   651                                         bits = (TUint8)( codeBlock->iLengthBits + TJ2kUtils::Log2( codePass ) );
       
   652 
       
   653                                         incomplete = ReadBits( tmpBits, bits, aTile );
       
   654                                         if ( !incomplete )
       
   655                                             {
       
   656                                             numPassesPerSegPtr[codeBlock->iPassIndex] = codePass;
       
   657                                             numDataSizePtr[codeBlock->iPassIndex++] = (TUint16)tmpBits;
       
   658 
       
   659                                             codeBlock->iDataLength += tmpBits;
       
   660                                             codeBlock->iLastPass = (TUint8)( codeBlock->iLastPass + codePass );
       
   661                                             if ( tmpBits > 0 )
       
   662                                                 {
       
   663                                                 SetBodyIncomplete();
       
   664                                                 }
       
   665                                             }
       
   666                                         }
       
   667                                     else
       
   668                                         {
       
   669                                         TUint16 totalCodePass = codePass;
       
   670                                         TUint16 tmpCodePass;
       
   671                                         for ( index = 0; index < numSegment; ++index )
       
   672                                             {
       
   673                                             if ( aComponent.IsTermination() )
       
   674                                                 {
       
   675                                                 tmpCodePass = 1;
       
   676                                                 }
       
   677                                             else
       
   678                                                 {
       
   679                                                 if ( codeBlock->iLastPass < KFirstLazyPassIndex )
       
   680                                                     {
       
   681                                                     tmpCodePass = (TUint16)( KFirstLazyPassIndex - ( TInt )codeBlock->iLastPass );
       
   682                                                     }
       
   683                                                 else
       
   684                                                     {
       
   685                                                     tmpCodePass = (TUint16)( ( codeBlock->iLastPass % 3 ) ? 1 : ( ( totalCodePass > 1 ) ? 2 : 1 ) );
       
   686                                                     }
       
   687                                                 }
       
   688                                             bits = (TUint8)( codeBlock->iLengthBits + TJ2kUtils::Log2( tmpCodePass ) );
       
   689                                             incomplete = ReadBits( tmpBits, bits, aTile );
       
   690                                             if ( !incomplete )
       
   691                                                 {
       
   692                                                 numPassesPerSegPtr[codeBlock->iPassIndex] = tmpCodePass;
       
   693                                                 numDataSizePtr[codeBlock->iPassIndex++] = (TUint16)tmpBits;
       
   694 
       
   695                                                 codeBlock->iDataLength += tmpBits;
       
   696                                                 codeBlock->iLastPass = (TUint8)( codeBlock->iLastPass + tmpCodePass );
       
   697                                                 totalCodePass = (TUint16)( totalCodePass - tmpCodePass );
       
   698                                                 if ( tmpBits > 0 )
       
   699                                                     {
       
   700                                                     SetBodyIncomplete();
       
   701                                                     }
       
   702                                                 }
       
   703                                             else
       
   704                                                 {
       
   705                                                 index = numSegment;     // break from the for-loop
       
   706                                                 }
       
   707                                             }
       
   708                                         }
       
   709                                     }
       
   710 
       
   711                                 if ( incomplete )
       
   712                                     {
       
   713                                     // Underflow, restore the original codeblock information
       
   714                                     codeBlock->iPassIndex = origPassIndex;
       
   715                                     codeBlock->iLastPass = origLastPass;
       
   716                                     codeBlock->iLengthBits = origLengthBits;
       
   717                                     codeBlock->iDataLength = origDataLength;
       
   718 
       
   719                                     // Underflow, should backup the iterator position
       
   720                                     if ( cbIndex > packet->LastCodeBlockProcessed() )
       
   721                                         {
       
   722                                         // Next read should match the codeblock index
       
   723                                         packet->SetMatch();
       
   724                                         }
       
   725                                     
       
   726                                     if ( !firstRecovery )
       
   727                                         {
       
   728                                         SetRecoverFromIncomplete();
       
   729                                         reader.iData = recoverData;
       
   730                                         reader.iPos = recoverPos;
       
   731                                         reader.iNextPos = recoverNextPos;
       
   732                                         }
       
   733                                     else
       
   734                                         {
       
   735                                         if ( IsRecoverFromIncomplete() )
       
   736                                             {
       
   737                                             reader.iData = recoverData;
       
   738                                             reader.iPos = recoverPos;
       
   739                                             reader.iNextPos = recoverNextPos;
       
   740                                             }
       
   741                                         }
       
   742                                     
       
   743                                     if ( isBackup )
       
   744                                         {
       
   745                                         if ( recoverIncTag )
       
   746                                             {
       
   747                                             packet->RestoreIncTagtree( recoverIncTagTreeValue, 
       
   748                                                                        recoverIncTagTreeState );
       
   749                                             }
       
   750                                         if ( recoverMsbTag )
       
   751                                             {
       
   752                                             packet->RestoreMsbTagtree( recoverMsbTagTreeValue, 
       
   753                                                                        recoverMsbTagTreeState );
       
   754                                             }
       
   755 
       
   756                                         // Release memory
       
   757                                         packet->FreeBackupTagtree( recoverIncTagTreeValue, 
       
   758                                                                    recoverIncTagTreeState, 
       
   759                                                                    recoverMsbTagTreeValue, 
       
   760                                                                    recoverMsbTagTreeState );
       
   761                                         }
       
   762                                     reader.iPtr = rollbackPtr;
       
   763                                     
       
   764                                     // Return from the packet header decoding
       
   765                                     return incomplete;
       
   766                                     }
       
   767 
       
   768                                 }
       
   769 
       
   770                             packet->SetLastCodeBlockProcessed( cbIndex );
       
   771                             firstRecovery  = EFalse;
       
   772                             recoverData = reader.iData;
       
   773                             recoverPos = reader.iPos;
       
   774                             recoverNextPos = reader.iNextPos;
       
   775                             recoverIncTag = recoverMsbTag = EFalse;
       
   776                             rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
       
   777                             } // end of xIndex
       
   778                         } // end of yIndex
       
   779 
       
   780                     packet->SetLastCodeBlockProcessed( 0 );
       
   781                     packet->ResetMatch();
       
   782                     ResetRecoverFromIncomplete();
       
   783                     subband = subband->NextSubbandRaster();
       
   784                     if ( subband )
       
   785                         {
       
   786                         if ( isBackup )
       
   787                             {
       
   788                             // Sibling may have different tag tree level, so release memory here
       
   789                             packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
       
   790                                                        recoverMsbTagTreeValue, recoverMsbTagTreeState );
       
   791                             }
       
   792                         packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
       
   793                         aSubband.SetLastSubbandProcessed( (TUint8)subband->SubbandType() );
       
   794                         }
       
   795 
       
   796                     } while ( subband );
       
   797 
       
   798                 if ( !incomplete )
       
   799                     {
       
   800                     // Packet header has been completely processed
       
   801                     SetHeader();
       
   802                     SetIncluded( aTile.LastLayerProcessed() );
       
   803                     AlignReader( aTile );
       
   804                     aSubband.SetLastSubbandProcessed( CJ2kSubband::EBandLL );
       
   805                     }
       
   806                 if ( isBackup )
       
   807                     {
       
   808                     // Release memory
       
   809                     packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
       
   810                                                recoverMsbTagTreeValue, recoverMsbTagTreeState );
       
   811                     }
       
   812                 }
       
   813             else
       
   814                 {
       
   815                 // Packet has been processed
       
   816                 reader.iPtr = rollbackPtr;
       
   817                 }
       
   818             }
       
   819 
       
   820         if ( !incomplete )
       
   821             {
       
   822             if ( aComponent.IsEPHMarkerUsed() )
       
   823                 {
       
   824                 ReadEPHMarker( aTile );
       
   825                 }
       
   826             }
       
   827         }
       
   828     return incomplete;
       
   829     }
       
   830 
       
   831 // -----------------------------------------------------------------------------
       
   832 // CJ2kPacket::ReadPacketBodyL
       
   833 // Read the packet body
       
   834 // (other items were commented in a header).
       
   835 // -----------------------------------------------------------------------------
       
   836 //
       
   837 TUint8 CJ2kPacket::ReadPacketBodyL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband )
       
   838     {
       
   839     TUint8 incomplete = EFalse;
       
   840     if ( LastCodeBlockProcessed() == 0 )
       
   841         {
       
   842         if ( ReadSOP_EPHMarker( aComponent, aTile, EFalse ) )
       
   843             {
       
   844             return ETrue;
       
   845             }
       
   846         }
       
   847 
       
   848     TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
       
   849 
       
   850     // Packet body has not been processed yet
       
   851     if ( !IsBody() )
       
   852         {
       
   853         SetBodyIncomplete();
       
   854 
       
   855         CJ2kSubband *subband = &aSubband;
       
   856         if ( subband->SubbandResLevel() > 0 )
       
   857             {
       
   858             if ( subband->LastSubbandProcessed() == CJ2kSubband::EBandLL )
       
   859                 {
       
   860                 subband->SetLastSubbandProcessed( CJ2kSubband::EBandHL );
       
   861                 }
       
   862             else
       
   863                 {
       
   864                 // Move to last subband processed
       
   865                 while ( subband->SubbandType() != aSubband.LastSubbandProcessed() )
       
   866                     {
       
   867                     subband = subband->NextSubbandRaster();
       
   868                     }
       
   869                 }
       
   870             }
       
   871         TUint16 xIndex = 0;
       
   872         TUint16 yIndex = 0;
       
   873         TUint16 cbIndex = 0;
       
   874         TUint16 cbYIndex = 0;
       
   875         TUint16 index = 0;
       
   876         TUint16 cblkLength = 0;
       
   877         TUint16 layer = aTile.LastLayerProcessed();
       
   878         TInt32  totalLength = 0;
       
   879         TUint8 *rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
       
   880         
       
   881         CJ2kPacket *packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
       
   882         CJ2kCodeBlock *codeBlock = 0;
       
   883         do
       
   884             {
       
   885         
       
   886             for ( yIndex = 0; yIndex < packet->NumOfBlocksY(); ++yIndex )
       
   887                 {
       
   888                 cbYIndex = (TUint16)( yIndex * packet->NumOfBlocksX() );
       
   889                 for ( xIndex = 0; xIndex < packet->NumOfBlocksX(); ++xIndex )
       
   890                     {
       
   891                     cbIndex = (TUint16)( cbYIndex + xIndex );
       
   892                     if ( cbIndex < packet->LastCodeBlockProcessed() ||
       
   893                         ( packet->IsMatch() && cbIndex == packet->LastCodeBlockProcessed() ) )
       
   894                         {
       
   895                         // Has been processed, skip to the next codeblock
       
   896                         continue;   //lint !e960    Using continue saves a lot of code here.
       
   897                         }
       
   898                     else
       
   899                         {
       
   900                         packet->ResetMatch();
       
   901                         codeBlock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( cbIndex ) );
       
   902                         
       
   903                         if ( ( *codeBlock->iNumSegment )[layer] > 0 )
       
   904                             {
       
   905                             TUint tempLength = 0;
       
   906                             TUint8 skip = 0;
       
   907                             
       
   908                             if ( !aTile.IsSpeedup() )
       
   909                             {
       
   910                                 // If this resolution level is not required in decoding, skip storing the data to save memory
       
   911                                 if ( aTile.LastLevelProcessed() > (TUint8)( aTile.NumOfLevelsPOC() - aTile.ImageInfo().LevelDrop() ) )
       
   912                                     skip = 1;
       
   913                             }
       
   914                             
       
   915                             tempLength = codeBlock->iDataLength;
       
   916                             
       
   917                             if ( tempLength )
       
   918                                 {
       
   919                                 // Find out which segment has been processed
       
   920                                 totalLength = codeBlock->iDataLength - tempLength;
       
   921                                     {
       
   922                                     for ( index = 1; index <= ( *codeBlock->iNumSegment )[layer]; ++index )
       
   923                                         {
       
   924                                         totalLength -= ( *codeBlock->iDataSize )[codeBlock->iPassIndex - index];
       
   925                                         if ( totalLength <= 0 )
       
   926                                             {
       
   927                                             break;   //lint !e960    break usage saves code here.
       
   928                                             }
       
   929                                         }
       
   930                                     }
       
   931                                 }
       
   932                             else
       
   933                                 {
       
   934                                 index = ( *codeBlock->iNumSegment )[layer];
       
   935                                 }
       
   936 
       
   937                             for ( ; index > 0; --index )
       
   938                                 {
       
   939                                 cblkLength = ( *codeBlock->iDataSize )[codeBlock->iPassIndex - index];
       
   940                                 if ( ( reader.iPtrEnd - reader.iPtr ) < cblkLength )
       
   941                                     {
       
   942                                     // Underflow, rollback the iterator position
       
   943                                     reader.iPtr = rollbackPtr;
       
   944                                     incomplete = ETrue;
       
   945                                     if ( cbIndex > packet->LastCodeBlockProcessed() )
       
   946                                         {
       
   947                                         // Next read should match the codeblock index
       
   948                                         packet->SetMatch();
       
   949                                         }
       
   950 
       
   951                                     return incomplete;
       
   952                                     }
       
   953                                 else
       
   954                                     {
       
   955                                     
       
   956                                         // Store data only if the resolution level is not skipped
       
   957                                         if( !skip )
       
   958                                         {
       
   959                                     	    TPtr8 data = codeBlock->DataL()->Des();
       
   960 	                                        data.Append( reader.iPtr, cblkLength );
       
   961                                         }
       
   962                                     
       
   963                                     reader.iPtr += cblkLength;
       
   964                                     }
       
   965                                 // Save the iterator position
       
   966                                 rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
       
   967                                 }
       
   968                             }
       
   969                         }
       
   970                     packet->SetLastCodeBlockProcessed( cbIndex );
       
   971 
       
   972                     // Save the iterator position
       
   973                     rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
       
   974                     } // end of xIndex
       
   975                 } // end of yIndex
       
   976 
       
   977             packet->SetLastCodeBlockProcessed( 0 );
       
   978             packet->ResetMatch();
       
   979             subband = subband->NextSubbandRaster();
       
   980             if ( subband )
       
   981                 {
       
   982                 packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
       
   983                 aSubband.SetLastSubbandProcessed( (TUint8)subband->SubbandType() );
       
   984                 }
       
   985 
       
   986             } while ( subband );
       
   987 
       
   988         SetBody();
       
   989         ResetBodyIncomplete();
       
   990         aSubband.SetLastSubbandProcessed( CJ2kSubband::EBandLL );
       
   991         }
       
   992 
       
   993     return incomplete;
       
   994     }
       
   995 
       
   996 // -----------------------------------------------------------------------------
       
   997 // CJ2kPacket::ResetInternalFlags
       
   998 // Reset the internal flags
       
   999 // (other items were commented in a header).
       
  1000 // -----------------------------------------------------------------------------
       
  1001 //
       
  1002 void CJ2kPacket::ResetInternalFlags()
       
  1003     {
       
  1004     ResetHeader();
       
  1005     ResetBody();
       
  1006     }
       
  1007 
       
  1008 // -----------------------------------------------------------------------------
       
  1009 // CJ2kPacket::BuildTagtreeL
       
  1010 // Build the tag tree
       
  1011 // (other items were commented in a header).
       
  1012 // -----------------------------------------------------------------------------
       
  1013 //
       
  1014 void CJ2kPacket::BuildTagtreeL()
       
  1015     {
       
  1016     TUint32 width  = iCodeBlockSize.iWidth;
       
  1017     TUint32 height = iCodeBlockSize.iHeight;
       
  1018 
       
  1019     while ( width != 1 || height != 1 )
       
  1020         {
       
  1021         width  = ( width + 1 ) >> 1;
       
  1022         height = ( height + 1 ) >> 1;
       
  1023         ++iTagTreeLevel;
       
  1024         }
       
  1025 
       
  1026     TInt size = 0;
       
  1027     TInt sizeIndex = 0;
       
  1028     width = iCodeBlockSize.iWidth;
       
  1029     height = iCodeBlockSize.iHeight;
       
  1030 
       
  1031     iTagTreeInfo = HBufC16::NewMaxL( iTagTreeLevel + 1 );
       
  1032     TPtr16 tmpPtr = ( iTagTreeInfo->Des() );
       
  1033     tmpPtr[0] = (TUint16)sizeIndex;
       
  1034 
       
  1035     for ( TUint8 index = 0; index < iTagTreeLevel; ++index )
       
  1036         {
       
  1037         size = width * height;
       
  1038         sizeIndex += size;
       
  1039         tmpPtr[index + 1] = (TUint16)sizeIndex;
       
  1040         }
       
  1041 
       
  1042     TChar fillChar( 0xffff );
       
  1043 
       
  1044     iIncTagTreeValue = HBufC16::NewMaxL( sizeIndex );
       
  1045     iIncTagTreeValue->Des().Fill( fillChar, iIncTagTreeValue->Length() );
       
  1046     iIncTagTreeState = HBufC16::NewMaxL( sizeIndex );
       
  1047     iIncTagTreeState->Des().FillZ();
       
  1048 
       
  1049     iMsbTagTreeValue = HBufC16::NewMaxL( sizeIndex );
       
  1050     iMsbTagTreeValue->Des().Fill( fillChar, iIncTagTreeValue->Length() );
       
  1051     iMsbTagTreeState = HBufC16::NewMaxL( sizeIndex );
       
  1052     iMsbTagTreeState->Des().FillZ();
       
  1053     }
       
  1054 
       
  1055 // -----------------------------------------------------------------------------
       
  1056 // CJ2kPacket::DecodeIncTagtree
       
  1057 // Decode the included tag tree
       
  1058 // (other items were commented in a header).
       
  1059 // -----------------------------------------------------------------------------
       
  1060 //
       
  1061 TUint8 CJ2kPacket::DecodeIncTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue )
       
  1062     {
       
  1063     TUint8 bit = 2;
       
  1064     TInt16 parentState = 0;
       
  1065     TUint8 contCoding = 1;
       
  1066     TUint16 idx = 0;
       
  1067     TUint16 layer = (TUint16)( aTile.LastLayerProcessed() + 1 );
       
  1068 
       
  1069     for ( TInt16 index = TInt16( iTagTreeLevel - 1 ); index >= 0; --index )
       
  1070         {
       
  1071         idx = (TUint16)( ( aHeight >> index ) * ( (TUint32)( iCodeBlockSize.iWidth + ( 1 << index ) - 1 ) >> index ) + ( aWidth >> index ) );
       
  1072         if ( ( IncTagState( index, idx ) < parentState ) && IncTagValue( index, idx ) == 0xffff )
       
  1073             {
       
  1074             SetIncTagState( index, idx, (TUint16)( parentState - contCoding ) );
       
  1075             }
       
  1076 
       
  1077         while ( contCoding && IncTagState( index, idx ) < layer && IncTagValue( index, idx ) == 0xffff )
       
  1078             {
       
  1079             if ( ReadBit( bit, aTile ) )
       
  1080                 {
       
  1081                 return ETrue;
       
  1082                 }
       
  1083 
       
  1084             if ( bit == 1 )
       
  1085                 {
       
  1086                 SetIncTagValue( index, idx, IncTagState( index, idx ) );
       
  1087                 }
       
  1088             IncrementIncTagState( index, idx );
       
  1089             }
       
  1090         parentState = IncTagState( index, idx );
       
  1091         if ( bit == 0 || IncTagValue( index, idx ) == 0xffff )
       
  1092             {
       
  1093             contCoding = 0;
       
  1094             }
       
  1095         }
       
  1096     aValue = IncTagValue( 0, idx );
       
  1097     return EFalse;
       
  1098     }
       
  1099 
       
  1100 // -----------------------------------------------------------------------------
       
  1101 // CJ2kPacket::DecodeMsbTagtree
       
  1102 // Decode the msb tag tree
       
  1103 // (other items were commented in a header).
       
  1104 // -----------------------------------------------------------------------------
       
  1105 //
       
  1106 TUint8 CJ2kPacket::DecodeMsbTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue )
       
  1107     {
       
  1108     TUint8 bit = 2;
       
  1109     TInt16 parentState = 0;
       
  1110     TUint8 contCoding = 1;
       
  1111     TUint16 idx = 0;
       
  1112     TUint16 layer = 0xffff;
       
  1113 
       
  1114     for ( TInt16 index = (TUint16)( iTagTreeLevel - 1 ); index >= 0; --index )
       
  1115         {
       
  1116         idx = (TUint16)( ( aHeight >> index ) * ( (TUint32)( iCodeBlockSize.iWidth + ( 1 << index ) - 1 ) >> index ) + ( aWidth >> index ) );
       
  1117 
       
  1118         if ( ( MsbTagState( index, idx ) < parentState ) && MsbTagValue( index, idx ) == 0xffff )
       
  1119             {
       
  1120             SetMsbTagState( index, idx, (TUint16)( ( parentState - contCoding ) ) );
       
  1121             }
       
  1122 
       
  1123         while ( contCoding && MsbTagState( index, idx ) < layer && MsbTagValue( index, idx ) == 0xffff )
       
  1124             {
       
  1125             if ( ReadBit( bit, aTile ) )
       
  1126                 {
       
  1127                 return ETrue;
       
  1128                 }
       
  1129 
       
  1130             if ( bit == 1 )
       
  1131                 {
       
  1132                 SetMsbTagValue( index, idx, MsbTagState( index, idx ) );
       
  1133                 }
       
  1134             IncrementMsbTagState( index, idx );
       
  1135             }
       
  1136         parentState = MsbTagState( index, idx );
       
  1137         if ( bit == 0 || MsbTagValue( index, idx ) == 0xffff )
       
  1138             {
       
  1139             contCoding = 0;
       
  1140             }
       
  1141         }
       
  1142     aValue = MsbTagValue( 0, idx );
       
  1143     return EFalse;
       
  1144     }
       
  1145 
       
  1146 // -----------------------------------------------------------------------------
       
  1147 // CJ2kPacket::BackupIncTagtreeL
       
  1148 // Backup the included tag tree
       
  1149 // (other items were commented in a header).
       
  1150 // -----------------------------------------------------------------------------
       
  1151 //
       
  1152 void CJ2kPacket::BackupIncTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState )
       
  1153     {
       
  1154     if ( aTagValue && aTagState )
       
  1155         {
       
  1156         if ( aTagValue->Des().MaxLength() < iIncTagTreeValue->Length() )
       
  1157             {
       
  1158             aTagValue = aTagValue->ReAllocL( iIncTagTreeValue->Length() );
       
  1159             }
       
  1160         if ( aTagState->Des().MaxLength() < iIncTagTreeState->Length() )
       
  1161             {
       
  1162             aTagState = aTagState->ReAllocL( iIncTagTreeState->Length() );
       
  1163             }
       
  1164         }
       
  1165     else
       
  1166         {
       
  1167         aTagValue = HBufC16::NewMaxLC( iIncTagTreeValue->Length() );
       
  1168         aTagState = HBufC16::NewMaxLC( iIncTagTreeState->Length() );
       
  1169         }
       
  1170     *aTagValue = *iIncTagTreeValue;
       
  1171     *aTagState = *iIncTagTreeState;
       
  1172     }
       
  1173 
       
  1174 // -----------------------------------------------------------------------------
       
  1175 // CJ2kPacket::BackupMsbTagtreeL
       
  1176 // Backup the msb tag tree
       
  1177 // (other items were commented in a header).
       
  1178 // -----------------------------------------------------------------------------
       
  1179 //
       
  1180 void CJ2kPacket::BackupMsbTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState )
       
  1181     {
       
  1182     if ( aTagValue && aTagState )
       
  1183         {
       
  1184         if ( aTagValue->Des().MaxLength() < iMsbTagTreeValue->Length() )
       
  1185             {
       
  1186             aTagValue = aTagValue->ReAllocL( iMsbTagTreeValue->Length() );
       
  1187             }
       
  1188         if ( aTagState->Des().MaxLength() < iMsbTagTreeState->Length() )
       
  1189             {
       
  1190             aTagState = aTagState->ReAllocL( iMsbTagTreeState->Length() );
       
  1191             }
       
  1192         }
       
  1193     else
       
  1194         {
       
  1195         aTagValue = HBufC16::NewMaxLC( iMsbTagTreeValue->Length() );
       
  1196         aTagState = HBufC16::NewMaxLC( iMsbTagTreeState->Length() );
       
  1197         }
       
  1198     *aTagValue = *iMsbTagTreeValue;
       
  1199     *aTagState = *iMsbTagTreeState;
       
  1200     }
       
  1201 
       
  1202 // -----------------------------------------------------------------------------
       
  1203 // CJ2kPacket::RestoreIncTagtree
       
  1204 // Restore the included tag tree
       
  1205 // (other items were commented in a header).
       
  1206 // -----------------------------------------------------------------------------
       
  1207 //
       
  1208 void CJ2kPacket::RestoreIncTagtree( HBufC16 *aTagValue, HBufC16 *aTagState )
       
  1209     {
       
  1210     *iIncTagTreeValue = *aTagValue;
       
  1211     *iIncTagTreeState = *aTagState;
       
  1212     }
       
  1213 
       
  1214 // -----------------------------------------------------------------------------
       
  1215 // CJ2kPacket::RestoreMsbTagtree
       
  1216 // Restore the msb tag tree
       
  1217 // (other items were commented in a header).
       
  1218 // -----------------------------------------------------------------------------
       
  1219 //
       
  1220 void CJ2kPacket::RestoreMsbTagtree( HBufC16 *aTagValue, HBufC16 *aTagState )
       
  1221     {
       
  1222     *iMsbTagTreeValue = *aTagValue;
       
  1223     *iMsbTagTreeState = *aTagState;
       
  1224     }
       
  1225 
       
  1226 // -----------------------------------------------------------------------------
       
  1227 // CJ2kPacket::FreeBackupTagtree
       
  1228 // Release the temporary backup memory
       
  1229 // (other items were commented in a header).
       
  1230 // -----------------------------------------------------------------------------
       
  1231 //
       
  1232 void CJ2kPacket::FreeBackupTagtree( HBufC16*& aIncTagValue, HBufC16*& aIncTagState,
       
  1233                                     HBufC16*& aMsbTagValue, HBufC16*& aMsbTagState )
       
  1234     {
       
  1235     TInt count = 0;
       
  1236     if ( aIncTagValue )
       
  1237         {
       
  1238         delete aIncTagValue;
       
  1239         aIncTagValue = 0;
       
  1240         ++count;
       
  1241         }
       
  1242     if ( aIncTagState )
       
  1243         {
       
  1244         delete aIncTagState;
       
  1245         aIncTagState = 0;
       
  1246         ++count;
       
  1247         }
       
  1248     if ( aMsbTagValue )
       
  1249         {
       
  1250         delete aMsbTagValue;
       
  1251         aMsbTagValue = 0;
       
  1252         ++count;
       
  1253         }
       
  1254     if ( aMsbTagState )
       
  1255         {
       
  1256         delete aMsbTagState;
       
  1257         aMsbTagState = 0;
       
  1258         ++count;
       
  1259         }
       
  1260     CleanupStack::Pop( count );
       
  1261     }
       
  1262 
       
  1263 // -----------------------------------------------------------------------------
       
  1264 // CJ2kPacket::IsIncludedL
       
  1265 // Is the layer has been included in previous packet
       
  1266 // (other items were commented in a header).
       
  1267 // -----------------------------------------------------------------------------
       
  1268 //
       
  1269 TUint8 CJ2kPacket::IsIncludedL( TUint16 aLayer )
       
  1270     {
       
  1271     TInt entries = ( iLayer % 8 ) ? ( ( iLayer / 8 ) + 1 ) : ( iLayer / 8 );
       
  1272     if ( iIncluded == 0 || iIncluded->Des().MaxLength() < entries )
       
  1273         {
       
  1274         if ( iIncluded )
       
  1275             {
       
  1276             TInt diff = entries - iIncluded->Length();
       
  1277             iIncluded = iIncluded->ReAllocL( entries );
       
  1278             while ( diff-- )
       
  1279                 {
       
  1280                 iIncluded->Des().Append( (TUint8)0 );
       
  1281                 }
       
  1282             }
       
  1283         else
       
  1284             {
       
  1285             iIncluded = HBufC8::NewMaxL( entries );
       
  1286             iIncluded->Des().FillZ();
       
  1287             }
       
  1288         }
       
  1289     return IncludedAt( aLayer );
       
  1290     }
       
  1291 
       
  1292 // -----------------------------------------------------------------------------
       
  1293 // CJ2kPacket::IncludedAt
       
  1294 // Get the inclusive information at specific layer
       
  1295 // (other items were commented in a header).
       
  1296 // -----------------------------------------------------------------------------
       
  1297 //
       
  1298 TUint8 CJ2kPacket::IncludedAt( TUint16 aLayer ) const
       
  1299     {
       
  1300     TInt entry = aLayer / 8;
       
  1301     TInt bit   = aLayer % 8;
       
  1302     return (TUint8)( ( iIncluded->Des() )[entry] & ( 0x01 << bit ) );
       
  1303     }
       
  1304 
       
  1305 // -----------------------------------------------------------------------------
       
  1306 // CJ2kPacket::SetIncluded
       
  1307 // Set the inclusive information at specific layer
       
  1308 // (other items were commented in a header).
       
  1309 // -----------------------------------------------------------------------------
       
  1310 //
       
  1311 void CJ2kPacket::SetIncluded( TUint16 aLayer )
       
  1312     {
       
  1313     TInt entry = aLayer / 8;
       
  1314     TInt bit   = aLayer % 8;
       
  1315     TPtr8 tmpPtr = iIncluded->Des();
       
  1316     tmpPtr[entry] |= ( 0x01 << bit );
       
  1317     }
       
  1318 
       
  1319 // -----------------------------------------------------------------------------
       
  1320 // CJ2kPacket::IsBackupNeeded
       
  1321 // Is tag tree backup is required for underflow recovery
       
  1322 // (other items were commented in a header).
       
  1323 // -----------------------------------------------------------------------------
       
  1324 //
       
  1325 TUint8 CJ2kPacket::IsBackupNeeded( CJ2kTileInfo& aTile )
       
  1326     {
       
  1327     return !( aTile.IsPPT() || aTile.ImageInfo().IsPPM() );
       
  1328     }
       
  1329 
       
  1330 // -----------------------------------------------------------------------------
       
  1331 // CJ2kPacket::StartReadBit
       
  1332 // Read a bit from the packet header stream
       
  1333 // (other items were commented in a header).
       
  1334 // -----------------------------------------------------------------------------
       
  1335 //
       
  1336 TUint8 CJ2kPacket::StartReadBit( CJ2kTileInfo& aTile )
       
  1337     {
       
  1338     return ( !IsRecoverFromIncomplete() ) ?
       
  1339         aTile.PacketHeaderReader().StartReadBit() : 
       
  1340         (TUint8)EFalse;
       
  1341     }
       
  1342 
       
  1343 // -----------------------------------------------------------------------------
       
  1344 // CJ2kPacket::ReadBit
       
  1345 // Read a bit from the packet header stream
       
  1346 // (other items were commented in a header).
       
  1347 // -----------------------------------------------------------------------------
       
  1348 //
       
  1349 TUint8 CJ2kPacket::ReadBit( TUint8& aBit, CJ2kTileInfo& aTile )
       
  1350     {
       
  1351     return aTile.PacketHeaderReader().ReadBit( aBit );
       
  1352     }
       
  1353 
       
  1354 // -----------------------------------------------------------------------------
       
  1355 // CJ2kPacket::ReadBits
       
  1356 // Read some bits from the packet header stream
       
  1357 // (other items were commented in a header).
       
  1358 // -----------------------------------------------------------------------------
       
  1359 //
       
  1360 TUint8 CJ2kPacket::ReadBits( TUint8& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile )
       
  1361     {
       
  1362     return aTile.PacketHeaderReader().ReadBits( aBit, aBitLen );
       
  1363     }
       
  1364 
       
  1365 // -----------------------------------------------------------------------------
       
  1366 // CJ2kPacket::ReadBits
       
  1367 // Read some bits from the packet header stream
       
  1368 // (other items were commented in a header).
       
  1369 // -----------------------------------------------------------------------------
       
  1370 //
       
  1371 TUint8 CJ2kPacket::ReadBits( TUint32& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile )
       
  1372     {
       
  1373     return aTile.PacketHeaderReader().ReadBits( aBit, aBitLen );
       
  1374     }
       
  1375 
       
  1376 // -----------------------------------------------------------------------------
       
  1377 // CJ2kPacket::AlignReader
       
  1378 // Align the stream to the next byte boundary if necessary
       
  1379 // (other items were commented in a header).
       
  1380 // -----------------------------------------------------------------------------
       
  1381 //
       
  1382 void CJ2kPacket::AlignReader( CJ2kTileInfo& aTile )
       
  1383     {
       
  1384     aTile.PacketHeaderReader().AlignReader();
       
  1385     }
       
  1386 
       
  1387 // -----------------------------------------------------------------------------
       
  1388 // CJ2kPacket::ReadSOPMarker
       
  1389 // Try to consume the SOP marker if there is one
       
  1390 // (other items were commented in a header).
       
  1391 // -----------------------------------------------------------------------------
       
  1392 //
       
  1393 TUint8 CJ2kPacket::ReadSOPMarker( CJ2kTileInfo& aTile )
       
  1394     {
       
  1395     // SOP may be inside the CodeStream only
       
  1396     return CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() ).ReadSOPMarker();
       
  1397     }
       
  1398 
       
  1399 // -----------------------------------------------------------------------------
       
  1400 // CJ2kPacket::ReadEPHMarker
       
  1401 // Try to consume the EPH marker if there is one
       
  1402 // (other items were commented in a header).
       
  1403 // -----------------------------------------------------------------------------
       
  1404 //
       
  1405 TUint8 CJ2kPacket::ReadEPHMarker( CJ2kTileInfo& aTile )
       
  1406     {
       
  1407     // EPH may be inside PPT or PPM or CodeStream
       
  1408     return aTile.PacketHeaderReader().ReadEPHMarker();
       
  1409     }
       
  1410 
       
  1411 // -----------------------------------------------------------------------------
       
  1412 // CJ2kPacket::ReadSOP_EPHMarker
       
  1413 // Try to re-align stream to next byte boundary if necessary,
       
  1414 // (other items were commented in a header).
       
  1415 // -----------------------------------------------------------------------------
       
  1416 //
       
  1417 TUint8 CJ2kPacket::ReadSOP_EPHMarker( CJ2kComponentInfo& aComponent, CJ2kTileInfo& aTile, TBool aSOP )
       
  1418     {
       
  1419     TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
       
  1420 
       
  1421     TUint8 incomplete = reader.TryReAlignReader();
       
  1422     incomplete = reader.TryReadEPHMarker();
       
  1423 
       
  1424     if ( !incomplete && aSOP && aComponent.IsSOPMarkerUsed() && ( !IsHeader() || !IsBody() ) )
       
  1425         {
       
  1426         incomplete = ReadSOPMarker( aTile );
       
  1427         }
       
  1428 
       
  1429     return incomplete;
       
  1430     }