imagingmodules/jp2kcodec/Src/JP2KCodec.cpp
changeset 0 469c91dae73b
child 4 3993b8f65362
equal deleted inserted replaced
-1:000000000000 0:469c91dae73b
       
     1 /*
       
     2 * Copyright (c) 2003-2006 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:  CJp2kReadCodec class implements the ICL read codec interface.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <fbs.h>
       
    21 #include <JP2KImageData.h>
       
    22 #include "JP2KImageUtils.h"
       
    23 #include "JP2KFormat.h"
       
    24 #include "JP2KStreamReader.h"
       
    25 #include "JP2KTileInfo.h"
       
    26 #include "JP2KImageInfo.h"
       
    27 #include "JP2KCodec.h"
       
    28 #include "JP2KEntropyDecoder.h"
       
    29 #include "JP2KImageWriter.h"
       
    30 #include "JP2KSynthesis.h"
       
    31 
       
    32 // EXTERNAL DATA STRUCTURES
       
    33 
       
    34 // EXTERNAL FUNCTION PROTOTYPES  
       
    35 
       
    36 // CONSTANTS
       
    37 
       
    38 // MACROS
       
    39 
       
    40 // LOCAL CONSTANTS AND MACROS
       
    41 
       
    42 // MODULE DATA STRUCTURES
       
    43 
       
    44 // LOCAL FUNCTION PROTOTYPES
       
    45 
       
    46 // FORWARD DECLARATIONS
       
    47 
       
    48 // ============================= LOCAL FUNCTIONS ===============================
       
    49 
       
    50 // ============================ MEMBER FUNCTIONS ===============================
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CJp2kReadCodec::NewL
       
    54 // Two-phased constructor.
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 CJp2kReadCodec* CJp2kReadCodec::NewL( const TJ2kInfo& aJ2kInfo )
       
    58     {
       
    59     CJp2kReadCodec* self = new ( ELeave ) CJp2kReadCodec( aJ2kInfo );
       
    60 
       
    61     CleanupStack::PushL( self );
       
    62     self->ConstructL();
       
    63     CleanupStack::Pop( self ); 
       
    64 
       
    65     return self;
       
    66     }
       
    67 
       
    68 // Destructor
       
    69 CJp2kReadCodec::~CJp2kReadCodec()
       
    70     {
       
    71     delete iImageInfo;
       
    72     iImageInfo = 0;
       
    73 
       
    74     delete iEntropy;
       
    75     iEntropy = 0;
       
    76 
       
    77     delete iImageWriter;
       
    78     iImageWriter = 0;
       
    79 
       
    80     delete iSynthesis;
       
    81     iSynthesis = 0;
       
    82     }
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CJp2kReadCodec::DecodeTileL
       
    86 // Decoding the current tile-part
       
    87 // (other items were commented in a header).
       
    88 // -----------------------------------------------------------------------------
       
    89 //
       
    90 TFrameState CJp2kReadCodec::DecodeTileL()
       
    91     {
       
    92     CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
    93 
       
    94     // Decode and delete the tile
       
    95     DecodeAndDeleteTileL( tile );
       
    96 
       
    97     // reset the codec back to the parsing state
       
    98     iDecodeTile = EFalse;
       
    99     TFrameState retCode = EFrameIncomplete;
       
   100 
       
   101     // Start with new tile
       
   102     iUseNewTile = ETrue;
       
   103     if ( !iUseNextTile )
       
   104         {
       
   105         iFHState = EStateInUnknown;
       
   106         retCode = EFrameIncompleteRepositionRequest;
       
   107         }
       
   108     else
       
   109         {
       
   110         if ( !iSequential )
       
   111             {
       
   112             // Must be End of Codestream EOC
       
   113             iFHState = EStateInEOC;
       
   114             retCode = EFrameComplete;
       
   115             }
       
   116         else if ( iFHState == EStateInEOC )
       
   117             {
       
   118             retCode = EFrameComplete;
       
   119             }
       
   120         else
       
   121             {
       
   122             iFHState = EStateInUnknown;
       
   123             }
       
   124         }
       
   125     return retCode;
       
   126     }
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CJp2kReadCodec::IsDecodeTile
       
   130 // Is codec in the decoding state
       
   131 // (other items were commented in a header).
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 TBool CJp2kReadCodec::IsDecodeTile() const
       
   135     {
       
   136     return iDecodeTile;
       
   137     }
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CJp2kReadCodec::InitFrameHeader
       
   141 // (other items were commented in a header).
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 void CJp2kReadCodec::InitFrameHeader( TFrameInfo& aFrameInfo, CFrameImageData& aFrameData )
       
   145     {
       
   146     // Initialize internal data structure for holding frame header
       
   147     ASSERT( aFrameInfo.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised );
       
   148 
       
   149     iFrame = &aFrameInfo;
       
   150     iFrameData = &aFrameData;
       
   151     aFrameInfo.SetCurrentFrameState( TFrameInfo::EFrameInfoProcessingFrameHeader );
       
   152     }
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 // CJp2kReadCodec::ProcessFrameHeaderL
       
   156 // Collect the JP2 codestream Main Header information.
       
   157 // (other items were commented in a header).
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 TFrameState CJp2kReadCodec::ProcessFrameHeaderL( TBufPtr8& aData )
       
   161     {
       
   162     // Read frame header and fill up internal data structure
       
   163     TFrameState retCode = EFrameIncomplete;
       
   164 
       
   165     iReader.iPtr = aData.Ptr();
       
   166     iReader.iPtrStart = CONST_CAST( TUint8*, iReader.iPtr );
       
   167     iReader.iPtrEnd   = iReader.iPtrStart + aData.Length();
       
   168 
       
   169     while ( iFHState != EStateInSOT )
       
   170         {
       
   171         iReader.iPtrStartMarker = CONST_CAST( TUint8*, iReader.iPtr );
       
   172         switch ( iFHState )
       
   173             {
       
   174             case EStateInSOC:
       
   175                 {
       
   176                 retCode = ReadSOCL();
       
   177                 break;
       
   178                 }
       
   179             case EStateInSIZ:
       
   180                 {
       
   181                 retCode = ReadSIZL();
       
   182                 break;
       
   183                 }
       
   184             case EStateInCOD:
       
   185                 {
       
   186                 retCode = ReadCODL();
       
   187                 break;
       
   188                 }
       
   189             case EStateInCOC:
       
   190                 {
       
   191                 retCode = ReadCOCL();
       
   192                 break;
       
   193                 }
       
   194             case EStateInQCD:
       
   195                 {
       
   196                 retCode = ReadQCDL();
       
   197                 break;
       
   198                 }
       
   199             case EStateInQCC:
       
   200                 {
       
   201                 retCode = ReadQCCL();
       
   202                 break;
       
   203                 }
       
   204             case EStateInRGN:
       
   205                 {
       
   206                 retCode = ReadRGNL();
       
   207                 break;
       
   208                 }
       
   209             case EStateInPOC:
       
   210                 {
       
   211                 retCode = ReadPOCL();
       
   212                 break;
       
   213                 }
       
   214             case EStateInPPM:
       
   215                 {
       
   216                 retCode = ReadPPML();
       
   217                 break;
       
   218                 }
       
   219             case EStateInTLM:
       
   220                 {
       
   221                 retCode = ReadTLML();
       
   222                 break;
       
   223                 }
       
   224             case EStateInPLM:
       
   225                 {
       
   226                 retCode = ReadPLML();
       
   227                 break;
       
   228                 }
       
   229             case EStateInCRG:
       
   230                 {
       
   231                 retCode = ReadCRGL();
       
   232                 break;
       
   233                 }
       
   234             case EStateInCOM:
       
   235                 {
       
   236                 retCode = ReadCOML();
       
   237                 break;
       
   238                 }
       
   239             case EStateInUnknown:
       
   240                 {
       
   241                 // Update the internal state based on the Marker
       
   242                 retCode = UpdateStateFromMarkerL(); 
       
   243                 break;
       
   244                 }
       
   245             default:
       
   246                 {
       
   247                 // Unrecognized marker
       
   248                 User::Leave( KErrCorrupt );
       
   249                 break;
       
   250                 }
       
   251             }
       
   252         // Check for underflow
       
   253         if ( retCode != EFrameComplete ) 
       
   254             {
       
   255             aData.Shift( iReader.iPtr - iReader.iPtrStart );
       
   256             return retCode;
       
   257             }
       
   258 
       
   259         // Update the internal counter for data processed
       
   260         iReader.UpdateMainHeader();
       
   261         }
       
   262 
       
   263     // Convert the MainHeader's COM marker to TJp2kComment
       
   264     // and let the framework managing the buffer.
       
   265     TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
       
   266     for ( TInt index = 0; index < mainMarker.iCom.Count(); ++index )
       
   267         {
       
   268         TJp2kComment* jp2kComment = new ( ELeave ) TJp2kComment;
       
   269         CleanupDeletePushL( jp2kComment );
       
   270 
       
   271         jp2kComment->iComment = mainMarker.iCom[index]->iCcom;
       
   272 
       
   273         User::LeaveIfError( iFrameData->AppendImageData( jp2kComment ) );
       
   274         CleanupStack::Pop();
       
   275 
       
   276         // Transfer the ownership of the buffer from TMainMarker to framework
       
   277         User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kComment->iComment ) );
       
   278         mainMarker.iCom[index]->iCcom = 0;
       
   279         }
       
   280 
       
   281     // Convert some metadata from file format to TImageDataBlock derived objects
       
   282     ConvertImageDataL();
       
   283 
       
   284     // Try to sort PPM and PLM if there is one
       
   285     iImageInfo->DoCompactMainHeaderL();
       
   286 
       
   287     aData.Shift( iReader.iPtr - iReader.iPtrStart );
       
   288 
       
   289     // Fill up the image related information if it is not
       
   290     // JP2 file format
       
   291     if ( !( iJ2kInfo.iOption & TJ2kInfo::EJP2file ) )
       
   292         {
       
   293         const TSizMarker &sizMarker = iImageInfo->SizMarker();
       
   294 
       
   295         // To get the right output image size, we must compute the size tile by tile.
       
   296         // Compute the width of the output image
       
   297         TInt32 tileCompCanvasWidth = 0;
       
   298         TInt32 numHorTiles = iImageInfo->NumOfHorizTiles(); 
       
   299         TInt32 tileStartCanvas;
       
   300         TInt32 tileEndCanvas;
       
   301         TInt32 tileCompStartCanvas;
       
   302         for(TUint16 indexX = 0; indexX < numHorTiles; ++indexX )  
       
   303             {
       
   304             tileStartCanvas = Max( ( sizMarker.iXTOsiz + indexX * sizMarker.iXTsiz ), sizMarker.iXOsiz );
       
   305             tileEndCanvas = Min( ( sizMarker.iXTOsiz + ( indexX + 1 ) * sizMarker.iXTsiz ), sizMarker.iXsiz );
       
   306 
       
   307             // Add this tile's contribution to the total size
       
   308             tileCompStartCanvas = TJ2kUtils::Ceil( tileStartCanvas, sizMarker.iXRsiz[0] );
       
   309             tileCompCanvasWidth += TJ2kUtils::Ceil( tileEndCanvas, sizMarker.iXRsiz[0] ) - tileCompStartCanvas;
       
   310             }
       
   311         
       
   312         // Compute the height of the output image
       
   313         TInt32 tileCompCanvasHeight = 0;
       
   314         TInt32 numVerTiles = iImageInfo->NumOfVertTiles(); 
       
   315         for(TUint16 indexY = 0; indexY < numVerTiles; ++indexY )  
       
   316             {
       
   317             tileStartCanvas = Max( ( sizMarker.iYTOsiz + indexY * sizMarker.iYTsiz ), sizMarker.iYOsiz );
       
   318             tileEndCanvas = Min( ( sizMarker.iYTOsiz + ( indexY + 1 ) * sizMarker.iYTsiz ), sizMarker.iYsiz );
       
   319 
       
   320             // Add this tile's contribution to the total size
       
   321             tileCompStartCanvas = TJ2kUtils::Ceil( tileStartCanvas, sizMarker.iYRsiz[0] );
       
   322             tileCompCanvasHeight += TJ2kUtils::Ceil( tileEndCanvas, sizMarker.iYRsiz[0] ) - tileCompStartCanvas;
       
   323             }
       
   324         
       
   325         iFrame->iOverallSizeInPixels = TSize( tileCompCanvasWidth, tileCompCanvasHeight );
       
   326 
       
   327         iFrame->iFrameCoordsInPixels.SetRect( TPoint( 0, 0 ), iFrame->iOverallSizeInPixels );
       
   328         iFrame->iFrameSizeInTwips.SetSize( 0, 0 );
       
   329 
       
   330         for ( TUint16 index = 0; index < sizMarker.iCsiz; ++index )  
       
   331             {
       
   332             iFrame->iBitsPerPixel += ( ( sizMarker.iSsiz[index] & 0x7f ) + 1 );
       
   333             }
       
   334 
       
   335         // We can dither.
       
   336         iFrame->iFlags |= TFrameInfo::ECanDither;
       
   337 
       
   338         // Decoder is able to handle scaleable resolution
       
   339         iFrame->iFlags |= TFrameInfo::EConstantAspectRatio;
       
   340 
       
   341         if ( sizMarker.iCsiz > 1 )
       
   342             {
       
   343             iFrame->iFlags |= TFrameInfo::EColor;
       
   344             }
       
   345 
       
   346         // Animation is not allowed
       
   347         iFrame->iDelay = 0;
       
   348 
       
   349         switch ( iFrame->iBitsPerPixel )
       
   350             {
       
   351             case 1:
       
   352                 {
       
   353                 iFrame->iFrameDisplayMode = EGray2;
       
   354                 break;
       
   355                 }
       
   356             case 2:
       
   357                 {
       
   358                 iFrame->iFrameDisplayMode = EGray4;
       
   359                 break;
       
   360                 }
       
   361             case 4:
       
   362                 {
       
   363                 iFrame->iFrameDisplayMode = ( iFrame->iFlags & TFrameInfo::EColor ) ? EColor16 : EGray16;
       
   364                 break;
       
   365                 }
       
   366             case 8:
       
   367                 {
       
   368                 iFrame->iFrameDisplayMode = ( iFrame->iFlags & TFrameInfo::EColor ) ? EColor16M : EGray256;
       
   369                 break;
       
   370                 }
       
   371             case 12:
       
   372                 {
       
   373                 iFrame->iFrameDisplayMode = ( iFrame->iFlags & TFrameInfo::EColor ) ? EColor4K : EGray256;
       
   374                 break;
       
   375                 }
       
   376             case 16:
       
   377                 {
       
   378                 iFrame->iFrameDisplayMode = EColor64K;
       
   379                 break;
       
   380                 }
       
   381             case 24:
       
   382                 {
       
   383                 iFrame->iFrameDisplayMode = EColor16M;
       
   384                 break;
       
   385                 }
       
   386             default:
       
   387                 {
       
   388                 iFrame->iFrameDisplayMode = EColor64K;
       
   389                 break;
       
   390                 }
       
   391             }
       
   392         }
       
   393 
       
   394     // It is the offset that ICL framework used to read in
       
   395     // more data from the image file.
       
   396     iFrame->SetFrameDataOffset( iReader.iStartSOT );
       
   397 
       
   398     // Frame header has been processed without error
       
   399     // the flag is used by the ICL framework to determine
       
   400     // whether it should continue processing or halt with error
       
   401     iFrame->SetCurrentFrameState( TFrameInfo::EFrameInfoProcessingComplete );
       
   402 
       
   403     return retCode;
       
   404     }
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 // CJp2kReadCodec::InitFrameL
       
   408 // Called from ICL framework to initialise frame.
       
   409 // (other items were commented in a header).
       
   410 // -----------------------------------------------------------------------------
       
   411 //
       
   412 void CJp2kReadCodec::InitFrameL( TFrameInfo& /*aFrameInfo*/, CFrameImageData& /*aFrameData*/, 
       
   413                                  TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, 
       
   414                                  CFbsBitmap* /*aDestinationMask*/ )
       
   415     {
       
   416     // Always use ERgb mode unless specified in the JP2 file format
       
   417     TDisplayMode mode = ERgb;  
       
   418 
       
   419     TInt reductionFactor = ImageProcessorUtility::ReductionFactor( iFrame->iOverallSizeInPixels,
       
   420                                                                    aDestination.SizeInPixels() );
       
   421 
       
   422     iImageInfo->SetLevelDrop( (TUint8)reductionFactor );
       
   423 
       
   424     // If the codestream doesn't contain enough wavelet levels to do the resolution 
       
   425     // reduction required by the framework / calling application, "extraLevels" are 
       
   426     // assigned to perform the resolution reduction. The "extra" resolution drop is
       
   427     // performed at the output stage, i.e. all the samples are decoded, but only 
       
   428     // 1/4, 1/16, etc. are written to output.
       
   429     if(reductionFactor > iImageInfo->MainMarker().iCod.iNumOfLevels)
       
   430         {
       
   431         iImageInfo->SetExtraLevelDrop( (TUint8)(reductionFactor - iImageInfo->MainMarker().iCod.iNumOfLevels) );
       
   432         }
       
   433     else
       
   434         {
       
   435         iImageInfo->SetExtraLevelDrop( 0 );
       
   436         }
       
   437 
       
   438     CImageProcessor* imageProc = ImageProcessorUtility::NewImageProcessorL( aDestination, 
       
   439                                                                             0,
       
   440                                                                             mode,
       
   441                                                                             aDisableErrorDiffusion );
       
   442     TPoint startAt( iFrame->iFrameCoordsInPixels.iTl.iX,
       
   443                     iFrame->iFrameCoordsInPixels.iTl.iY );
       
   444 
       
   445     TRect imageSize( startAt, aDestination.SizeInPixels() );
       
   446 
       
   447     // Prepare the bitmap using the image size
       
   448     SetImageProcessor( imageProc );
       
   449     imageProc->PrepareL( aDestination, imageSize );
       
   450 
       
   451     // Clear bitmap so sensibly draw partial decodes
       
   452     ClearBitmapL(aDestination, KRgbWhite);
       
   453 
       
   454     iUseNewTile = ETrue;
       
   455     iReader.iNewDataStart = iFrame->FrameDataOffset();
       
   456     iStyleUsed = EUnknownDecoder;
       
   457 
       
   458     iProgressBar = EFalse;
       
   459     if ( ( iImageInfo->NumOfHorizTiles() == 1 ) &&
       
   460          ( iImageInfo->NumOfVertTiles() == 1 ) )
       
   461         {
       
   462         // To force a return immediately from ProcessFrameL()
       
   463         // on first entry to stimulate the occurrance of
       
   464         // the progress bar
       
   465         iProgressBar = ETrue;
       
   466         }
       
   467 
       
   468     if ( iFHState != EStateInSOT )
       
   469         {
       
   470         // We are in zoom in mode
       
   471         iUseNextTile = iSequential = EFalse;
       
   472         iFHState = EStateInSOT;
       
   473         iLastTileIndex = 0;
       
   474         iImageInfo->SetLastTilePartProcessed( (TUint16)0xffff );
       
   475         iImageWriter->SetNewImageProcessor( imageProc );
       
   476 
       
   477         if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
       
   478             {
       
   479             iReader.iCSLength = iJ2kInfo.iCSBoxLength;
       
   480             
       
   481             // We have read in all header information, so skip it
       
   482             if ( iReader.iCSLength > iReader.iStartSOT )
       
   483                 {
       
   484                 iReader.iCSLength -= iReader.iStartSOT;
       
   485                 }
       
   486             iReader.iDataUsed = 0;
       
   487             }
       
   488         }
       
   489     }
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // CJp2kReadCodec::ProcessFrameL
       
   493 // Collect the JP2 codestream Tile Part information.
       
   494 // (other items were commented in a header).
       
   495 // -----------------------------------------------------------------------------
       
   496 //
       
   497 TFrameState CJp2kReadCodec::ProcessFrameL(TBufPtr8& aSrc)
       
   498     {
       
   499     // Start decoding the compressed data stream
       
   500     TFrameState retCode = EFrameIncomplete;
       
   501 
       
   502     iReader.iPtr = aSrc.Ptr();
       
   503 
       
   504     iReader.iPtrStart = CONST_CAST( TUint8*, iReader.iPtr );
       
   505     iReader.iPtrEnd   = iReader.iPtrStart + aSrc.Length();
       
   506 
       
   507     while ( iFHState != EStateInEOC )
       
   508         {
       
   509         iReader.iPtrStartMarker = CONST_CAST( TUint8*, iReader.iPtr );
       
   510         switch ( iFHState )
       
   511             {
       
   512             case EStateInSOT:
       
   513                 {
       
   514                 retCode = ReadSOTL();
       
   515                 break;
       
   516                 }
       
   517             case EStateInSOD:
       
   518                 {
       
   519                 retCode = ReadSODL();
       
   520                 break;
       
   521                 }
       
   522             case EStateInBITSTREAM:
       
   523                 {
       
   524                 retCode = ReadBitStreamL();
       
   525                 break;
       
   526                 }
       
   527             case EStateInCOD:
       
   528                 {
       
   529                 retCode = ReadCODL( EFalse );
       
   530                 break;
       
   531                 }
       
   532             case EStateInCOC:
       
   533                 {
       
   534                 retCode = ReadCOCL( EFalse );
       
   535                 break;
       
   536                 }
       
   537             case EStateInQCD:
       
   538                 {
       
   539                 retCode = ReadQCDL( EFalse );
       
   540                 break;
       
   541                 }
       
   542             case EStateInQCC:
       
   543                 {
       
   544                 retCode = ReadQCCL( EFalse );
       
   545                 break;
       
   546                 }
       
   547             case EStateInRGN:
       
   548                 {
       
   549                 retCode = ReadRGNL( EFalse );
       
   550                 break;
       
   551                 }
       
   552             case EStateInPOC:
       
   553                 {
       
   554                 retCode = ReadPOCL( EFalse );
       
   555                 break;
       
   556                 }
       
   557             case EStateInPPT:
       
   558                 {
       
   559                 retCode = ReadPPTL();
       
   560                 break;
       
   561                 }
       
   562             case EStateInPLT:
       
   563                 {
       
   564                 retCode = ReadPLTL();
       
   565                 break;
       
   566                 }
       
   567             case EStateInCOM:
       
   568                 {
       
   569                 retCode = ReadCOML( EFalse );
       
   570                 break;
       
   571                 }
       
   572             case EStateInUnknown:
       
   573                 {
       
   574                 // Update the internal state based on the Marker
       
   575                 retCode = UpdateStateFromMarkerL();
       
   576                 break;
       
   577                 }
       
   578             case EStateInSkipTile:
       
   579                 {
       
   580                 retCode = ReadSkipTileL();
       
   581                 break;
       
   582                 }
       
   583             default:
       
   584                 {
       
   585                 // Unrecognized marker
       
   586                 User::Leave( KErrCorrupt );
       
   587                 break;
       
   588                 }
       
   589             }
       
   590         // Check for underflow
       
   591         if ( retCode != EFrameComplete ) 
       
   592             {
       
   593             // Request to jump to another section of the image file
       
   594             if ( retCode == EFrameIncompleteRepositionRequest )
       
   595                 {
       
   596                 // Update the internal counter for data processed
       
   597                 iReader.UpdateTileHeader();
       
   598                 }
       
   599 
       
   600             aSrc.Shift( iReader.iPtr - iReader.iPtrStart );
       
   601             return retCode;
       
   602             }
       
   603 
       
   604         if ( iFHState != EStateInSkipTile && iFHState != EStateInSOT )
       
   605             {
       
   606             // Update the internal counter for data processed
       
   607             // only for the current tile
       
   608             iReader.UpdateTileHeader();
       
   609             }
       
   610 
       
   611         if ( ( iProgressBar && iFHState != EStateInEOC ) || iDecodeTile )
       
   612             {
       
   613             iProgressBar = EFalse;
       
   614             aSrc.Shift( iReader.iPtr - iReader.iPtrStart );
       
   615             return EFrameIncomplete;
       
   616             }
       
   617         }
       
   618 
       
   619     if ( iDecodeTile == EFalse )
       
   620         {
       
   621         ImageProcessor()->FlushPixels();
       
   622         }
       
   623 
       
   624     return EFrameComplete;
       
   625     }
       
   626 
       
   627 // -----------------------------------------------------------------------------
       
   628 // CJp2kReadCodec::GetNewDataPosition
       
   629 // Get the new offset where data should be read from.
       
   630 // (other items were commented in a header).
       
   631 // -----------------------------------------------------------------------------
       
   632 //
       
   633 void CJp2kReadCodec::GetNewDataPosition( TInt& aPosition, TInt& /*aLength*/ )
       
   634     {
       
   635     // Set new offset position so that
       
   636     // ICL framework will read in more image data for processing
       
   637     aPosition = iReader.iNewDataStart + iJ2kInfo.iCSOffset;
       
   638     }
       
   639 
       
   640 // -----------------------------------------------------------------------------
       
   641 // CJp2kReadCodec::CJp2kReadCodec
       
   642 // C++ default constructor can NOT contain any code, that
       
   643 // might leave.
       
   644 // -----------------------------------------------------------------------------
       
   645 //
       
   646 CJp2kReadCodec::CJp2kReadCodec( const TJ2kInfo& aJ2kInfo ) :
       
   647     iJ2kInfo( aJ2kInfo )
       
   648     {
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // CJp2kReadCodec::ConstructL
       
   653 // Symbian 2nd phase constructor can leave.
       
   654 // -----------------------------------------------------------------------------
       
   655 //
       
   656 void CJp2kReadCodec::ConstructL()
       
   657     {
       
   658     iImageInfo = new ( ELeave ) CJ2kImageInfo;
       
   659 
       
   660     // Invoke base class 2nd phase constructor.
       
   661     CImageProcessorReadCodec::ConstructL();
       
   662     }
       
   663 
       
   664 // -----------------------------------------------------------------------------
       
   665 // CJp2kReadCodec::ReadSOCL
       
   666 // Verify and process Start of Codestream (SOC marker).
       
   667 // (other items were commented in a header).
       
   668 // -----------------------------------------------------------------------------
       
   669 //
       
   670 TFrameState CJp2kReadCodec::ReadSOCL()
       
   671     {    
       
   672     const TUint8* dataPtr = iReader.iPtr;
       
   673 
       
   674     if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
       
   675         {
       
   676         // Codestream box in JP2 file format
       
   677         iReader.iCSLength = iJ2kInfo.iCSBoxLength;
       
   678         iReader.iPtr += KJ2kBoxTypeLength;
       
   679 
       
   680         if ( iReader.iCSLength == 1 )
       
   681             {
       
   682             // The XLBox shall exist and contains the actual length of the box
       
   683             // XLBox is 8 bytes width
       
   684             iReader.iCSLength = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   685             iReader.iCSLength += PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   686 
       
   687             // Populate back to the iJ2kInfo
       
   688             CONST_CAST( TJ2kInfo&, iJ2kInfo ).iCSBoxLength = iReader.iCSLength;
       
   689             }
       
   690         }
       
   691 
       
   692     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerSize )
       
   693         {
       
   694         // Underflow, backup the pointer to the beginning
       
   695         iReader.iPtr = dataPtr;
       
   696         return EFrameIncomplete;
       
   697         }
       
   698 
       
   699     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSOC )
       
   700         {
       
   701         // Unrecognized SOC marker
       
   702         User::Leave( KErrCorrupt );
       
   703         }
       
   704 
       
   705     // SIZ marker shall immediately follow the SOC marker
       
   706     iFHState = EStateInSIZ;
       
   707 
       
   708     return EFrameComplete;
       
   709     }
       
   710 
       
   711 // -----------------------------------------------------------------------------
       
   712 // CJp2kReadCodec::ReadSIZL
       
   713 // Verify and process Image and Tile Size (SIZ marker).
       
   714 // (other items were commented in a header).
       
   715 // -----------------------------------------------------------------------------
       
   716 //
       
   717 TFrameState CJp2kReadCodec::ReadSIZL()
       
   718     {
       
   719     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
   720         {
       
   721         // Underflow
       
   722         return EFrameIncomplete;
       
   723         }
       
   724 
       
   725     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSIZ )
       
   726         {
       
   727         // Unrecognized SIZ marker
       
   728         User::Leave( KErrCorrupt );
       
   729         }
       
   730 
       
   731     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
   732 
       
   733     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
   734         {
       
   735         // Underflow, backup the iterator to the beginning of the marker
       
   736         iReader.iPtr -= KMarkerMinLength;
       
   737         return EFrameIncomplete;
       
   738         }
       
   739 
       
   740     TSizMarker& sizMarker = CONST_CAST( TSizMarker&, iImageInfo->SizMarker() );
       
   741 
       
   742     sizMarker.iRsiz   = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
   743     sizMarker.iXsiz   = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   744     sizMarker.iYsiz   = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   745     sizMarker.iXOsiz  = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   746     sizMarker.iYOsiz  = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   747     sizMarker.iXTsiz  = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   748     sizMarker.iYTsiz  = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   749     sizMarker.iXTOsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   750     sizMarker.iYTOsiz = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
   751     sizMarker.iCsiz   = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
   752     
       
   753     if(sizMarker.iXOsiz > sizMarker.iXsiz || sizMarker.iYOsiz > sizMarker.iYsiz)
       
   754         {
       
   755         // Image offset is larger than image size, exit
       
   756         User::Leave( KErrCorrupt );
       
   757         }
       
   758 
       
   759     if(sizMarker.iXTOsiz > sizMarker.iXsiz || sizMarker.iYTOsiz > sizMarker.iYsiz)
       
   760         {
       
   761         // Tile offset is larger than image size, exit
       
   762         User::Leave( KErrCorrupt );
       
   763         }
       
   764 
       
   765     for ( TUint16 index = 0; index < sizMarker.iCsiz; ++index )
       
   766         {
       
   767         // Component's information
       
   768         User::LeaveIfError( sizMarker.iSsiz.Append( *iReader.iPtr++ ) );
       
   769         User::LeaveIfError( sizMarker.iXRsiz.Append( *iReader.iPtr++ ) );
       
   770         User::LeaveIfError( sizMarker.iYRsiz.Append( *iReader.iPtr++ ) );
       
   771         
       
   772         if((( sizMarker.iSsiz[index] & 0x7f ) + 1) > KMaxBitdepth )
       
   773             {
       
   774             // Invalid bitdepth for this component, exit
       
   775             User::Leave( KErrCorrupt );
       
   776             }
       
   777         }
       
   778 
       
   779     if ( iJ2kInfo.iCMPList.Count() > sizMarker.iCsiz )
       
   780         {
       
   781         // Populate the remaining component Rsiz using component 0's Rsiz
       
   782         TUint16 indexi = (TUint16)( iJ2kInfo.iCMPList.Count() - sizMarker.iCsiz );
       
   783         while ( indexi )
       
   784             {
       
   785             User::LeaveIfError( sizMarker.iXRsiz.Append( sizMarker.iXRsiz[0] ) );
       
   786             User::LeaveIfError( sizMarker.iYRsiz.Append( sizMarker.iYRsiz[0] ) );
       
   787             --indexi;
       
   788             }
       
   789         }
       
   790 
       
   791     // Make sure we read all the data
       
   792     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
   793         {
       
   794         // We must be missing some data in the marker
       
   795         User::Leave( KErrCorrupt );
       
   796         }
       
   797 
       
   798     // Any valid marker may come after SIZ marker
       
   799     iFHState = EStateInUnknown;
       
   800 
       
   801     return EFrameComplete;
       
   802     }
       
   803 
       
   804 // -----------------------------------------------------------------------------
       
   805 // CJp2kReadCodec::ReadCODL
       
   806 // Verify and process Coding Style Default (COD marker).
       
   807 // (other items were commented in a header).
       
   808 // -----------------------------------------------------------------------------
       
   809 //
       
   810 TFrameState CJp2kReadCodec::ReadCODL( TBool aMain )
       
   811     {
       
   812     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
   813         {
       
   814         // Underflow
       
   815         return EFrameIncomplete;
       
   816         }
       
   817 
       
   818     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCOD )
       
   819         {
       
   820         // Unrecognized COD marker
       
   821         User::Leave(KErrCorrupt);
       
   822         }
       
   823 
       
   824     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
   825 
       
   826     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
   827         {
       
   828         // Underflow, backup the iterator to the beginning of the marker
       
   829         iReader.iPtr -= KMarkerMinLength;
       
   830         return EFrameIncomplete;
       
   831         }
       
   832 
       
   833     TCODMarker *codMarker = NULL;
       
   834 
       
   835     if ( aMain )
       
   836         {
       
   837         TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
       
   838         codMarker = &mainMarker.iCod;
       
   839         }
       
   840     else
       
   841         {
       
   842         // COD in Tile Part Header
       
   843         codMarker = new ( ELeave ) TCODMarker;        
       
   844         CleanupDeletePushL( codMarker );
       
   845         }
       
   846 
       
   847     codMarker->iScod = *iReader.iPtr++;
       
   848     codMarker->iProgressionOrder = *iReader.iPtr++;
       
   849     codMarker->iNumOfLayers = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
   850     codMarker->iColorTransformation = *iReader.iPtr++;
       
   851     codMarker->iNumOfLevels = *iReader.iPtr++;
       
   852 
       
   853     TUint8 tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
       
   854     codMarker->iCodeBlockSiz.iWidth  = 1 << tmp;
       
   855 
       
   856     tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
       
   857     codMarker->iCodeBlockSiz.iHeight = 1 << tmp;
       
   858 
       
   859     codMarker->iCodeBlockStyle = *iReader.iPtr++;
       
   860     codMarker->iWaveletTransformation = *iReader.iPtr++;
       
   861 
       
   862     if ( codMarker->iScod & 0x01 )
       
   863         {
       
   864         // Entropy coder with precincts defined below
       
   865         codMarker->iPrecinctSiz = HBufC8::NewL( codMarker->iNumOfLevels + 1 );
       
   866         for ( TUint8 index = 0; index < codMarker->iNumOfLevels + 1; ++index )
       
   867             {
       
   868             codMarker->iPrecinctSiz->Des().Append( *iReader.iPtr++ );
       
   869             }
       
   870         }
       
   871 
       
   872     // Make sure we read all the data
       
   873     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
   874         {
       
   875         // We must be missing some data in the marker
       
   876         User::Leave( KErrCorrupt );
       
   877         }
       
   878 
       
   879     if ( !aMain )
       
   880         {
       
   881         CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
   882 
       
   883         // Append COD to the current tile and decrement the tile length
       
   884         tile.AppendCOD( codMarker, markerLength + KMarkerSize );
       
   885         CleanupStack::Pop();
       
   886         }
       
   887 
       
   888     // Any valid marker may come after COD marker
       
   889     iFHState = EStateInUnknown;
       
   890     return EFrameComplete;
       
   891     }
       
   892 
       
   893 // -----------------------------------------------------------------------------
       
   894 // CJp2kReadCodec::ReadCOCL
       
   895 // Verify and process Coding Style Component (COC marker).
       
   896 // (other items were commented in a header).
       
   897 // -----------------------------------------------------------------------------
       
   898 //
       
   899 TFrameState CJp2kReadCodec::ReadCOCL( TBool aMain )
       
   900     {
       
   901     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
   902         {
       
   903         // Underflow
       
   904         return EFrameIncomplete;
       
   905         }
       
   906 
       
   907     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCOC )
       
   908         {
       
   909         // Unrecognized COC marker
       
   910         User::Leave( KErrCorrupt );
       
   911         }
       
   912 
       
   913     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
   914 
       
   915     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
   916         {
       
   917         // Underflow, backup the iterator to the beginning of the marker
       
   918         iReader.iPtr -= KMarkerMinLength;
       
   919         return EFrameIncomplete;
       
   920         }
       
   921 
       
   922     const TSizMarker& sizMarker = iImageInfo->SizMarker();
       
   923 
       
   924     TCOCMarker *cocMarker = new ( ELeave ) TCOCMarker;    
       
   925     CleanupDeletePushL(cocMarker);
       
   926 
       
   927     if ( sizMarker.iCsiz < 257 )
       
   928         {
       
   929         // 8 bits component
       
   930         cocMarker->iCcoc = *iReader.iPtr++;
       
   931         }
       
   932     else
       
   933         {
       
   934         // 16 bits component
       
   935         cocMarker->iCcoc = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
   936         }
       
   937 
       
   938     cocMarker->iScoc = *iReader.iPtr++;
       
   939     cocMarker->iNumOfLevels = *iReader.iPtr++;
       
   940 
       
   941     TUint8 tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
       
   942     cocMarker->iCodeBlockSiz.iWidth  = 1 << tmp;
       
   943 
       
   944     tmp = (TUint8)( ( *iReader.iPtr++ ) + 2 );
       
   945     cocMarker->iCodeBlockSiz.iHeight = 1 << tmp;
       
   946 
       
   947     cocMarker->iCodeBlockStyle = *iReader.iPtr++;
       
   948     cocMarker->iWaveletTransformation = *iReader.iPtr++;
       
   949 
       
   950     if ( cocMarker->iScoc & 0x01 )
       
   951         {
       
   952         // Entropy coder with precincts defined below
       
   953         cocMarker->iPrecinctSiz = HBufC8::NewL( cocMarker->iNumOfLevels + 1 );
       
   954         for ( TUint8 index = 0; index < cocMarker->iNumOfLevels + 1; ++index )
       
   955             {
       
   956             cocMarker->iPrecinctSiz->Des().Append( *iReader.iPtr++ );
       
   957             }
       
   958         }
       
   959 
       
   960     // Make sure we read all the data
       
   961     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
   962         {
       
   963         // We must be missing some data in the marker
       
   964         User::Leave( KErrCorrupt );
       
   965         }
       
   966 
       
   967     if ( aMain )
       
   968         {
       
   969         iImageInfo->AppendCOCL( cocMarker );
       
   970         }
       
   971     else
       
   972         {
       
   973         CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
   974 
       
   975         // Append COC to the current tile and decrement the tile length
       
   976         tile.AppendCOCL( cocMarker, markerLength + KMarkerSize );
       
   977         }
       
   978     CleanupStack::Pop();
       
   979 
       
   980     // Any valid marker may come after COC marker
       
   981     iFHState = EStateInUnknown;
       
   982 
       
   983     return EFrameComplete;
       
   984     }
       
   985 
       
   986 // -----------------------------------------------------------------------------
       
   987 // CJp2kReadCodec::ReadQCDL
       
   988 // Verify and process Quantization Default (QCD marker).
       
   989 // (other items were commented in a header).
       
   990 // -----------------------------------------------------------------------------
       
   991 //
       
   992 TFrameState CJp2kReadCodec::ReadQCDL( TBool aMain )
       
   993     {
       
   994     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
   995         {   
       
   996         // Underflow
       
   997         return EFrameIncomplete;
       
   998         }
       
   999 
       
  1000     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KQCD )
       
  1001         {
       
  1002         // Unrecognized QCD marker
       
  1003         User::Leave( KErrCorrupt );
       
  1004         }
       
  1005 
       
  1006     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1007     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1008         {
       
  1009         // Underflow, backup the iterator to the beginning of the marker
       
  1010         iReader.iPtr -= KMarkerMinLength;
       
  1011         return EFrameIncomplete;
       
  1012         }
       
  1013 
       
  1014     TQCDMarker *qcdMarker = NULL;
       
  1015 
       
  1016     if ( aMain )
       
  1017         {
       
  1018         TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
       
  1019         qcdMarker = &mainMarker.iQcd;
       
  1020         }
       
  1021     else
       
  1022         {
       
  1023         // QCD in Tile Part Header
       
  1024         qcdMarker = new ( ELeave ) TQCDMarker;
       
  1025         
       
  1026         CleanupDeletePushL( qcdMarker );
       
  1027         }
       
  1028 
       
  1029     qcdMarker->iSqcd = *iReader.iPtr++;
       
  1030 
       
  1031     if ( qcdMarker->iSqcd & 0x01 )
       
  1032         {
       
  1033         // Scalar derived (values signalled for NLL subband only)
       
  1034         TUint16 tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1035         qcdMarker->iExponent = HBufC8::NewL(1);
       
  1036         qcdMarker->iExponent->Des().Append( (TUint8)( (tmp >> 11) & 0x1f ) );
       
  1037         qcdMarker->iMantissa = HBufC16::NewL(1);
       
  1038         qcdMarker->iMantissa->Des().Append( (TUint16)( tmp & 0x07ff ) );
       
  1039         }
       
  1040     else
       
  1041         {
       
  1042         TInt entries = markerLength - ( iReader.iPtr - iReader.iPtrStartMarker ) + KMarkerSize;
       
  1043         if ( qcdMarker->iSqcd & 0x1f )
       
  1044             {
       
  1045             // Word oriented
       
  1046             TUint16 tmp;
       
  1047             qcdMarker->iExponent = HBufC8::NewL( entries / 2 );
       
  1048             qcdMarker->iMantissa = HBufC16::NewL( entries / 2 );
       
  1049 
       
  1050             while ( entries >= 2 )
       
  1051                 {
       
  1052                 tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1053                 qcdMarker->iExponent->Des().Append((TUint8)( ( tmp >> 11) & 0x1f ) );
       
  1054                 qcdMarker->iMantissa->Des().Append((TUint16)( tmp & 0x07ff ) );
       
  1055                 entries -= 2;
       
  1056             }
       
  1057         }
       
  1058         else
       
  1059             {
       
  1060             // No quantization
       
  1061             qcdMarker->iExponent = HBufC8::NewL( entries );
       
  1062             while ( entries )
       
  1063                 {
       
  1064                 qcdMarker->iExponent->Des().Append( (TUint8)( ( *iReader.iPtr++ >> 3 ) & 0x1f ) );
       
  1065                 --entries;
       
  1066                 }
       
  1067             }
       
  1068         }
       
  1069 
       
  1070     // Make sure we read all the data
       
  1071     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1072         {
       
  1073         // We must be missing some data in the marker
       
  1074         User::Leave( KErrCorrupt );
       
  1075         }
       
  1076 
       
  1077     if ( !aMain )
       
  1078         {
       
  1079         CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  1080 
       
  1081         // Append QCD to the current tile and decrement the tile length
       
  1082         tile.AppendQCD( qcdMarker, markerLength + KMarkerSize );
       
  1083         CleanupStack::Pop();
       
  1084         }
       
  1085 
       
  1086     // Any valid marker may come after QCD marker
       
  1087     iFHState = EStateInUnknown;
       
  1088 
       
  1089     return EFrameComplete;
       
  1090     }
       
  1091 
       
  1092 // -----------------------------------------------------------------------------
       
  1093 // CJp2kReadCodec::ReadQCCL
       
  1094 // Verify and process Quantization Component (QCC marker).
       
  1095 // (other items were commented in a header).
       
  1096 // -----------------------------------------------------------------------------
       
  1097 //
       
  1098 TFrameState CJp2kReadCodec::ReadQCCL(TBool aMain)
       
  1099     {
       
  1100     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1101         {
       
  1102         // Underflow
       
  1103         return EFrameIncomplete;
       
  1104         }
       
  1105 
       
  1106     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KQCC )
       
  1107         {
       
  1108         // Unrecognized QCC marker
       
  1109         User::Leave( KErrCorrupt );
       
  1110         }
       
  1111 
       
  1112     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1113     if ( ( iReader.iPtrEnd - iReader.iPtr ) < (markerLength - KMarkerLength ) )
       
  1114         {
       
  1115         // Underflow, backup the iterator to the beginning of the marker
       
  1116         iReader.iPtr -= KMarkerMinLength;
       
  1117         return EFrameIncomplete;
       
  1118         }
       
  1119 
       
  1120     const TSizMarker& sizMarker = iImageInfo->SizMarker();
       
  1121 
       
  1122     TQCCMarker *qccMarker = new (ELeave) TQCCMarker;
       
  1123 
       
  1124     CleanupDeletePushL( qccMarker );
       
  1125 
       
  1126     if ( sizMarker.iCsiz < 257 )
       
  1127         {
       
  1128         // 8 bits component
       
  1129         qccMarker->iCqcc = *iReader.iPtr++;
       
  1130         }
       
  1131     else
       
  1132         {
       
  1133         // 16 bit component
       
  1134         qccMarker->iCqcc = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1135         }
       
  1136 
       
  1137     qccMarker->iSqcc = *iReader.iPtr++;
       
  1138 
       
  1139     if ( qccMarker->iSqcc & 0x01 )
       
  1140         {
       
  1141         // Scalar derived (values signalled for NLL subband only)
       
  1142         TUint16 tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1143         qccMarker->iExponent = HBufC8::NewL(1);
       
  1144         qccMarker->iExponent->Des().Append( (TUint8)( ( tmp >> 11 ) & 0x1f ) );
       
  1145         qccMarker->iMantissa = HBufC16::NewL(1);
       
  1146         qccMarker->iMantissa->Des().Append( (TUint16)( tmp & 0x07ff ) );
       
  1147         }
       
  1148     else
       
  1149         {
       
  1150         TInt entries = markerLength - ( iReader.iPtr - iReader.iPtrStartMarker ) + KMarkerSize;
       
  1151         if ( qccMarker->iSqcc & 0x1f )
       
  1152             {
       
  1153             // Word oriented
       
  1154             TUint16 tmp;
       
  1155             qccMarker->iExponent = HBufC8::NewL( entries / 2 );
       
  1156             qccMarker->iMantissa = HBufC16::NewL( entries / 2 );
       
  1157 
       
  1158             while ( entries >= 2 )
       
  1159                 {
       
  1160                 tmp = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1161                 qccMarker->iExponent->Des().Append( (TUint8)( ( tmp >> 11 ) & 0x1f ) );
       
  1162                 qccMarker->iMantissa->Des().Append( (TUint16)( tmp & 0x07ff ) );
       
  1163                 entries -= 2;
       
  1164                 }
       
  1165             }
       
  1166         else
       
  1167             {
       
  1168             // No quantization
       
  1169             qccMarker->iExponent = HBufC8::NewL( entries );
       
  1170             while ( entries )
       
  1171                 {
       
  1172                 qccMarker->iExponent->Des().Append( (TUint8)( ( *iReader.iPtr++ >> 3 ) & 0x1f ) );
       
  1173                 --entries;
       
  1174                 }
       
  1175             }
       
  1176         }
       
  1177 
       
  1178     // Make sure we read all the data
       
  1179     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1180         {
       
  1181         // We must be missing some data in the marker
       
  1182         User::Leave( KErrCorrupt );
       
  1183         }
       
  1184 
       
  1185     if ( aMain )
       
  1186         {
       
  1187         iImageInfo->AppendQCCL( qccMarker );
       
  1188         }
       
  1189     else
       
  1190         {
       
  1191         CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  1192 
       
  1193         // Append QCC to the current tile and decrement the tile length
       
  1194         tile.AppendQCCL( qccMarker, markerLength + KMarkerSize );
       
  1195         }
       
  1196     CleanupStack::Pop();
       
  1197 
       
  1198     // Any valid marker may come after QCC marker
       
  1199     iFHState = EStateInUnknown;
       
  1200 
       
  1201     return EFrameComplete;
       
  1202     }
       
  1203 
       
  1204 // -----------------------------------------------------------------------------
       
  1205 // CJp2kReadCodec::ReadRGNL
       
  1206 // Verify and process Region of Interest (RGN marker).
       
  1207 // (other items were commented in a header).
       
  1208 // -----------------------------------------------------------------------------
       
  1209 //
       
  1210 TFrameState CJp2kReadCodec::ReadRGNL( TBool aMain )
       
  1211     {
       
  1212     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1213         {
       
  1214         // Underflow
       
  1215         return EFrameIncomplete;
       
  1216         }
       
  1217 
       
  1218     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KRGN )
       
  1219         {
       
  1220         // Unrecognized RGN marker
       
  1221         User::Leave( KErrCorrupt );
       
  1222         }
       
  1223 
       
  1224     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1225 
       
  1226     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1227         {
       
  1228         // Underflow, backup the iterator to the beginning of the marker
       
  1229         iReader.iPtr -= KMarkerMinLength;
       
  1230         return EFrameIncomplete;
       
  1231         }
       
  1232 
       
  1233     const TSizMarker& sizMarker = iImageInfo->SizMarker();
       
  1234 
       
  1235     TRGNMarker *rgnMarker = new ( ELeave ) TRGNMarker;
       
  1236     CleanupDeletePushL( rgnMarker );
       
  1237 
       
  1238     if ( sizMarker.iCsiz < 257 )
       
  1239         {
       
  1240         // 8 bits component
       
  1241         rgnMarker->iCrgn = *iReader.iPtr++;
       
  1242         }
       
  1243     else
       
  1244         {
       
  1245         // 16 bits component
       
  1246         rgnMarker->iCrgn = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1247         }
       
  1248 
       
  1249     rgnMarker->iSrgn  = *iReader.iPtr++;
       
  1250     rgnMarker->iSPrgn = *iReader.iPtr++;
       
  1251 
       
  1252     // Make sure we read all the data
       
  1253     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1254         {
       
  1255         // We must be missing some data in the marker
       
  1256         User::Leave( KErrCorrupt );
       
  1257         }
       
  1258 
       
  1259     if ( aMain )
       
  1260         {
       
  1261         iImageInfo->AppendRGNL( rgnMarker );
       
  1262         }
       
  1263     else
       
  1264         {
       
  1265         CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  1266 
       
  1267         // Append RGN to the current tile and decrement the tile length
       
  1268         tile.AppendRGNL( rgnMarker, markerLength + KMarkerSize );
       
  1269         }
       
  1270     CleanupStack::Pop();
       
  1271 
       
  1272     // Any valid marker may come after RGN marker
       
  1273     iFHState = EStateInUnknown;
       
  1274 
       
  1275     return EFrameComplete;
       
  1276     }
       
  1277 
       
  1278 // -----------------------------------------------------------------------------
       
  1279 // CJp2kReadCodec::ReadPOCL
       
  1280 // Verify and process Progression Order Change ( POC marker ).
       
  1281 // (other items were commented in a header).
       
  1282 // -----------------------------------------------------------------------------
       
  1283 //
       
  1284 TFrameState CJp2kReadCodec::ReadPOCL( TBool aMain )
       
  1285     {
       
  1286     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1287         {
       
  1288         // Underflow
       
  1289         return EFrameIncomplete;
       
  1290         }
       
  1291 
       
  1292     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPOC )
       
  1293         {
       
  1294         // Unrecognized COC marker
       
  1295         User::Leave( KErrCorrupt );
       
  1296         }
       
  1297 
       
  1298     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1299     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1300         {
       
  1301         // Underflow, backup the iterator to the beginning of the marker
       
  1302         iReader.iPtr -= KMarkerMinLength;
       
  1303         return EFrameIncomplete;
       
  1304         }
       
  1305 
       
  1306     const TSizMarker& sizMarker = iImageInfo->SizMarker();
       
  1307 
       
  1308     TPOCMarker *pocMarker = new ( ELeave ) TPOCMarker;
       
  1309     CleanupDeletePushL( pocMarker );
       
  1310 
       
  1311     TInt entries = markerLength - KMarkerSize;
       
  1312     TInt sizEntry = ( sizMarker.iCsiz < 257 ) ? 7 : 9;
       
  1313 
       
  1314     while ( entries >= sizEntry )
       
  1315         {
       
  1316         User::LeaveIfError( pocMarker->iRSpoc.Append( *iReader.iPtr++ ) );
       
  1317 
       
  1318         if ( sizMarker.iCsiz < 257 )
       
  1319             {
       
  1320             // 8 bits component
       
  1321             User::LeaveIfError( pocMarker->iCSpoc.Append( *iReader.iPtr++ ) );
       
  1322             }
       
  1323         else
       
  1324             {
       
  1325             // 16 bits component
       
  1326             User::LeaveIfError( pocMarker->iCSpoc.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
       
  1327             }
       
  1328         User::LeaveIfError( pocMarker->iLYEpoc.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
       
  1329         User::LeaveIfError( pocMarker->iREpoc.Append( *iReader.iPtr++ ) );
       
  1330         if ( sizMarker.iCsiz < 257 )
       
  1331             {
       
  1332             // 8 bits component
       
  1333             User::LeaveIfError( pocMarker->iCEpoc.Append( *iReader.iPtr++ ) );
       
  1334             }
       
  1335         else
       
  1336             {
       
  1337             // 16 bits component
       
  1338             User::LeaveIfError( pocMarker->iCEpoc.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
       
  1339             }
       
  1340         User::LeaveIfError( pocMarker->iPpoc.Append( *iReader.iPtr++ ) );
       
  1341 
       
  1342         entries -= sizEntry;
       
  1343         }
       
  1344 
       
  1345     // Make sure we read all the data
       
  1346     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1347         {
       
  1348         // We must be missing some data in the marker
       
  1349         User::Leave( KErrCorrupt );
       
  1350         }
       
  1351 
       
  1352     if ( aMain )
       
  1353         {
       
  1354         iImageInfo->AppendPOCL( pocMarker );
       
  1355         }
       
  1356     else
       
  1357         {
       
  1358         CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  1359         
       
  1360         // Append POC to the current tile and decrement the tile length
       
  1361         tile.AppendPOCL( pocMarker, markerLength + KMarkerSize );
       
  1362         }
       
  1363     CleanupStack::Pop(  );
       
  1364 
       
  1365     // Any valid marker may come after POC marker
       
  1366     iFHState = EStateInUnknown;
       
  1367 
       
  1368     return EFrameComplete;
       
  1369     }
       
  1370 
       
  1371 // -----------------------------------------------------------------------------
       
  1372 // CJp2kReadCodec::ReadPPML
       
  1373 // Verify and process Packed Packet Headers, Main Header ( PPM marker ).
       
  1374 // (other items were commented in a header).
       
  1375 // -----------------------------------------------------------------------------
       
  1376 //
       
  1377 TFrameState CJp2kReadCodec::ReadPPML()
       
  1378     {
       
  1379     TUint8 isUnderflow = EFalse;
       
  1380     if ( !iPreviousPPM )
       
  1381         {
       
  1382         if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1383             {
       
  1384             // Underflow
       
  1385             return EFrameIncomplete;
       
  1386             }
       
  1387 
       
  1388         if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPPM )
       
  1389             {
       
  1390             // Unrecognized PPM marker
       
  1391             User::Leave( KErrCorrupt );
       
  1392             }
       
  1393 
       
  1394         TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1395         if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( KMarkerLength + 1 ) )
       
  1396             {
       
  1397             // Underflow, we need Zppm and Nppm to be in the buffer
       
  1398             // backup the iterator to the beginning of the marker
       
  1399             iReader.iPtr -= KMarkerMinLength;
       
  1400             return EFrameIncomplete;
       
  1401             }
       
  1402 
       
  1403         if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1404             {
       
  1405             // Underflow, will keep reading
       
  1406             isUnderflow = ETrue;
       
  1407             }
       
  1408 
       
  1409         TPPMMarker *ppmMarker = new ( ELeave ) TPPMMarker;        
       
  1410         CleanupDeletePushL( ppmMarker );
       
  1411 
       
  1412         ppmMarker->iZppm = *iReader.iPtr++;
       
  1413         TUint32 entries = (TUint32)( markerLength - KMarkerSize - 1 );
       
  1414 
       
  1415         ppmMarker->iNppm = entries;
       
  1416         ppmMarker->iIppm = HBufC8::NewL( entries );
       
  1417 
       
  1418         if ( !isUnderflow )
       
  1419             {
       
  1420             ppmMarker->iIppm->Des(  ).Append( iReader.iPtr, entries );
       
  1421             iReader.iPtr += entries;
       
  1422             iPreviousPPM = 0;
       
  1423 
       
  1424             // Make sure we read all the data
       
  1425             if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1426                 {
       
  1427                 // We must be missing some data in the marker
       
  1428                 User::Leave( KErrCorrupt );
       
  1429                 }
       
  1430             }
       
  1431         else
       
  1432             {
       
  1433             ppmMarker->iIppm->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1434             ppmMarker->iRemainder = (TUint32)( entries - ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1435             iReader.iPtr = iReader.iPtrEnd;
       
  1436             iPreviousPPM = ppmMarker;
       
  1437             }
       
  1438 
       
  1439         // Insert the new PPM marker into the right order
       
  1440         TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
       
  1441         TUint8 tmp = ETrue;
       
  1442         if ( mainMarker.iPpm.Count() > 0 &&
       
  1443              mainMarker.iPpm[mainMarker.iPpm.Count() - 1]->iZppm > ppmMarker->iZppm )
       
  1444             {
       
  1445             for ( entries = 0; entries < (TUint32)mainMarker.iPpm.Count(); ++entries )
       
  1446                 {
       
  1447                 // Order by iZppm of the PPM marker
       
  1448                 if ( mainMarker.iPpm[entries]->iZppm > ppmMarker->iZppm )
       
  1449                     {
       
  1450                     User::LeaveIfError( mainMarker.iPpm.Insert( ppmMarker, entries ) );
       
  1451 
       
  1452                     tmp = EFalse;
       
  1453                     entries = (TUint32)mainMarker.iPpm.Count();  
       
  1454                     }
       
  1455                 }
       
  1456             }
       
  1457 
       
  1458         if ( tmp )
       
  1459             {
       
  1460             User::LeaveIfError( mainMarker.iPpm.Append( ppmMarker ) );
       
  1461             }
       
  1462         CleanupStack::Pop();
       
  1463         }
       
  1464     else
       
  1465         {
       
  1466         if ( (TUint32)( iReader.iPtrEnd - iReader.iPtr ) < iPreviousPPM->iRemainder )
       
  1467             {
       
  1468             // Continue reading incomplete COM marker
       
  1469             iPreviousPPM->iIppm->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1470             iPreviousPPM->iRemainder = (TUint32)( iPreviousPPM->iRemainder - ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1471             iReader.iPtr = iReader.iPtrEnd;
       
  1472             isUnderflow = ETrue;
       
  1473             }
       
  1474         else
       
  1475             {
       
  1476             // We have the complete COM marker now
       
  1477             iPreviousPPM->iIppm->Des().Append( iReader.iPtr, iPreviousPPM->iRemainder );
       
  1478             iReader.iPtr += iPreviousPPM->iRemainder;
       
  1479             iPreviousPPM->iRemainder = 0;
       
  1480             iPreviousPPM = 0;
       
  1481             }
       
  1482         }
       
  1483 
       
  1484     if ( !isUnderflow )
       
  1485         {
       
  1486         // Any valid marker may come after PPM marker
       
  1487         iFHState = EStateInUnknown;
       
  1488         return EFrameComplete;
       
  1489         }
       
  1490     else
       
  1491         {
       
  1492         // Underflow, stay in the same state
       
  1493         iReader.UpdateMainHeader();
       
  1494         return EFrameIncomplete;
       
  1495         }
       
  1496     }
       
  1497 
       
  1498 // -----------------------------------------------------------------------------
       
  1499 // CJp2kReadCodec::ReadTLML
       
  1500 // Verify and process Tile Part Lengths, Main Header ( TLM marker ).
       
  1501 // (other items were commented in a header).
       
  1502 // -----------------------------------------------------------------------------
       
  1503 //
       
  1504 TFrameState CJp2kReadCodec::ReadTLML()
       
  1505     {
       
  1506     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1507         {
       
  1508         // Underflow
       
  1509         return EFrameIncomplete;
       
  1510         }
       
  1511 
       
  1512     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KTLM )
       
  1513         {
       
  1514         // Unrecognized TLM marker
       
  1515         User::Leave( KErrCorrupt );
       
  1516         }
       
  1517 
       
  1518     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1519     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1520         {
       
  1521         // Underflow, backup the iterator to the beginning of the marker
       
  1522         iReader.iPtr -= KMarkerMinLength;
       
  1523         return EFrameIncomplete;
       
  1524         }
       
  1525 
       
  1526     TTLMMarker *tlmMarker = new ( ELeave ) TTLMMarker;    
       
  1527     CleanupDeletePushL( tlmMarker );
       
  1528 
       
  1529     tlmMarker->iZtlm = *iReader.iPtr++;
       
  1530     tlmMarker->iStlm = *iReader.iPtr++;
       
  1531 
       
  1532     TInt entries = markerLength - ( 2 * KMarkerSize );
       
  1533     TUint8 st = (TUint8)( ( tlmMarker->iStlm >> 4 ) & 0x03 );
       
  1534     TUint8 sp = (TUint8)( ( tlmMarker->iStlm >> 6 ) & 0x01 );
       
  1535     TInt sizEntry = st;
       
  1536     sizEntry += ( sp ? 4 : 2 );
       
  1537 
       
  1538     while ( entries >= sizEntry )
       
  1539         {
       
  1540         if ( st == 1 )
       
  1541             {
       
  1542             // 8 bits tile index
       
  1543             User::LeaveIfError( tlmMarker->iTtlm.Append( *iReader.iPtr++ ) );
       
  1544             }
       
  1545         else if ( st == 2 )
       
  1546             {
       
  1547             // 16 bits tile index
       
  1548             User::LeaveIfError( tlmMarker->iTtlm.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
       
  1549             }
       
  1550         if ( sp )   //lint !e961    no else is needed here at the end of if...else if
       
  1551             {
       
  1552             // 32 bits length
       
  1553             User::LeaveIfError( tlmMarker->iPtlm.Append( PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr ) ) );
       
  1554             }
       
  1555         else
       
  1556             {
       
  1557             // 16 bits length
       
  1558             User::LeaveIfError( tlmMarker->iPtlm.Append( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) ) );
       
  1559             }
       
  1560         entries -= sizEntry;
       
  1561         }
       
  1562 
       
  1563     // Make sure we read all the data
       
  1564     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1565         {
       
  1566         // We must be missing some data in the marker
       
  1567         User::Leave( KErrCorrupt );
       
  1568         }
       
  1569 
       
  1570     // Insert the new TLM marker into the right order
       
  1571     TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
       
  1572     sp = 1;
       
  1573     for ( entries = 0; entries < mainMarker.iTlm.Count(); ++entries )
       
  1574         {
       
  1575         // Order by iZtlm of the TLM marker
       
  1576         if ( mainMarker.iTlm[entries]->iZtlm > tlmMarker->iZtlm )
       
  1577             {
       
  1578             User::LeaveIfError( mainMarker.iTlm.Insert( tlmMarker, entries ) );
       
  1579             sp = 0;
       
  1580             entries = mainMarker.iTlm.Count();
       
  1581             }
       
  1582         }
       
  1583 
       
  1584     if ( sp )
       
  1585         {
       
  1586         User::LeaveIfError( mainMarker.iTlm.Append( tlmMarker ) );
       
  1587         }
       
  1588     CleanupStack::Pop();
       
  1589 
       
  1590     // Any valid marker may come after TLM marker
       
  1591     iFHState = EStateInUnknown;
       
  1592 
       
  1593     return EFrameComplete;
       
  1594     }
       
  1595 
       
  1596 // -----------------------------------------------------------------------------
       
  1597 // CJp2kReadCodec::ReadPLML
       
  1598 // Verify and process Packet Length, Main Header ( PLM marker ).
       
  1599 // (other items were commented in a header).
       
  1600 // -----------------------------------------------------------------------------
       
  1601 //
       
  1602 TFrameState CJp2kReadCodec::ReadPLML()
       
  1603     {
       
  1604     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1605         {
       
  1606         // Underflow
       
  1607         return EFrameIncomplete;
       
  1608         }
       
  1609 
       
  1610     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPLM )
       
  1611         {
       
  1612         // Unrecognized PLM marker
       
  1613         User::Leave( KErrCorrupt );
       
  1614         }
       
  1615 
       
  1616     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1617     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1618         {
       
  1619         // Underflow, backup the iterator to the beginning of the marker
       
  1620         iReader.iPtr -= KMarkerMinLength;
       
  1621         return EFrameIncomplete;
       
  1622         }
       
  1623 
       
  1624     TPLMMarker *plmMarker =  new ( ELeave ) TPLMMarker;    
       
  1625     CleanupDeletePushL( plmMarker );
       
  1626 
       
  1627     plmMarker->iZplm = *iReader.iPtr++;
       
  1628     TUint32 entries = (TUint32)( markerLength - KMarkerSize - 1 );
       
  1629 
       
  1630     plmMarker->iNplm = (TUint8)entries;
       
  1631     plmMarker->iIplm = HBufC8::NewL( entries );
       
  1632     plmMarker->iIplm->Des().Append( iReader.iPtr, entries );
       
  1633     iReader.iPtr += entries;
       
  1634 
       
  1635     // Make sure we read all the data
       
  1636     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1637         {
       
  1638         // We must be missing some data in the marker
       
  1639         User::Leave( KErrCorrupt );
       
  1640         }
       
  1641 
       
  1642     // Insert the new PLM marker into the right order
       
  1643     TMainMarker& mainMarker = CONST_CAST( TMainMarker&, iImageInfo->MainMarker() );
       
  1644     TUint8 tmp = ETrue;
       
  1645 
       
  1646     if ( mainMarker.iPlm.Count() > 0 &&
       
  1647          mainMarker.iPlm[mainMarker.iPlm.Count() - 1]->iZplm > plmMarker->iZplm )
       
  1648         {
       
  1649         for ( entries = 0; entries < (TUint32)mainMarker.iPlm.Count(); ++entries )
       
  1650             {
       
  1651             // Order by iZplm of the PLM marker
       
  1652             if ( mainMarker.iPlm[entries]->iZplm > plmMarker->iZplm )
       
  1653                 {
       
  1654                 User::LeaveIfError( mainMarker.iPlm.Insert( plmMarker, entries ) );
       
  1655                 tmp = EFalse;
       
  1656                 entries = (TUint32)mainMarker.iPlm.Count();     
       
  1657             }
       
  1658         }
       
  1659     }
       
  1660 
       
  1661     if ( tmp )
       
  1662         {
       
  1663         User::LeaveIfError( mainMarker.iPlm.Append( plmMarker ) );
       
  1664         }
       
  1665     CleanupStack::Pop();
       
  1666 
       
  1667     // Any valid marker may come after PLM marker
       
  1668     iFHState = EStateInUnknown;
       
  1669 
       
  1670     return EFrameComplete;
       
  1671     }
       
  1672 
       
  1673 // -----------------------------------------------------------------------------
       
  1674 // CJp2kReadCodec::ReadCRGL
       
  1675 // Verify and process Component Registration, Main Header ( CRG marker ).
       
  1676 // (other items were commented in a header).
       
  1677 // -----------------------------------------------------------------------------
       
  1678 //
       
  1679 TFrameState CJp2kReadCodec::ReadCRGL()
       
  1680     {
       
  1681     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1682         {
       
  1683         // Underflow
       
  1684         return EFrameIncomplete;
       
  1685         }
       
  1686 
       
  1687     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCRG )
       
  1688         {
       
  1689         // Unrecognized CRG marker
       
  1690         User::Leave( KErrCorrupt );
       
  1691         }
       
  1692 
       
  1693     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1694     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1695         {
       
  1696         // Underflow, backup the iterator to the beginning of the marker
       
  1697         iReader.iPtr -= KMarkerMinLength;
       
  1698         return EFrameIncomplete;
       
  1699         }
       
  1700 
       
  1701     TCRGMarker *crgMarker = new ( ELeave ) TCRGMarker;    
       
  1702     CleanupDeletePushL( crgMarker );
       
  1703 
       
  1704     TInt entries = markerLength - KMarkerSize;
       
  1705     TUint16 xCrg;
       
  1706     TUint16 yCrg;
       
  1707     while ( entries )
       
  1708         {
       
  1709         xCrg = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1710         yCrg = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1711         User::LeaveIfError( crgMarker->iXYcrg.Append( TPoint( xCrg, yCrg ) ) );
       
  1712         entries -= 4;
       
  1713         }
       
  1714 
       
  1715     // Make sure we read all the data
       
  1716     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1717         {
       
  1718         // We must be missing some data in the marker
       
  1719         User::Leave( KErrCorrupt );
       
  1720         }
       
  1721 
       
  1722     iImageInfo->AppendCRGL( crgMarker );
       
  1723 
       
  1724     CleanupStack::Pop(  );
       
  1725 
       
  1726     // Any valid marker may come after CRG marker
       
  1727     iFHState = EStateInUnknown;
       
  1728 
       
  1729     return EFrameComplete;
       
  1730     }
       
  1731 
       
  1732 // -----------------------------------------------------------------------------
       
  1733 // CJp2kReadCodec::ReadCOML
       
  1734 // Verify and process Comment ( COM marker ).
       
  1735 // (other items were commented in a header).
       
  1736 // -----------------------------------------------------------------------------
       
  1737 //
       
  1738 TFrameState CJp2kReadCodec::ReadCOML( TBool aMain )
       
  1739     {
       
  1740     TUint8 isUnderflow = EFalse;
       
  1741     if ( !iPreviousCOM )
       
  1742         {
       
  1743         if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1744             {
       
  1745             // Underflow
       
  1746             return EFrameIncomplete;
       
  1747             }
       
  1748 
       
  1749         if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KCME )
       
  1750             {
       
  1751             // Unrecognized COM marker
       
  1752             User::Leave( KErrCorrupt );
       
  1753             }
       
  1754 
       
  1755         TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1756         if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerLength )
       
  1757             {
       
  1758             // Underflow, we need Rcom to be in the buffer
       
  1759             // backup the iterator to the beginning of the marker
       
  1760             iReader.iPtr -= KMarkerMinLength;
       
  1761             return EFrameIncomplete;
       
  1762             }
       
  1763 
       
  1764         if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1765             {
       
  1766             // Underflow, will keep reading
       
  1767             isUnderflow = ETrue;
       
  1768             }
       
  1769 
       
  1770         TCOMMarker* comMarker = new ( ELeave ) TCOMMarker;        
       
  1771         CleanupDeletePushL( comMarker );
       
  1772 
       
  1773         comMarker->iRcom = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1774         TInt entries = markerLength - ( 2 * KMarkerSize );
       
  1775 
       
  1776         comMarker->iCcom = HBufC8::NewL( entries );
       
  1777         if ( !isUnderflow )
       
  1778             {
       
  1779             comMarker->iCcom->Des().Append( iReader.iPtr, entries );
       
  1780             iReader.iPtr += entries;
       
  1781             iPreviousCOM = 0;
       
  1782 
       
  1783             // Make sure we read all the data
       
  1784             if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1785                 {
       
  1786                 // We must be missing some data in the marker
       
  1787                 User::Leave( KErrCorrupt );
       
  1788                 }
       
  1789             }
       
  1790         else
       
  1791             {
       
  1792             comMarker->iCcom->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1793             comMarker->iRemainder = (TUint16)( entries - ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1794             iReader.iPtr = iReader.iPtrEnd;
       
  1795             iPreviousCOM = comMarker;
       
  1796             }
       
  1797 
       
  1798         if ( aMain )
       
  1799             {
       
  1800             iImageInfo->AppendCOML( comMarker );
       
  1801             }
       
  1802         else
       
  1803             {
       
  1804             CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  1805             
       
  1806             // Append COM to the current tile and decrement the tile length
       
  1807             tile.AppendCOML( comMarker, markerLength + KMarkerSize );
       
  1808             }
       
  1809         CleanupStack::Pop();
       
  1810         }
       
  1811     else
       
  1812         {
       
  1813         if ( ( iReader.iPtrEnd - iReader.iPtr ) < iPreviousCOM->iRemainder )
       
  1814             {
       
  1815             // Continue reading incomplete COM marker
       
  1816             iPreviousCOM->iCcom->Des().Append( iReader.iPtr, ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1817             iPreviousCOM->iRemainder = (TUint16)( iPreviousCOM->iRemainder - ( iReader.iPtrEnd - iReader.iPtr ) );
       
  1818             iReader.iPtr = iReader.iPtrEnd;
       
  1819             isUnderflow = ETrue;
       
  1820         }
       
  1821         else
       
  1822             {
       
  1823             // We have the complete COM marker now
       
  1824             iPreviousCOM->iCcom->Des(  ).Append( iReader.iPtr, iPreviousCOM->iRemainder );
       
  1825             iReader.iPtr += iPreviousCOM->iRemainder;
       
  1826             iPreviousCOM->iRemainder = 0;
       
  1827             iPreviousCOM = 0;
       
  1828             }
       
  1829         }
       
  1830 
       
  1831     if ( !isUnderflow )
       
  1832         {
       
  1833         // Any valid marker may come after COM marker
       
  1834         iFHState = EStateInUnknown;
       
  1835         return EFrameComplete;
       
  1836         }
       
  1837     else
       
  1838         {
       
  1839         // Underflow, stay in the same state
       
  1840         if ( aMain )
       
  1841             {
       
  1842             iReader.UpdateMainHeader(  );
       
  1843             }
       
  1844         return EFrameIncomplete;
       
  1845         }
       
  1846     }
       
  1847 
       
  1848 // -----------------------------------------------------------------------------
       
  1849 // CJp2kReadCodec::ReadSOTL
       
  1850 // Verify and process Start of Tile Part ( SOT marker ).
       
  1851 // (other items were commented in a header).
       
  1852 // -----------------------------------------------------------------------------
       
  1853 //
       
  1854 TFrameState CJp2kReadCodec::ReadSOTL()
       
  1855     {
       
  1856     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  1857         {
       
  1858         // Underflow
       
  1859         return EFrameIncomplete;
       
  1860         }
       
  1861 
       
  1862     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSOT )
       
  1863         {
       
  1864         // Unrecognized SOT marker
       
  1865         User::Leave( KErrCorrupt );
       
  1866         }
       
  1867 
       
  1868     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1869     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  1870         {
       
  1871         // Underflow, backup the iterator to the beginning of the marker
       
  1872         iReader.iPtr -= KMarkerMinLength;
       
  1873         return EFrameIncomplete;
       
  1874         }
       
  1875 
       
  1876     TSotMarker sotMarker;
       
  1877     sotMarker.iIsot = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  1878     sotMarker.iPsot = PtrReadUtil::ReadBigEndianUint32Inc( iReader.iPtr );
       
  1879     sotMarker.iTPsot = *iReader.iPtr++;
       
  1880     sotMarker.iTNsot = *iReader.iPtr++;
       
  1881     
       
  1882     if(sotMarker.iIsot >= ( iImageInfo->NumOfHorizTiles() * iImageInfo->NumOfVertTiles() ))
       
  1883         {
       
  1884         // Invalid tile index, exceeds the number of tiles, exit
       
  1885         User::Leave( KErrCorrupt );
       
  1886         }
       
  1887 
       
  1888     if ( sotMarker.iPsot == 0 )
       
  1889         {
       
  1890         // Try to look for tile part length information
       
  1891         // from the TLM in the main header - if there is one
       
  1892         iImageInfo->GetFromTLM( sotMarker );
       
  1893         }
       
  1894 
       
  1895     iImageInfo->IncrementLastTilePartProcessed();
       
  1896 
       
  1897     if ( iUseNewTile )
       
  1898         {
       
  1899         if ( sotMarker.iIsot < iLastTileIndex )
       
  1900             {
       
  1901             // Skip all tiles with iIsot smaller than the iLastTileIndex
       
  1902             iReader.iSkipLength = sotMarker.iPsot - markerLength - KMarkerSize;
       
  1903             iUseNewTile = EFalse;
       
  1904             iFHState = EStateInSkipTile;
       
  1905             return EFrameComplete;
       
  1906             }
       
  1907 
       
  1908         if(sotMarker.iTPsot >= sotMarker.iTNsot)
       
  1909             {
       
  1910             // Skip the tiles where tile part index is larger than 
       
  1911             // the number of tile parts
       
  1912             iReader.iSkipLength = sotMarker.iPsot - markerLength - KMarkerSize;
       
  1913             iUseNewTile = EFalse;
       
  1914             iFHState = EStateInSkipTile;
       
  1915             return EFrameComplete;
       
  1916             }
       
  1917 	
       
  1918         // Start using this tile as the current tile
       
  1919         iLastTileIndex = sotMarker.iIsot;
       
  1920 
       
  1921         // Save the next tile offset
       
  1922         iReader.iNewDataStart += sotMarker.iPsot;
       
  1923         iUseNextTile = iSequential = ETrue;
       
  1924         }
       
  1925     else
       
  1926         {
       
  1927         if ( sotMarker.iIsot != iLastTileIndex )
       
  1928             {
       
  1929             if ( iUseNextTile )
       
  1930                 {
       
  1931                 if ( sotMarker.iIsot > iLastTileIndex )
       
  1932                     {
       
  1933                     iUseNextTile = EFalse;
       
  1934                     }
       
  1935                 }
       
  1936             iSequential = EFalse;
       
  1937 
       
  1938             // Skip all tiles that are not equal to current tile
       
  1939             iReader.iSkipLength = sotMarker.iPsot - markerLength - KMarkerSize;
       
  1940             iFHState = EStateInSkipTile;
       
  1941             return EFrameComplete;
       
  1942             }
       
  1943         else
       
  1944             {
       
  1945             // Tiles are in sequential order
       
  1946             if ( iUseNextTile && iSequential )
       
  1947                 {
       
  1948                 // Save the next tile offset
       
  1949                 iReader.iNewDataStart += sotMarker.iPsot;
       
  1950             }
       
  1951         }
       
  1952     }
       
  1953 
       
  1954     CJ2kTileInfo *tile = 0;
       
  1955     if ( iUseNewTile )
       
  1956         {
       
  1957         tile = CJ2kTileInfo::NewLC( *iImageInfo, iReader );
       
  1958         }
       
  1959     else
       
  1960         {
       
  1961         tile = CONST_CAST( CJ2kTileInfo*, &iImageInfo->TileAt( iLastTileIndex ) );
       
  1962         }
       
  1963 
       
  1964     // Set the SOT marker
       
  1965     tile->SetSotMarker( sotMarker );
       
  1966 
       
  1967     if ( sotMarker.iPsot )
       
  1968         {
       
  1969         // Decrement the tile length
       
  1970         tile->SetTileLength( sotMarker.iPsot - markerLength - KMarkerSize );
       
  1971         }
       
  1972 
       
  1973     // Make sure we read all the data
       
  1974     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  1975         {
       
  1976         // We must be missing some data in the marker
       
  1977         User::Leave( KErrCorrupt );
       
  1978         }
       
  1979 
       
  1980     if ( iUseNewTile )
       
  1981         { 
       
  1982         iImageInfo->Append( tile );
       
  1983         CleanupStack::Pop();
       
  1984         iUseNewTile = EFalse;
       
  1985         }
       
  1986 
       
  1987     // Any valid marker may come after SOT marker
       
  1988     iFHState = EStateInUnknown;
       
  1989     return EFrameComplete;
       
  1990 
       
  1991     }
       
  1992 
       
  1993 // -----------------------------------------------------------------------------
       
  1994 // CJp2kReadCodec::ReadSODL
       
  1995 // Verify and process Start of Data ( SOD marker ).
       
  1996 // (other items were commented in a header).
       
  1997 // -----------------------------------------------------------------------------
       
  1998 //
       
  1999 TFrameState CJp2kReadCodec::ReadSODL()
       
  2000     {
       
  2001     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KSOD )
       
  2002         {
       
  2003         // Unrecognized SOD marker
       
  2004         User::Leave( KErrCorrupt );
       
  2005         }
       
  2006 
       
  2007     CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  2008 
       
  2009     TUint32& length = tile.TileLength();
       
  2010     if ( length )
       
  2011         {
       
  2012         // Decrement the tile length
       
  2013         length -= KMarkerSize;
       
  2014         }
       
  2015 
       
  2016     // Initialize the tile only for tile part 0
       
  2017     if ( tile.IsFirstTilePart() )
       
  2018         {
       
  2019         tile.InitializeL();
       
  2020         iImageInfo->SetLastTilePartProcessed( tile.SotMarker().iIsot );
       
  2021         }
       
  2022 
       
  2023     if ( tile.IsPPT() )
       
  2024         {
       
  2025         // Use packet header information from PPT
       
  2026         tile.UsePPTL();
       
  2027         }
       
  2028     else if ( iImageInfo->IsPPM() )
       
  2029         {
       
  2030         // Use packet header information from PPM
       
  2031         iImageInfo->UsePPM( tile );
       
  2032         }
       
  2033     else
       
  2034         {
       
  2035         tile.SetPacketHeaderReader( &iReader );
       
  2036         }
       
  2037 
       
  2038     if ( ( iImageInfo->NumOfHorizTiles() == 1 ) &&
       
  2039          ( iImageInfo->NumOfVertTiles() == 1 ) )
       
  2040         {
       
  2041         // To force a return immediately from ProcessFrameL()
       
  2042         // on first entry to stimulate the occurrance of
       
  2043         // the progress bar
       
  2044         iProgressBar = ETrue;
       
  2045         }
       
  2046 
       
  2047     // We know that bitstream will follow SOD marker
       
  2048     iFHState = EStateInBITSTREAM;
       
  2049 
       
  2050     return EFrameComplete;
       
  2051     }
       
  2052 
       
  2053 // -----------------------------------------------------------------------------
       
  2054 // CJp2kReadCodec::ReadBitStreamL
       
  2055 // Verify and process BitStream Data.
       
  2056 // (other items were commented in a header).
       
  2057 // -----------------------------------------------------------------------------
       
  2058 //
       
  2059 TFrameState CJp2kReadCodec::ReadBitStreamL()
       
  2060     {
       
  2061     CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  2062     TUint32& length = tile.TileLength(  );
       
  2063 
       
  2064     if ( length )
       
  2065         {
       
  2066         if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( TInt32 )length )
       
  2067             {
       
  2068             // Larger bitstream will not fit into the internal
       
  2069             // buffer size, so process a chunk at a time
       
  2070             // we have to add some kind of state information
       
  2071             // so that we know where to continue and process
       
  2072             if ( tile.IsSpeedup() )
       
  2073                 {
       
  2074                 // For RLCP/RPCL progression order
       
  2075                 if ( tile.LastLevelProcessed() <= tile.NumOfLevelsPOC() )
       
  2076                     {
       
  2077                     tile.ReadBitStreamL();
       
  2078                     }
       
  2079                 else
       
  2080                     {
       
  2081                     // discard any data that beyond the required resolution level
       
  2082                     if ( !tile.IsPPT() )
       
  2083                         {
       
  2084                         if ( iImageInfo->IsPPM() )
       
  2085                             {
       
  2086                             // discard current packet header in PPM marker
       
  2087                             iImageInfo->ResetPPM();
       
  2088                             }
       
  2089                         }
       
  2090                     iReader.iPtr = iReader.iPtrEnd;
       
  2091                     }
       
  2092                 }
       
  2093             else
       
  2094                 {
       
  2095                 tile.ReadBitStreamL();
       
  2096                 }
       
  2097 
       
  2098             length -= ( iReader.iPtr - iReader.iPtrStartMarker );
       
  2099             iReader.UpdateTileHeader();
       
  2100 
       
  2101             // stay in the current state
       
  2102             return EFrameIncomplete;
       
  2103             }
       
  2104 
       
  2105         // We are sure that all tile part data fit into the buffer
       
  2106         // so just go ahead and process it
       
  2107         if ( tile.IsSpeedup() )
       
  2108             {
       
  2109             // For RLCP/RPCL progression order
       
  2110             if ( tile.LastLevelProcessed() <= tile.NumOfLevelsPOC() )
       
  2111                 {
       
  2112                 tile.ReadBitStreamL( ETrue );
       
  2113                 iReader.TryReAlignReader();
       
  2114                 }
       
  2115             else
       
  2116                 {
       
  2117                 // discard any data that beyond the required resolution level
       
  2118                 if ( !tile.IsPPT() )
       
  2119                     {
       
  2120                     if ( iImageInfo->IsPPM() )
       
  2121                         {
       
  2122                         // discard current packet header in PPM marker
       
  2123                         iImageInfo->ResetPPM();
       
  2124                         }
       
  2125                     }
       
  2126                 iReader.iPtr += length;
       
  2127                 }
       
  2128             }
       
  2129         else
       
  2130             {
       
  2131             tile.ReadBitStreamL( ETrue );
       
  2132             iReader.TryReAlignReader();
       
  2133             }
       
  2134 
       
  2135         length -= ( iReader.iPtr - iReader.iPtrStartMarker );
       
  2136 
       
  2137         if ( tile.IsSpeedup() )
       
  2138             {
       
  2139             // discard any data that beyond the required resolution level
       
  2140             if ( !tile.IsPPT() )
       
  2141                 {
       
  2142                 if ( iImageInfo->IsPPM() )
       
  2143                     {
       
  2144                     // discard current packet header in PPM marker
       
  2145                     iImageInfo->ResetPPM();
       
  2146                     }
       
  2147                 }
       
  2148             iReader.iPtr += length;
       
  2149             length = 0;
       
  2150             }
       
  2151 
       
  2152         // Sanity check
       
  2153         if ( length != 0 )
       
  2154             {
       
  2155             User::Leave( KErrCorrupt );
       
  2156             }
       
  2157 
       
  2158         if ( tile.IsLastTilePart() )
       
  2159             {
       
  2160             tile.DoReleaseUnusedMarkers();
       
  2161 
       
  2162             // proceed to the decoding state
       
  2163             iDecodeTile = ETrue;
       
  2164 
       
  2165             // Start with new tile
       
  2166             iUseNewTile = ETrue;
       
  2167             if ( !iUseNextTile )
       
  2168                 {
       
  2169                 iFHState = EStateInUnknown;
       
  2170                 return EFrameIncompleteRepositionRequest;
       
  2171                 }
       
  2172             else
       
  2173                 {
       
  2174                 if ( !iSequential )
       
  2175                     {
       
  2176                     // Must be End of Codestream EOC
       
  2177                     iFHState = EStateInEOC;
       
  2178                     iReader.iPtr += KMarkerSize;
       
  2179                     return EFrameComplete;
       
  2180                     }
       
  2181                 }
       
  2182             }
       
  2183 
       
  2184         // We do not know what is the next marker
       
  2185         // either next SOT or EOC
       
  2186         iFHState = EStateInUnknown;
       
  2187         }
       
  2188     else
       
  2189         {
       
  2190         if ( iReader.iPtrEnd == iReader.iPtr )
       
  2191             {
       
  2192             // Assume that we have done with the image
       
  2193             iFHState = EStateInEOC;
       
  2194             }
       
  2195         else
       
  2196             {
       
  2197             if ( ( iReader.iPtrEnd - iReader.iPtr ) >= 2 )
       
  2198                 {
       
  2199                 TUint16 marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
       
  2200                 if ( marker == KSOT )
       
  2201                     {
       
  2202                     // Next SOT marker is found
       
  2203                     iFHState = EStateInSOT;
       
  2204                     }
       
  2205                 else if ( marker == EStateInEOC )
       
  2206                     {
       
  2207                     // End of Codestream is found
       
  2208                     iFHState = EStateInEOC;
       
  2209                     iReader.iPtr += KMarkerSize;
       
  2210                     }
       
  2211                 else
       
  2212                     {
       
  2213                     tile.ReadBitStreamL();
       
  2214                     marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
       
  2215 
       
  2216                     if ( marker == KSOT || marker == KEOC )
       
  2217                         {
       
  2218                         iFHState = EStateInUnknown;
       
  2219 
       
  2220                         if ( tile.IsLastTilePart() )
       
  2221                             {
       
  2222                             tile.DoReleaseUnusedMarkers();
       
  2223 
       
  2224                             // proceed to the decoding state
       
  2225                             iDecodeTile = ETrue;
       
  2226 
       
  2227                             // Start with new tile
       
  2228                             iUseNewTile = ETrue;
       
  2229                             if ( !iUseNextTile )
       
  2230                                 {
       
  2231                                 return EFrameIncompleteRepositionRequest;
       
  2232                                 }
       
  2233                             else
       
  2234                                 {
       
  2235                                 if ( !iSequential )
       
  2236                                     {
       
  2237                                     // Must be End of Codestream EOC
       
  2238                                     iFHState = EStateInEOC;
       
  2239                                     iReader.iPtr += KMarkerSize;
       
  2240                                     }
       
  2241                                 }
       
  2242                             }
       
  2243                         }
       
  2244                     else
       
  2245                         {
       
  2246                         iReader.UpdateTileHeader();
       
  2247 
       
  2248                         // Stay in the current state
       
  2249                         return EFrameIncomplete;
       
  2250                         }
       
  2251                     }
       
  2252                 }
       
  2253             else
       
  2254                 {
       
  2255                 iReader.UpdateTileHeader();                
       
  2256 
       
  2257                 // Stay in the current state
       
  2258                 return EFrameIncomplete;
       
  2259                 }
       
  2260             }
       
  2261         }
       
  2262 
       
  2263     if ( ( iImageInfo->NumOfHorizTiles() == 1 ) &&
       
  2264          ( iImageInfo->NumOfVertTiles() == 1 ) )
       
  2265         {
       
  2266         // To force a return immediately from ProcessFrameL()
       
  2267         // on first entry to stimulate the occurrance of
       
  2268         // the progress bar
       
  2269         iProgressBar = ETrue;
       
  2270         }
       
  2271 
       
  2272     return EFrameComplete;
       
  2273     }
       
  2274 
       
  2275 // -----------------------------------------------------------------------------
       
  2276 // CJp2kReadCodec::ReadPPTL
       
  2277 // Verify and process Packed Packet Headers, Tile Part Header ( PPT marker ).
       
  2278 // (other items were commented in a header).
       
  2279 // -----------------------------------------------------------------------------
       
  2280 //
       
  2281 TFrameState CJp2kReadCodec::ReadPPTL()
       
  2282     {
       
  2283     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  2284         {
       
  2285         // Underflow
       
  2286         return EFrameIncomplete;
       
  2287         }
       
  2288 
       
  2289     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPPT )
       
  2290         {
       
  2291         // Unrecognized PPT marker
       
  2292         User::Leave( KErrCorrupt );
       
  2293         }
       
  2294 
       
  2295     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  2296 
       
  2297     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  2298         {
       
  2299         // Underflow, backup the iterator to the beginning of the marker
       
  2300         iReader.iPtr -= KMarkerMinLength;
       
  2301         return EFrameIncomplete;
       
  2302         }
       
  2303 
       
  2304     TPPTMarker *pptMarker = new ( ELeave ) TPPTMarker;    
       
  2305     CleanupDeletePushL( pptMarker );
       
  2306 
       
  2307     TInt entries = markerLength - KMarkerSize - 1;
       
  2308     pptMarker->iZppt = *iReader.iPtr++;
       
  2309     pptMarker->iIppt = HBufC8::NewL( entries );
       
  2310     pptMarker->iIppt->Des(  ).Append( iReader.iPtr, entries );
       
  2311     iReader.iPtr += entries;
       
  2312 
       
  2313     // Make sure we read all the data
       
  2314     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  2315         {
       
  2316         // We must be missing some data in the marker
       
  2317         User::Leave( KErrCorrupt );
       
  2318         }
       
  2319 
       
  2320     CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  2321     
       
  2322     // Append PPT to the current tile and decrement the tile length
       
  2323     tile.AppendPPTL( pptMarker, markerLength + KMarkerSize );
       
  2324     CleanupStack::Pop();
       
  2325 
       
  2326     // Any valid marker may come after PPT marker
       
  2327     iFHState = EStateInUnknown;
       
  2328 
       
  2329     return EFrameComplete;
       
  2330     }
       
  2331 
       
  2332 // -----------------------------------------------------------------------------
       
  2333 // CJp2kReadCodec::ReadPLTL
       
  2334 // Verify and process Packet Length, Tile Part Header ( PLT marker ).
       
  2335 // (other items were commented in a header).
       
  2336 // -----------------------------------------------------------------------------
       
  2337 //
       
  2338 TFrameState CJp2kReadCodec::ReadPLTL()
       
  2339     {
       
  2340     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerMinLength )
       
  2341         {
       
  2342         // Underflow
       
  2343         return EFrameIncomplete;
       
  2344         }
       
  2345 
       
  2346     if ( PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr ) != KPLT )
       
  2347         {
       
  2348         // Unrecognized PLT marker
       
  2349         User::Leave( KErrCorrupt );
       
  2350         }
       
  2351 
       
  2352     TUint16 markerLength = PtrReadUtil::ReadBigEndianUint16Inc( iReader.iPtr );
       
  2353 
       
  2354     if ( ( iReader.iPtrEnd - iReader.iPtr ) < ( markerLength - KMarkerLength ) )
       
  2355         {
       
  2356         // Underflow, backup the iterator to the beginning of the marker
       
  2357         iReader.iPtr -= KMarkerMinLength;
       
  2358         return EFrameIncomplete;
       
  2359         }
       
  2360 
       
  2361     TPLTMarker *pltMarker = new ( ELeave ) TPLTMarker;
       
  2362     //CleanupStack::PushL( pltMarker );
       
  2363     CleanupDeletePushL( pltMarker );
       
  2364 
       
  2365     pltMarker->iZplt = *iReader.iPtr++;
       
  2366 
       
  2367     TInt entries = markerLength - KMarkerSize - 1;
       
  2368     while ( entries )
       
  2369         {
       
  2370         User::LeaveIfError( pltMarker->iIplt.Append( *iReader.iPtr++ ) );
       
  2371         --entries;
       
  2372         }
       
  2373 
       
  2374     // Make sure we read all the data
       
  2375     if ( ( iReader.iPtr - iReader.iPtrStartMarker ) != ( markerLength + KMarkerSize ) )
       
  2376         {
       
  2377         // We must be missing some data in the marker
       
  2378         User::Leave( KErrCorrupt );
       
  2379         }   
       
  2380 
       
  2381     CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  2382 
       
  2383     // Append PLT to the current tile and decrement the tile length
       
  2384     tile.AppendPLTL( pltMarker, markerLength + KMarkerSize );
       
  2385     CleanupStack::Pop();
       
  2386 
       
  2387     // Any valid marker may come after PLT marker
       
  2388     iFHState = EStateInUnknown;
       
  2389 
       
  2390     return EFrameComplete;
       
  2391     }
       
  2392 
       
  2393 // -----------------------------------------------------------------------------
       
  2394 // CJp2kReadCodec::ReadSkipTileL
       
  2395 // Ignore the content and advance the iterator to the next marker.
       
  2396 // (other items were commented in a header).
       
  2397 // -----------------------------------------------------------------------------
       
  2398 //
       
  2399 TFrameState CJp2kReadCodec::ReadSkipTileL()
       
  2400     {
       
  2401     if ( (TUint32)( iReader.iPtrEnd - iReader.iPtr ) < iReader.iSkipLength )
       
  2402         {
       
  2403         iReader.iSkipLength -= ( iReader.iPtrEnd - iReader.iPtr );
       
  2404         iReader.iPtr = iReader.iPtrEnd;
       
  2405         
       
  2406         // Stay in the current state
       
  2407         return EFrameIncomplete;
       
  2408         }
       
  2409     else
       
  2410         {
       
  2411         if ( iReader.iSkipLength )
       
  2412             {
       
  2413             iReader.iPtr += iReader.iSkipLength;
       
  2414             iReader.iSkipLength = 0;
       
  2415             }
       
  2416         else
       
  2417             {
       
  2418             iFHState = EStateInUnknown;
       
  2419             }
       
  2420         return EFrameComplete;
       
  2421         }
       
  2422     }
       
  2423 
       
  2424 // -----------------------------------------------------------------------------
       
  2425 // CJp2kReadCodec::UpdateStateFromMarkerL
       
  2426 // Update the current state according to the marker type.
       
  2427 // (other items were commented in a header).
       
  2428 // -----------------------------------------------------------------------------
       
  2429 //
       
  2430 TFrameState CJp2kReadCodec::UpdateStateFromMarkerL()
       
  2431     {
       
  2432     if ( ( iReader.iPtrEnd - iReader.iPtr ) < KMarkerSize )
       
  2433         {
       
  2434         // Underflow
       
  2435         return EFrameIncomplete;
       
  2436         }
       
  2437 
       
  2438     TUint16 marker = PtrReadUtil::ReadBigEndianUint16( iReader.iPtr );
       
  2439     switch ( marker )
       
  2440         {
       
  2441         case KCOD:
       
  2442             {
       
  2443             iFHState = EStateInCOD;
       
  2444             break;
       
  2445             }
       
  2446         case KCOC:
       
  2447             {
       
  2448             iFHState = EStateInCOC;
       
  2449             break;
       
  2450             }
       
  2451         case KQCD:
       
  2452             {
       
  2453             iFHState = EStateInQCD;
       
  2454             break;
       
  2455             }
       
  2456         case KQCC:
       
  2457             {
       
  2458             iFHState = EStateInQCC;
       
  2459             break;
       
  2460             }
       
  2461         case KRGN:
       
  2462             {
       
  2463             iFHState = EStateInRGN;
       
  2464             break;
       
  2465             }
       
  2466         case KPOC:
       
  2467             {
       
  2468             iFHState = EStateInPOC;
       
  2469             break;
       
  2470             }
       
  2471         case KPPM:
       
  2472             {
       
  2473             iFHState = EStateInPPM;
       
  2474             break;
       
  2475             }
       
  2476         case KTLM:
       
  2477             {
       
  2478             iFHState = EStateInTLM;
       
  2479             break;
       
  2480             }
       
  2481         case KPLM:
       
  2482             {
       
  2483             iFHState = EStateInPLM;
       
  2484             break;
       
  2485             }
       
  2486         case KCRG:
       
  2487             {
       
  2488             iFHState = EStateInCRG;
       
  2489             break;
       
  2490             }
       
  2491         case KCME:
       
  2492             {
       
  2493             iFHState = EStateInCOM;
       
  2494             break;
       
  2495             }
       
  2496         case KSOT:
       
  2497             {
       
  2498             iFHState = EStateInSOT;
       
  2499             break;
       
  2500             }
       
  2501         case KPPT:
       
  2502             {
       
  2503             iFHState = EStateInPPT;
       
  2504             break;
       
  2505             }
       
  2506         case KPLT:
       
  2507             {
       
  2508             iFHState = EStateInPLT;
       
  2509             break;
       
  2510             }
       
  2511         case KSOD:
       
  2512             {
       
  2513             iFHState = EStateInSOD;
       
  2514             break;
       
  2515             }
       
  2516         case KEOC:
       
  2517             {
       
  2518             if ( !iUseNewTile && iImageInfo->TileCount() )
       
  2519                 {
       
  2520                 // There is a tile which has not been decoded yet
       
  2521                 CJ2kTileInfo& tile = CONST_CAST( CJ2kTileInfo&, iImageInfo->TileAt( iLastTileIndex ) );
       
  2522 
       
  2523                 tile.DoReleaseUnusedMarkers();
       
  2524 
       
  2525                 // Decode and delete the tile
       
  2526                 DecodeAndDeleteTileL( tile );
       
  2527 
       
  2528                 // Start with new tile
       
  2529                 iUseNewTile = ETrue;
       
  2530                 if ( !iUseNextTile )
       
  2531                     {
       
  2532                     iFHState = EStateInUnknown;
       
  2533                     return EFrameIncompleteRepositionRequest;
       
  2534                     }
       
  2535                 else
       
  2536                     {
       
  2537                     if ( !iSequential )
       
  2538                         {
       
  2539                         // Must be End of Codestream EOC
       
  2540                         iFHState = EStateInEOC;
       
  2541                         iReader.iPtr += KMarkerSize;
       
  2542                         return EFrameComplete;
       
  2543                         }
       
  2544                     }
       
  2545                 }
       
  2546             else
       
  2547                 {
       
  2548                 iFHState = EStateInEOC;
       
  2549                 
       
  2550                 // Have to increment the iterator
       
  2551                 iReader.iPtr += KMarkerSize;
       
  2552                 }
       
  2553             break;
       
  2554             }
       
  2555         default:
       
  2556             {
       
  2557             if ( marker < KEXTS || marker > KEXTE )
       
  2558                 {
       
  2559                 // Unrecognized marker
       
  2560                 User::Leave( KErrCorrupt );
       
  2561                 }
       
  2562             else
       
  2563                 {
       
  2564                 // Ignore the extension marker
       
  2565                 iReader.iPtr += KMarkerSize;
       
  2566                 }
       
  2567             break;
       
  2568             }
       
  2569         }
       
  2570     return EFrameComplete;
       
  2571     }
       
  2572 
       
  2573 // -----------------------------------------------------------------------------
       
  2574 // CJp2kReadCodec::DecodeAndDeleteTileL
       
  2575 // Decode the tile, write to image processor and delete the tile.
       
  2576 // (other items were commented in a header).
       
  2577 // -----------------------------------------------------------------------------
       
  2578 //
       
  2579 void CJp2kReadCodec::DecodeAndDeleteTileL( CJ2kTileInfo& aTile )
       
  2580     {
       
  2581     if ( !iEntropy )
       
  2582         {
       
  2583         iEntropy = CJ2kEntropyDecoder::NewL( *iImageInfo );
       
  2584         }
       
  2585 
       
  2586     if ( !iImageWriter )
       
  2587         {
       
  2588         iImageWriter = CJ2kImageWriter::NewL( ImageProcessor(  ), *iImageInfo, CONST_CAST( TJ2kInfo&,iJ2kInfo ) );
       
  2589         }
       
  2590 
       
  2591     if ( !iSynthesis )
       
  2592         {
       
  2593         iSynthesis = new ( ELeave ) CJ2kSynthesis;
       
  2594         }
       
  2595 
       
  2596     if ( iStyleUsed == EUnknownDecoder )
       
  2597         {
       
  2598         // Use tile-based as the default
       
  2599         iStyleUsed = ETileBasedDecoder;
       
  2600 
       
  2601         // If extra levels are dropped, the resolution of the decoded image is larger than 
       
  2602         // the resolution of the output image. levelsDropped here gives the resolution of 
       
  2603         // the decoded image (and thus relates to the amount of memory required for decoding).
       
  2604         TUint8 levelsDropped = (TUint8)(iImageInfo->LevelDrop() - iImageInfo->ExtraLevelDrop());
       
  2605 
       
  2606         TSizMarker& sizMarker = CONST_CAST( TSizMarker&, iImageInfo->SizMarker() );
       
  2607         if ( ( sizMarker.iXTsiz >> levelsDropped ) > (TUint32) KWaveletBlockSize ||
       
  2608              ( sizMarker.iYTsiz >> levelsDropped ) > (TUint32) KWaveletBlockSize )
       
  2609             {
       
  2610             iStyleUsed = EBlockBasedDecoder;
       
  2611             }
       
  2612         }
       
  2613 
       
  2614     if ( iStyleUsed == ETileBasedDecoder )
       
  2615         {
       
  2616         iSynthesis->DecodeTileL( *iImageWriter, *iEntropy, *iImageInfo, aTile );
       
  2617         }
       
  2618     else
       
  2619         {
       
  2620         iSynthesis->DecodeTileBlockL( *iImageWriter, *iEntropy, *iImageInfo, aTile );
       
  2621         }
       
  2622 
       
  2623     iImageInfo->Remove( 0 );
       
  2624     }
       
  2625 
       
  2626 // -----------------------------------------------------------------------------
       
  2627 // CJp2kReadCodec::ConvertImageDataL
       
  2628 // Convert some metadata from file format to TImageDataBlock derived objects
       
  2629 // and let the framework managing the buffer
       
  2630 // (other items were commented in a header).
       
  2631 // -----------------------------------------------------------------------------
       
  2632 //
       
  2633 void CJp2kReadCodec::ConvertImageDataL()
       
  2634     {
       
  2635     TJ2kInfo& info = CONST_CAST( TJ2kInfo&, iJ2kInfo );
       
  2636 
       
  2637     TInt index;
       
  2638     // Convert each IPR box to TJp2kIprBox image data
       
  2639     for ( index = 0; index < info.iIPRList.Count(); ++index )
       
  2640         {
       
  2641         TJp2kIprBox* jp2kIPR = new (ELeave) TJp2kIprBox;
       
  2642         CleanupDeletePushL( jp2kIPR );
       
  2643 
       
  2644         jp2kIPR->iIprData = info.iIPRList[index];
       
  2645 
       
  2646         User::LeaveIfError( iFrameData->AppendImageData( jp2kIPR ) );
       
  2647         CleanupStack::Pop(); // jp2kIPR
       
  2648 
       
  2649         // Transfer the ownership of the buffer to the framework
       
  2650         User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kIPR->iIprData ) );
       
  2651         info.iIPRList[index] = 0;
       
  2652         }
       
  2653     info.iIPRList.Reset();
       
  2654 
       
  2655     // Convert each XML box to TJp2kXmlBox image data
       
  2656     for ( index = 0; index < info.iXMLList.Count(); ++index )
       
  2657         {
       
  2658         TJp2kXmlBox* jp2kXML = new (ELeave) TJp2kXmlBox;
       
  2659         CleanupDeletePushL( jp2kXML );
       
  2660 
       
  2661         jp2kXML->iXmlData = info.iXMLList[index];
       
  2662 
       
  2663         User::LeaveIfError( iFrameData->AppendImageData( jp2kXML ) );
       
  2664         CleanupStack::Pop(); // jp2kXML
       
  2665 
       
  2666         // Transfer the ownership of the buffer to the framework
       
  2667         User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kXML->iXmlData ) );
       
  2668         info.iXMLList[index] = 0;
       
  2669         }
       
  2670     info.iXMLList.Reset();
       
  2671 
       
  2672     TInt length;
       
  2673     const TUint8 *ptr = 0;
       
  2674     // Convert each UUID box to TJp2kUuidBox image data
       
  2675     for ( index = 0; index < info.iUUIDList.Count(); ++index )
       
  2676         {
       
  2677         TJp2kUuidBox* jp2kUUID = new (ELeave) TJp2kUuidBox;
       
  2678         CleanupDeletePushL( jp2kUUID );
       
  2679 
       
  2680         ptr = info.iUUIDList[index]->Ptr();
       
  2681         jp2kUUID->iUuidId.Copy( ptr, KJ2KUuidIDSize );
       
  2682 
       
  2683         // Advance the pointer
       
  2684         ptr += KJ2KUuidIDSize;
       
  2685 
       
  2686         length = info.iUUIDList[index]->Length() - KJ2KUuidIDSize;
       
  2687         jp2kUUID->iUuidData = HBufC8::NewLC( length );
       
  2688         jp2kUUID->iUuidData->Des().Append( ptr, length );
       
  2689 
       
  2690         // Transfer the ownership of the buffer to the framework
       
  2691         User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kUUID->iUuidData ) );
       
  2692         CleanupStack::Pop( 1 ); // jp2kUUID->iUuidData
       
  2693 
       
  2694         User::LeaveIfError( iFrameData->AppendImageData( jp2kUUID ) );
       
  2695         CleanupStack::Pop( 1 ); // jp2kUUID
       
  2696         }
       
  2697     info.iUUIDList.ResetAndDestroy();
       
  2698 
       
  2699     // Convert each UUIDInfo box to TJp2kUuidInfoBox image data
       
  2700     for ( index = 0; index < info.iUUIDInfoListList.Count(); ++index )
       
  2701         {
       
  2702         TJp2kUuidInfoBox* jp2kUUIDInfo = new (ELeave) TJp2kUuidInfoBox;
       
  2703         CleanupDeletePushL( jp2kUUIDInfo );
       
  2704 
       
  2705         if ( info.iUUIDInfoListList[index]->Length() )
       
  2706             {
       
  2707             ptr = info.iUUIDInfoListList[index]->Ptr();
       
  2708             jp2kUUIDInfo->iUuidInfoNu = PtrReadUtil::ReadBigEndianUint16Inc( ptr );
       
  2709 
       
  2710             length = jp2kUUIDInfo->iUuidInfoNu * KJ2KUuidIDSize;
       
  2711             jp2kUUIDInfo->iUuidInfoId = HBufC8::NewLC( length );
       
  2712             jp2kUUIDInfo->iUuidInfoId->Des().Append( ptr, length );
       
  2713             }
       
  2714 
       
  2715         if ( info.iUUIDInfoUrlList[index]->Length() )
       
  2716             {
       
  2717             ptr = info.iUUIDInfoUrlList[index]->Ptr();
       
  2718 
       
  2719             // 1 byte unsigned integer
       
  2720             jp2kUUIDInfo->iUuidInfoVersion = *ptr++;
       
  2721 
       
  2722             // 3 bytes unsigned integer (in little endian)
       
  2723             jp2kUUIDInfo->iUuidInfoFlag = *ptr++;
       
  2724             jp2kUUIDInfo->iUuidInfoFlag |= ( *ptr++ << 8 );
       
  2725             jp2kUUIDInfo->iUuidInfoFlag |= ( *ptr++ << 16 );
       
  2726 
       
  2727             length = info.iUUIDInfoUrlList[index]->Length() - 4;
       
  2728             jp2kUUIDInfo->iUuidInfoData = HBufC8::NewLC( length );
       
  2729             jp2kUUIDInfo->iUuidInfoData->Des().Append( ptr, length );
       
  2730             }
       
  2731 
       
  2732         // Transfer the ownership of the buffer to the framework
       
  2733         if ( jp2kUUIDInfo->iUuidInfoData )
       
  2734             {
       
  2735             User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kUUIDInfo->iUuidInfoData ) );
       
  2736             CleanupStack::Pop( 1 ); // jp2kUUIDInfo->iUUidInfoData
       
  2737             }
       
  2738 
       
  2739         // Transfer the ownership of the buffer to the framework
       
  2740         if ( jp2kUUIDInfo->iUuidInfoId )
       
  2741             {
       
  2742             User::LeaveIfError( iFrameData->AppendImageBuffer( jp2kUUIDInfo->iUuidInfoId ) );
       
  2743             CleanupStack::Pop( 1 ); // jp2kUUIDInfo->iUuidInfoId
       
  2744             }
       
  2745 
       
  2746         User::LeaveIfError( iFrameData->AppendImageData( jp2kUUIDInfo ) );
       
  2747         CleanupStack::Pop( 1 ); // jp2kUUIDInfo
       
  2748         }
       
  2749     info.iUUIDInfoListList.ResetAndDestroy();
       
  2750     info.iUUIDInfoUrlList.ResetAndDestroy();
       
  2751     }