imagingmodules/jp2kcodec/Src/JP2KConvert.cpp
changeset 0 469c91dae73b
child 27 b0bc8115cfe9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KConvert.cpp	Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,2196 @@
+/*
+* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  JPEG2000 image encoder/decoder plugin class.
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KConvert.h"
+#include "JP2KStreamReader.h"
+#include "JP2KImageClientMain.h"
+#include "JP2KCodec.h"
+#include <barsc.h>
+#include <imageconversion.h>
+#include <barsread.h>
+#include <bautils.h>
+#include <e32math.h>
+#include <101F862D_extra.rsg>
+#include <icl/icl_uids.hrh>
+#include "JP2KUids.hrh"
+#include <JP2KImageData.h>
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES  
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+_LIT( KJ2KPanicCategory, "J2KConvertPlugin" );
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJp2kDecoder* CJp2kDecoder::NewL()
+    {
+    return new ( ELeave ) CJp2kDecoder;
+    }
+
+// Destructor
+CJp2kDecoder::~CJp2kDecoder()
+    {
+    // Call base class Cleanup(), else there is a possibility
+    // of memory leak
+    CImageDecoderPlugin::Cleanup();
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ImageType
+// Get the image type uid of this plugin.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ImageType( TInt aFrameNumber, TUid& aImageType, TUid& aImageSubType ) const
+    {
+    __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+    TUid uid = {KImageTypeJ2KUid};
+    aImageType = uid;
+    aImageSubType = KNullUid;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::NumberOfImageComments
+// Get the number of image comment.
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::NumberOfImageComments() const
+    {
+    __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+
+    const TUid commentUid = { KJ2KCommentUid };
+    const CFrameImageData& frameImageData = FrameData( 0 );
+    const TInt imageDataCount = frameImageData.ImageDataCount();
+    const TImageDataBlock *imageData = 0;
+    TInt imageCommentCount = 0;
+    for ( TInt index = 0; index < imageDataCount; ++index )
+        {
+        imageData = frameImageData.GetImageData( index );
+        if ( imageData->DataType() == commentUid )
+            {
+            imageCommentCount++;
+            }
+        }
+    return imageCommentCount;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ImageCommentL
+// Get the image comment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+HBufC* CJp2kDecoder::ImageCommentL( TInt aCommentNumber ) const
+    {
+    __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+    __ASSERT_ALWAYS( ( aCommentNumber >= 0 ) && ( aCommentNumber < NumberOfImageComments() ), 
+                     Panic( ECommentNumberOutOfRange ) );
+    
+    HBufC *comment = 0;
+
+    if( FrameData( 0 ).ImageDataCount() > 0 )
+        {
+        const TUid commentUid = { KJ2KCommentUid };
+        const CFrameImageData& frameImageData = FrameData( 0 );
+        const TInt imageDataCount = frameImageData.ImageDataCount();
+        const TImageDataBlock *imageData = 0;
+        TInt commentCount = 0;
+        for ( TInt index = 0; index < imageDataCount; ++index )
+            {
+            imageData = frameImageData.GetImageData( index );
+            if ( imageData->DataType() == commentUid )
+                {
+                if ( commentCount == aCommentNumber )
+                    {
+                    index = imageDataCount; // Break from the for loop
+                    }
+                else
+                    {
+                    commentCount++;
+                    }
+                }
+            }
+
+        if( imageData != 0 )
+            {
+            const TJp2kComment *jp2kComment = STATIC_CAST( const TJp2kComment*, imageData );
+            comment = HBufC::NewL( jp2kComment->iComment->Length() );
+
+            // Create 16 bit copy of the 8 bit original
+            comment->Des().Copy( *( jp2kComment->iComment ) );
+            }
+        }
+    return comment;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::NumberOfFrameComments
+// Get the number of frame comment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::NumberOfFrameComments( TInt aFrameNumber ) const
+    {
+    __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+    __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+   
+    return NumberOfImageComments();
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameCommentL
+// Get the frame comment.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+HBufC* CJp2kDecoder::FrameCommentL( TInt aFrameNumber, TInt aCommentNumber ) const
+    {
+    __ASSERT_ALWAYS( IsImageHeaderProcessingComplete(), Panic( EHeaderProcessingNotComplete ) );
+    __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+    return ImageCommentL( aCommentNumber );
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameInfoStringsL
+// Retrieve frame information and format it according to info stored in .rss file.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CFrameInfoStrings* CJp2kDecoder::FrameInfoStringsL( RFs& aFs, TInt aFrameNumber )
+    {
+    const TUid KJp2kCodecDllUid = { KJ2KCodecDllUidValue };
+
+    RResourceFile resourceFile;
+    OpenExtraResourceFileLC( aFs, KJp2kCodecDllUid, resourceFile );
+
+    HBufC8* resourceInfo = resourceFile.AllocReadLC( THEDECODERINFO );
+    TResourceReader resourceReader;
+    resourceReader.SetBuffer( resourceInfo );
+
+    TBuf<KCodecResourceStringMax> info;
+    TBuf<KCodecResourceStringMax> templte;
+
+    const TFrameInfo& frameInfo = FrameInfo( aFrameNumber );
+    CFrameInfoStrings* frameInfoStrings = CFrameInfoStrings::NewLC();
+
+    info = resourceReader.ReadTPtrC();
+    frameInfoStrings->SetDecoderL( info );
+
+    info = resourceReader.ReadTPtrC();
+    frameInfoStrings->SetFormatL( info );
+
+    TInt width = frameInfo.iOverallSizeInPixels.iWidth;
+    TInt height = frameInfo.iOverallSizeInPixels.iHeight;
+    TInt depth = frameInfo.iBitsPerPixel;
+
+    templte = resourceReader.ReadTPtrC();
+    info.Format( templte, width, height );
+    frameInfoStrings->SetDimensionsL( info );
+
+    CDesCArrayFlat* resourceArray = resourceReader.ReadDesCArrayL();
+    CleanupStack::PushL( resourceArray );
+    TUint formatIndex = ( frameInfo.iFlags & TFrameInfo::EColor ) ? 1 : 0;
+    templte = ( *resourceArray )[formatIndex];
+    CleanupStack::PopAndDestroy( resourceArray );
+    info.Format( templte, depth );
+    frameInfoStrings->SetDepthL( info );
+
+    resourceArray = resourceReader.ReadDesCArrayL();
+    CleanupStack::PushL( resourceArray );
+    formatIndex = 0;
+    info = ( *resourceArray )[formatIndex];
+    CleanupStack::PopAndDestroy( resourceArray );
+    frameInfoStrings->SetDetailsL( info );
+
+    CleanupStack::Pop( frameInfoStrings );
+    CleanupStack::PopAndDestroy( 2 ); // resourceInfo + resourceFile
+    return frameInfoStrings;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameHeaderBlockSize
+// Returns the frame header block size.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::FrameHeaderBlockSize( TInt aFrameNumber ) const
+    {
+    __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+    return KJ2kInputBufferSize;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::FrameBlockSize
+// Returns the frame block size.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CJp2kDecoder::FrameBlockSize(TInt aFrameNumber) const
+    {
+    __ASSERT_ALWAYS( aFrameNumber == 0, Panic( EFrameNumberOutOfRange ) );
+
+    return KJ2kInputBufferSize;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::DoConvert
+// Override the default DoConvert to split out the parsing and decoding
+// process into multiple steps.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::DoConvert()
+    {
+    TFrameState codecState = EFrameIncomplete;
+    TInt errCode = KErrNone;
+
+    CJp2kReadCodec *j2kCodec = static_cast<CJp2kReadCodec*>( ImageReadCodec() );
+
+    if ( !j2kCodec->IsDecodeTile() )
+        {
+        // parsing of a tile-part
+        TRAP( errCode, PrepareForProcessFrameL() );
+        if ( errCode != KErrNone )
+            {
+            RequestComplete( errCode );
+            return;
+            }
+
+        TBufPtr8& sourceData = SourceData();
+        TInt sourceLength = sourceData.Length();
+        if ( sourceLength != 0 )
+            {
+            TRAP( errCode, codecState = j2kCodec->ProcessFrameL( sourceData ) );
+            
+            if ( j2kCodec->IsDecodeTile() )
+                {
+                // tile-part contains all compressed data
+                // and proceed to the decoding
+                SelfComplete( KErrNone );
+                return;
+                }
+            }
+        // continue on parsing the tile-part
+        HandleProcessFrameResult( errCode, codecState );
+        }
+    else
+        {
+        // decoding of the tile-part
+        TRAP( errCode, codecState = j2kCodec->DecodeTileL() );
+
+        if ( errCode == KErrNone )
+            {
+            if ( j2kCodec->IsDecodeTile() )
+                {
+                // continue on decoding the tile-part
+                // if we split the decoding into multiple steps
+                SelfComplete( KErrNone );
+                return;
+                }
+            }
+        // either continue on parsing the next tile-part
+        // or done with the whole image
+        HandleProcessFrameResult( errCode, codecState );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::CJp2kDecoder
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJp2kDecoder::CJp2kDecoder()
+    {
+    }  
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadFormatL
+// JP2 File Format detection state machine.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadFormatL()
+    {
+    // Verify the JP2 file format if it exist
+    iCallFromFramework = ETrue;
+
+    while ( iState != EStateInCodestreamBox )
+        {
+        switch ( iState )
+            {
+            case EStateInSignatureBox:
+                {
+                ReadSignatureBoxL();
+                break;
+                }
+            case EStateInFileTypeBox:
+                {
+                ReadFileTypeBoxL();
+                break;
+                }
+            case EStateInJP2SuperBox:
+                {
+                ReadJp2HeaderBoxL();
+                break;
+                }
+            case EStateInIPRBox:
+                {
+                ReadIPRBoxL();
+                break;
+                }
+            case EStateInXMLBox:
+                {
+                ReadXMLBoxL();
+                break;
+                }
+            case EStateInUUIDBox:
+                {
+                ReadUUIDBoxL();
+                break;
+                }
+            case EStateInUUIDInfoBox:
+                {
+                ReadUUIDInfoBoxL();
+                break;
+                }
+            case EStateInUnknown:
+                {
+                if ( iCallFromFramework )
+                    {
+                    // Always read the length and type of the box
+                    ReadDataL( iLastRead, iBufferDes, KJ2kBoxTypeLength );
+
+                    if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+                        {
+                        if ( ( iJ2kInfo.iCSOffset != 0 ) && 
+                             ( (TUint32)iBufferDes.Length() == 0 ) )
+                            {
+                            // We have reach the end of file/stream and 
+                            // CodeStream box has been recognized
+                            iState = EStateInCodestreamBox;
+                            }
+                        else
+                            {
+                            // Need more data from the ICL framework
+                            User::Leave( KErrUnderflow );
+                            }
+                        }
+                    iPtr = iBufferDes.Ptr();
+                    }
+
+                if ( iState != EStateInCodestreamBox )
+                    {
+                    // Length and Type of next box
+                    iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+                    iBoxType = PtrReadUtil::ReadBigEndianUint32( iPtr );
+
+                    // Update the internal state based on the iBoxType
+                    UpdateStateFromBoxTypeL();
+
+                    if ( iState != EStateInCodestreamBox )
+                        {
+                        // Corrupted box length
+                        if ( ( (TInt32)iBoxLength ) < 0 )
+                            {
+                            User::Leave( KErrCorrupt );
+                            }
+                        }
+                    }
+                break;
+                }
+            default:
+                {
+                break;
+                }
+            }
+        iCallFromFramework = EFalse;
+        }
+
+    // When the code reach here, it means that we have found the 
+    // codestream box in JP2 file format or the codestream SOC itself
+    // in case of the JP2 file format, all the boxes after the
+    // codestream box will not be read and parsed.
+    
+    // In JP2 file format, iLastRead points to codestream box
+    // in JP2 codestream, iLastRead points to SOC marker
+    // it is the offset that ICL framework used to read
+    // in more data from the image file.
+    SetStartPosition( iJ2kInfo.iCSOffset );
+
+    // Always set the image data length to KMaxTInt32
+    SetDataLength( KMaxTInt );
+
+    // Fill up the image related information, if it is
+    // in JP2 file format, else defer the setting of the
+    // image info til SIZ marker in the codestream has
+    // been processed.
+    if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+        {
+        TFrameInfo& imageInfo = CONST_CAST( TFrameInfo&, ImageInfo() );
+        imageInfo.iOverallSizeInPixels = iJ2kInfo.iImageSize;
+        imageInfo.iFrameCoordsInPixels.SetRect( TPoint( 0, 0 ), iJ2kInfo.iImageSize );
+        imageInfo.iFrameSizeInTwips = iJ2kInfo.iImageSizeInTwips;
+
+        if ( iJ2kInfo.iBPCList.Count() > 0 )
+            {
+            // Calculate based on the bitdepth per component
+            for ( TUint16 index = 0; index < iJ2kInfo.iNC; ++index )
+                {
+                imageInfo.iBitsPerPixel += ( ( 0x7f & iJ2kInfo.iBPCList[index] ) + 1 );
+                }
+            }
+        else
+            {            
+            if ( iJ2kInfo.iBPC == KJ2kIsBPCBoxExist )
+                {
+                User::Leave( KErrCorrupt );
+                }
+
+            // Has the same bitdepth on each component
+            imageInfo.iBitsPerPixel = ( ( 0x7f & iJ2kInfo.iBPC ) + 1 ) * iJ2kInfo.iNC;
+            }
+        imageInfo.iFlags |= TFrameInfo::ECanDither;
+
+        // Decoder is able to handle scaleable resolution
+        imageInfo.iFlags |= TFrameInfo::EConstantAspectRatio;
+
+        if ( iJ2kInfo.iEnumCS != KJ2kColourSpecGrayScale )
+            {
+            imageInfo.iFlags |= TFrameInfo::EColor;
+            }
+        
+        // No animation.
+        imageInfo.iDelay = 0;
+
+        switch ( imageInfo.iBitsPerPixel )
+            {
+            case 1:
+                {
+                imageInfo.iFrameDisplayMode = EGray2;
+                break;
+                }
+            case 2:
+                {
+                imageInfo.iFrameDisplayMode = EGray4;
+                break;
+                }
+            case 4:
+                {
+                imageInfo.iFrameDisplayMode = ( imageInfo.iFlags & TFrameInfo::EColor ) ? EColor16 : EGray16;
+                break;
+                }
+            case 8:
+                {
+                imageInfo.iFrameDisplayMode = ( imageInfo.iFlags & TFrameInfo::EColor ) ? EColor16M : EGray256;
+                break;
+                }
+            case 12:
+                {
+                imageInfo.iFrameDisplayMode = ( imageInfo.iFlags & TFrameInfo::EColor ) ? EColor4K : EGray256;
+                break;
+                }
+            case 16:
+                {
+                imageInfo.iFrameDisplayMode = EColor64K;
+                break;
+                }
+            case 24:
+                {
+                imageInfo.iFrameDisplayMode = EColor16M;
+                break;
+                }
+            default:
+                {
+                imageInfo.iFrameDisplayMode = EColor64K;
+                break;
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadSignatureBoxL
+// Verify and process the Signature box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadSignatureBoxL(  )
+    {
+    // Validate the Signature Box
+    __ASSERT_ALWAYS( iLastRead == 0, Panic( EInvalidState ) );
+
+    // Read the Signature box + the next box's Length and Type
+    ReadDataL( iLastRead, iBufferDes, KJ2kFileInformationSize );
+
+    if ( (TUint32)iBufferDes.Length() < KJ2kSigBoxLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    if ( ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kSigBoxLength ) ||
+         ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kSigBoxType )   ||
+         ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kSigBoxContent ) )
+        {
+        // Unrecognized signature box
+        User::Leave( KErrCorrupt );
+        }
+
+    // File Type box shall immediately follow the Signature box
+    iLastRead = KJ2kSigBoxLength;
+    iState = EStateInFileTypeBox;
+
+    // JP2 file format
+    iJ2kInfo.iOption |= TJ2kInfo::EJP2file;
+
+    if ( iBufferDes.Length() < KJ2kFileInformationSize )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadFileTypeBoxL
+// Verify and process the File Type box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadFileTypeBoxL()
+    {
+    // Validate the File Type Box's Length and Type
+    if ( iCallFromFramework )
+        {
+        __ASSERT_ALWAYS( iLastRead == KJ2kSigBoxLength, Panic( EInvalidState ) );
+
+        ReadDataL( iLastRead, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        }
+
+    iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+    iBoxType = PtrReadUtil::ReadBigEndianUint32( iPtr );
+
+    if ( ( (TInt32)iBoxLength ) <= 0 || iBoxType != KJ2kFileTypeBox || iBoxLength > KJ2kFileTypeBoxMaxLength )
+        {
+        // Unrecognized file type box or corrupted box length
+        User::Leave( KErrCorrupt );
+        }
+
+    TUint8 xlBoxExist = 0;
+    if ( iBoxLength == 1 )
+        {
+        // The XLBox shall exist and contains the actual length of the box
+        // XLBox is 8 bytes width
+        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+        xlBoxExist = 1;
+        }
+
+    if ( ( (TInt32)iBoxLength ) <= 0 || ( ( (TInt32)iBoxLength - 16 ) / 4 ) <= 0 )
+        {
+        // Must include at least one CL field in the Compatibility list
+        User::Leave( KErrCorrupt );
+        }
+
+    // Read the File Type box + the next box's Length and Type
+    ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    // Substract next box's KJ2kBoxTypeLength
+    const TUint8 *ptrLimit = iPtr + iBoxLength - KJ2kBoxTypeLength;
+
+    // Advance the pointer by 8 bytes if XLBox exists
+    iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+    // Check Brand ( BR ) or Major Version
+    if ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kFileTypeBrand )
+        {
+        // It is ok at this point if Major Version does not match
+        iPtr += 0;
+        }
+
+    // Check Minor Version ( MinV )
+    if ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kFileTypeMinV )
+        {
+        // It is ok at this point if Minor Version does not match
+        iPtr += 0;
+        }
+
+    // Check Compatibility List ( CL )
+    TBool clFound = EFalse;
+    TUint32 clField = 0;
+    while ( ( iPtr + 4 ) <= ptrLimit  )
+        {
+        clField = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        if ( clField == KJ2kFileTypeBrand )
+            {
+            clFound = ETrue;
+            }
+        else if ( clField == KJ2kFileTypeProfile0 )
+            {
+            iJ2kInfo.iOption |= TJ2kInfo::EProfile0;
+            }
+        else if ( clField == KJ2kFileTypeProfile1 )
+            {
+            iJ2kInfo.iOption |= TJ2kInfo::EProfile1;
+            }
+        else
+            {
+            // other file types require no action
+            }
+        }
+
+    if ( !clFound || iPtr != ptrLimit )
+        {
+        // Unrecognized compatibility list or data misaligned
+        User::Leave( KErrCorrupt );
+        }
+
+    iLastRead += iBoxLength;
+    iState = EStateInUnknown;
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadJp2HeaderBoxL
+// Verify and process the JP2 Header box ( superbox ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadJp2HeaderBoxL()
+    {
+    // Since we are getting data from ICL framework
+    // we have no control of when will be the EOF
+    if ( iBoxLength == 0 )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    TUint8 xlBoxExist = 0;
+    if ( iBoxLength == 1 )
+        {
+        // The XLBox shall exist and contains the actual length of the box
+        // XLBox is 8 bytes width
+        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+        xlBoxExist = 1;
+        }
+
+    // Corrupted box length
+    if ( ( (TInt32)iBoxLength ) <= 0 )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // Validate the JP2 Header Super Box
+    // Read the JP2 box + the next box's Length and Type
+    ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    // Make sure that JP2 Header box contains enough data
+    // for Image Header box
+    if ( iBoxLength - KJ2kBoxTypeLength < KJ2kImageHeaderBoxLength )
+        {
+        // Missing Image Header box
+        User::Leave( KErrCorrupt );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    // Advance the pointer by 8 bytes if XLBox exists
+    iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+    // Image Header box shall be the first box within JP2 Header box
+    ReadImageHeaderBoxL();
+
+    TUint32 subBoxLength = 0;
+    TUint32 subBoxType = 0;
+
+    // Substract next box's Length and Type
+    const TUint8 *ptrLimit = iPtr + iBoxLength - KJ2kBoxTypeLength - KJ2kImageHeaderBoxLength;
+    TInt32 length = ptrLimit - iPtr;
+    TBool  csFound = EFalse;
+
+    while ( length > 0 )
+        {
+        if ( ( ptrLimit - iPtr ) < 8  )
+            {
+            // Not enough room for box data
+            User::Leave( KErrCorrupt );
+            }
+
+        subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        subBoxType = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+
+        if ( subBoxLength == 1 )
+            {
+            // The XLBox shall exist and contains the actual length of the box
+            // XLBox is 8 bytes width
+            subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+            subBoxLength += PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+            length -= KJ2kBoxTypeLength;
+            subBoxLength -= KJ2kBoxTypeLength;
+            }
+
+        if ( ( (TInt32)subBoxLength ) < 0 || ( subBoxLength <= 8 ) || ( ( iPtr + subBoxLength - KJ2kBoxTypeLength ) > ptrLimit ) )
+            {
+            // Not enough room for subbox data or corrupted subbox length
+            User::Leave( KErrCorrupt );
+            }
+
+        switch ( subBoxType )
+            {
+            case KJ2kColourSpecBoxType:
+                {
+                if ( !csFound )
+                    {
+                    // Colour Spec Box
+                    ReadColorSpecBoxL( subBoxLength );
+                    csFound = ETrue;
+                    }
+                else
+                    {
+                    // Ignore the second Colour Spec Box,
+                    // just advance the iterator pointer
+                    iPtr += subBoxLength - KJ2kBoxTypeLength;
+                    }
+                break;
+                }
+            case KJ2kResolutionBoxType:
+                {
+                // Resolution box ( superbox )
+                ReadResolutionBoxL( ptrLimit, subBoxLength );
+                break;
+                }
+            case KJ2kBitsPerCompBoxType:
+                {
+                // Bits Per Component Box
+                ReadBitsPerCompBoxL( subBoxLength );
+                break;
+                }
+            case KJ2kPaletterBoxType:
+                {
+                // Palette Box
+                ReadPaletteBoxL();
+                break;
+                }
+            case KJ2kComponentMapBoxType:
+                {
+                // Component Mapping Box
+                ReadComponentMapBoxL( subBoxLength );
+                break;
+                }
+            case KJ2kChannelDefBoxType:
+                {
+                // Channel Definition Box
+                ReadChannelDefBoxL( subBoxLength );
+                break;
+                }
+            default:
+                {
+                // Unrecognized Box
+                User::Leave( KErrCorrupt );
+                break;
+                }
+            }
+        length -= subBoxLength;
+        }
+
+    iLastRead += iBoxLength;
+    iState = EStateInUnknown;
+
+    // JP2 Header processed
+    iJ2kInfo.iOption |= TJ2kInfo::EJP2Header;
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadImageHeaderBoxL
+// Verify and process the Image Header box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadImageHeaderBoxL()
+    {
+    // Validate the Image Header Box
+    if ( ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kImageHeaderBoxLength ) ||
+         ( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) != KJ2kImageHeaderBoxType ) )
+        {
+        // Unrecognized Image Header box
+        User::Leave( KErrCorrupt );
+        }
+
+    iJ2kInfo.iImageSize.iHeight = (TInt)PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+    iJ2kInfo.iImageSize.iWidth = (TInt)PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+    iJ2kInfo.iNC  = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+    iJ2kInfo.iBPC = *iPtr++;
+
+    if ( (iJ2kInfo.iImageSize.iHeight <= 0) || (iJ2kInfo.iImageSize.iWidth <= 0) ||
+         (iJ2kInfo.iNC == 0) || (iJ2kInfo.iBPC == 0) )
+        {
+        // Corrupted image parameters
+        User::Leave( KErrCorrupt );
+        }
+
+    if ( *iPtr++ != KJ2kImageHeaderCompressionType )
+        {
+        // Unrecognized compression type
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check color space - UnkC
+    TUint8 value = *iPtr++;
+    if ( value == 0 || value == 1 )
+        {
+        iJ2kInfo.iOption |= ( value == 0 ) ? TJ2kInfo::EColorSpec : 0;
+        }
+    else
+        {
+        // Unrecognized color space
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check intellectual property - IPR 
+    value = *iPtr++;
+    if ( value == 0 || value == 1 )
+        {
+        iJ2kInfo.iOption |= value;
+        }
+    else
+        {
+        // Unrecognized intellectual property
+        User::Leave( KErrCorrupt );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadColorSpecBoxL
+// Verify and process the Colour Specification box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadColorSpecBoxL( const TUint32 aBoxLength )
+    {
+    // Validate the Color Specification Box
+    TUint8 method = *iPtr++;
+
+    if ( method != 1 && method != 2 )
+        {
+        // Unrecognized method
+        User::Leave( KErrCorrupt );
+        }
+
+    // Ignore the precedence
+    iPtr++;
+
+    // Ignore the approximation
+    iPtr++;
+
+    if ( method == 1 )
+        {
+        // Method must be 1 if we reach this point
+        iJ2kInfo.iEnumCS = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        switch ( iJ2kInfo.iEnumCS )
+            {
+            case 16:
+            case 17:
+            case 18:
+            case 21:
+            case 22:
+                {
+                break;
+                }
+            default:
+                {
+                // Unrecognized colour specification
+                User::Leave( KErrNotSupported );
+                break;
+                }
+            }
+        }
+    else
+        {
+        // ICC profile
+        TUint32 length = (TUint32)( aBoxLength - KJ2kBoxTypeLength - 3 );
+        iJ2kInfo.iICCProfile = HBufC8::NewL( length );
+        iJ2kInfo.iICCProfile->Des().Append( iPtr, length );
+        iPtr += length;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadBitsPerCompBoxL
+// Verify and process the Bits Per Component box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadBitsPerCompBoxL( TUint32 aBoxLength )
+    {
+    if ( iJ2kInfo.iBPC != KJ2kIsBPCBoxExist )
+        {
+        // Should not happen but we just advance 
+        // the iterator and ignore the whole box
+        iPtr += aBoxLength - KJ2kBoxTypeLength;
+        return;
+        }
+
+    // Validate the Bits Per Component Box
+    if ( ( aBoxLength - KJ2kBoxTypeLength ) != iJ2kInfo.iNC  )
+        {
+        // Unrecognized number of components
+        User::Leave( KErrCorrupt );
+        }
+
+    while ( aBoxLength > KJ2kBoxTypeLength )
+        {
+        User::LeaveIfError( iJ2kInfo.iBPCList.Append( *iPtr++ ) );
+
+        --aBoxLength;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadResolutionBoxL
+// Verify and process the Resolution box ( in JP2 Header box, 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadResolutionBoxL( const TUint8 *aPtrLimit, TUint32 aBoxLength )
+    {
+    TUint32 subBoxLength = 0;
+    TUint32 subBoxType = 0;
+
+    aBoxLength -= KJ2kBoxTypeLength;
+    while ( aBoxLength > 0 )
+        {
+        if ( (TUint32)( aPtrLimit - iPtr ) < KJ2kResSubBoxLength )
+            {
+            // Not enough room for subbox data
+            User::Leave( KErrCorrupt );
+            }
+
+        subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        subBoxType = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+
+        if ( subBoxLength == 1 )
+            {
+            // The XLBox shall exist and contains the actual length of the box
+            // XLBox is 8 bytes width
+            subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+            subBoxLength += PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+            aBoxLength -= KJ2kBoxTypeLength;
+            subBoxLength -= KJ2kBoxTypeLength;
+            }
+
+        if ( subBoxLength != KJ2kResSubBoxLength )
+            {
+            // Corrupted resolution box length, both sub boxes have length of 18
+            User::Leave( KErrCorrupt );
+            }
+
+        if ( subBoxType == KJ2kCaptureResBoxType )
+            {
+            ReadCaptureResBoxL( subBoxLength );
+            }
+        else if ( subBoxType == KJ2kDisplayResBoxType )
+            {
+            ReadDisplayResBoxL(  );
+            }
+        else
+            {
+            // Unrecognized box in Resolution super box
+            User::Leave( KErrCorrupt );
+            }
+        aBoxLength -= subBoxLength;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadDisplayResBoxL
+// Verify and process the Default Display Resolution box ( in Resolution box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadDisplayResBoxL()
+    {
+    // Store default display resolution
+    TUint16 verNum = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+    TUint16 verDen = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+    TUint16 horNum = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+    TUint16 horDen = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+    TUint8  verExp = *iPtr++;
+    TUint8  horExp = *iPtr++;
+    TReal   tenPow = 0.0;
+
+    // Check  the validity of the parameters
+    if((verNum == 0) || (verDen == 0) || (horNum == 0) || (horDen == 0))
+        {
+        // Values corrupted, do not try to compute the SizeInTwips
+        return;
+        }
+
+    User::LeaveIfError( Math::Pow10( tenPow, verExp ) );
+
+    TReal result = ( iJ2kInfo.iImageSize.iWidth / ( ( (TReal)verNum / verDen ) * tenPow ) ) / KJ2kTwipM;
+    iJ2kInfo.iImageSizeInTwips.iWidth = (TInt)result;
+
+    User::LeaveIfError( Math::Pow10( tenPow,horExp ) );
+
+    result = ( iJ2kInfo.iImageSize.iHeight / ( ( (TReal)horNum / horDen ) * tenPow ) ) / KJ2kTwipM;
+    iJ2kInfo.iImageSizeInTwips.iHeight = (TInt)result;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadCaptureResBoxL
+// Verify and process the Capture Resolution box ( in Resolution box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadCaptureResBoxL( const TUint32 aBoxLength )
+    {
+    // Ignore the capture resolution
+    iPtr += aBoxLength - KJ2kBoxTypeLength;
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadPaletteBoxL
+// Verify and process the Palette box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadPaletteBoxL()
+    {
+    // Validate the Palette Box
+    TUint16 entries = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+    TUint8  npc = *iPtr++;
+
+    if((entries > KMaxPaletteEntries) || (entries == 0))
+        {
+        // Number of entries must be between 1 and 1024
+        User::Leave( KErrCorrupt );
+        }
+
+    TInt rowIndex = 0;
+    TInt columnIndex = 0;
+    RArray<TUint> bpcInBytes;
+    TUint8 bpc = 0;
+
+    for ( rowIndex = 0; rowIndex < npc; ++rowIndex )
+        {
+        bpc = *iPtr++;
+        User::LeaveIfError( iJ2kInfo.iPalette.iBList.Append( bpc ) );
+
+        bpc = (TUint8)( ( 0x7f & bpc ) + 1 );
+        User::LeaveIfError( bpcInBytes.Append( (TUint)( ( bpc % 8 ) ? bpc / 8 + 1 : bpc / 8 ) ) );
+        }
+
+    RArray<TUint> *cList;
+    CleanupClosePushL( bpcInBytes );
+
+    for ( rowIndex = 0; rowIndex < entries; ++rowIndex )
+        {
+        cList = new ( ELeave ) RArray<TUint>( npc );
+        CleanupStack::PushL( cList );
+        CleanupClosePushL( *cList );
+
+        for ( columnIndex = 0; columnIndex < npc; ++columnIndex )
+            {
+            switch ( bpcInBytes[columnIndex] )
+                {
+                case 1:
+                    {
+                    User::LeaveIfError( cList->Append( (TUint)*iPtr++ ) );
+                    break;
+                    }
+                case 2:
+                    {
+                    User::LeaveIfError( cList->Append( (TUint)PtrReadUtil::ReadBigEndianUint16Inc( iPtr ) ) );
+                    break;
+                    }
+                case 3:
+                    {
+                    bpc = *iPtr++;
+                    User::LeaveIfError( cList->Append( ( (TUint)bpc << 16 ) | PtrReadUtil::ReadBigEndianUint16Inc( iPtr ) ) );
+                    break;
+                    }
+                case 4:
+                    {
+                    User::LeaveIfError( cList->Append( PtrReadUtil::ReadBigEndianUint32Inc( iPtr ) ) );
+                    break;
+                    }
+                default:
+                    {
+                    // Unrecognized index
+                    User::Leave( KErrCorrupt );
+                    break;
+                    }
+                }
+            }
+        User::LeaveIfError( iJ2kInfo.iPalette.iC2DArray.Append( cList ) );
+        CleanupStack::Pop(2);
+        }
+    CleanupStack::PopAndDestroy();
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadComponentMapBoxL
+// Verify and process the Component Mapping box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadComponentMapBoxL( TUint32 aBoxLength )
+    {
+    // Validate the Component Mapping Box
+    if ( ( aBoxLength - KJ2kBoxTypeLength ) % 4 != 0 )
+        {
+        // Misaligned Component Mapping box
+        User::Leave( KErrCorrupt );    
+        }
+
+    TUint16 cmp = 0;
+    TUint8 mtyp = 0;
+    TUint8 pcol = 0;
+
+    while ( aBoxLength > KJ2kBoxTypeLength )
+        {
+        cmp = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+
+        if(cmp > KMaxComponents)
+            {
+            // Illegal component index
+            User::Leave( KErrCorrupt );    
+            }
+
+        mtyp = *iPtr++;
+        pcol = *iPtr++;
+        if ( mtyp == 0 || mtyp == 1 )
+            {
+            if ( mtyp == 0 && pcol != 0 )
+                {
+                // Unrecognized matching between MTYP and PCOL
+                User::Leave( KErrCorrupt );
+                }
+            }
+        else
+            {
+            // Unrecognized MTYP
+            User::Leave( KErrCorrupt );
+            }
+
+        User::LeaveIfError( iJ2kInfo.iCMPList.Append( TComponentMap( cmp, mtyp, pcol ) ) );
+        aBoxLength -= 4;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadChannelDefBoxL
+// Verify and process the Channel Definition box ( in JP2 Header box ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadChannelDefBoxL( TUint32 aBoxLength )
+    {
+    // Validate the Channel Definition Box
+    TUint16 entries = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+    if ( ( aBoxLength - KJ2kBoxTypeLength - 2 ) / 6 != entries )
+        {
+        // Misaligned Channel Definition box
+        User::Leave( KErrCorrupt );
+        }
+
+    TUint16 cn = 0;
+    TUint16 typ = 0;
+    TUint16 asoc = 0;
+
+    while ( entries != 0 )
+        {
+        cn   = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+        typ  = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+        asoc = PtrReadUtil::ReadBigEndianUint16Inc( iPtr );
+        User::LeaveIfError( iJ2kInfo.iCNList.Append( TChannelDefinition( cn, typ, asoc ) ) );
+        --entries;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadIPRBoxL
+// Verify and process the IPR box .
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadIPRBoxL()
+    {
+    // Check whether this IPR box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This IPR box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // IPR box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    TUint xlBoxExist = 0;
+    if ( iBoxLength == 1 )
+        {
+        // The XLBox shall exist and contains the actual length of the box
+        // XLBox is 8 bytes width
+        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+        xlBoxExist = 1;
+        }
+
+    // Corrupted box length
+    if ( ( (TInt32)iBoxLength ) < 0 )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check whether this IPR box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This IPR box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // IPR box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    // Validate the IPR Box
+    // Read the IPR box + the next box's Length and Type
+    ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    // Advance the pointer by 8 bytes if XLBox exists
+    iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+    TInt length = iBoxLength - ( ( 1 + xlBoxExist ) * KJ2kBoxTypeLength );
+
+    HBufC8 *iprBuffer = HBufC8::NewLC( length );
+    iprBuffer->Des().Append( iPtr, length );
+    iPtr += length;
+
+    User::LeaveIfError( iJ2kInfo.iIPRList.Append( iprBuffer ) );
+    CleanupStack::Pop(); // iprBuffer
+
+    iLastRead += iBoxLength;
+    iState = EStateInUnknown;
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength )
+        {
+        // Test the end of file/stream 
+        ReadDataL( iLastRead, iBufferDes, 1 );
+        if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+             ( iJ2kInfo.iCSOffset != 0 ) )
+            {
+            // CodeStream box has been recognized
+            iState = EStateInCodestreamBox;
+            }
+        else
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadXMLBoxL
+// Verify and process the XML box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadXMLBoxL()
+    {
+    // Check whether this XML box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This XML box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // XML box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    TUint xlBoxExist = 0;
+    if ( iBoxLength == 1 )
+        {
+        // The XLBox shall exist and contains the actual length of the box
+        // XLBox is 8 bytes width
+        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+        xlBoxExist = 1;
+        }
+
+    // Corrupted box length
+    if ( ( (TInt32)iBoxLength ) < 0 )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check whether this XML box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This XML box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // XML box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    // Validate the XML Box
+    // Read the XML box + the next box's Length and Type
+    ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    // Advance the pointer by 8 bytes if XLBox exists
+    iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+    TInt length = iBoxLength - ( ( 1 + xlBoxExist ) * KJ2kBoxTypeLength );
+
+    HBufC8 *xmlBuffer = HBufC8::NewLC( length );
+    xmlBuffer->Des().Append( iPtr, length );
+    iPtr += length;
+
+    User::LeaveIfError( iJ2kInfo.iXMLList.Append( xmlBuffer ) );
+    CleanupStack::Pop(); // xmlBuffer
+
+    iLastRead += iBoxLength;
+    iState = EStateInUnknown;
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength )
+        {
+        // Test the end of file 
+        ReadDataL( iLastRead, iBufferDes, 1 );
+        if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+             ( iJ2kInfo.iCSOffset != 0 ) )
+            {
+            // CodeStream box has been recognized
+            iState = EStateInCodestreamBox;
+            }
+        else
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadUUIDBoxL
+// Verify and process UUID box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadUUIDBoxL()
+    {
+    // Check whether this UUID box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This UUID box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // UUID box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    TUint xlBoxExist = 0;
+    if ( iBoxLength == 1 )
+        {
+        // The XLBox shall exist and contains the actual length of the box
+        // XLBox is 8 bytes width
+        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+        xlBoxExist = 1;
+        }
+
+    // Corrupted box length
+    if ( ( (TInt32)iBoxLength ) < 0 )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check whether this UUID box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This UUID box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // UUID box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    // Validate the UUID Box
+    // Read the UUID box + the next box's Length and Type
+    ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    // Advance the pointer by 8 bytes if XLBox exists
+    iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+    TInt length = iBoxLength - ( ( 1 + xlBoxExist ) * KJ2kBoxTypeLength );
+
+    HBufC8 *uuidBuffer = HBufC8::NewLC( length );
+    uuidBuffer->Des().Append( iPtr, length );
+    iPtr += length;
+
+    User::LeaveIfError( iJ2kInfo.iUUIDList.Append( uuidBuffer ) );
+    CleanupStack::Pop(); // uuidBuffer
+
+    iLastRead += iBoxLength;
+    iState = EStateInUnknown;
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength )
+        {
+        // Test the end of file 
+        ReadDataL( iLastRead, iBufferDes, 1 );
+        if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+             ( iJ2kInfo.iCSOffset != 0 ) )
+            {
+            // CodeStream box has been recognized
+            iState = EStateInCodestreamBox;
+            }
+        else
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ReadUUIDInfoBoxL
+// Verify and process the UUID Info box ( superbox ).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ReadUUIDInfoBoxL()
+    {
+    // Check whether this UUIDInfo box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This UUIDInfo box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // UUIDInfo box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    TUint xlBoxExist = 0;
+    if ( iBoxLength == 1 )
+        {
+        // The XLBox shall exist and contains the actual length of the box
+        // XLBox is 8 bytes width
+        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+        xlBoxExist = 1;
+        }
+
+    // Corrupted box length
+    if ( ( (TInt32)iBoxLength ) < 0 )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check whether this UUIDInfo box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This UUIDInfo box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // UUIDInfo box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    // Validate the UUIDInfo Box
+    // Read the UUIDInfo box + the next box's Length and Type
+    ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    // Substract next box's Length and Type
+    const TUint8 *ptrLimit = iPtr + iBoxLength - KJ2kBoxTypeLength;
+
+    // Advance the pointer by 8 bytes if XLBox exists
+    iPtr += ( xlBoxExist * KJ2kBoxTypeLength );
+
+    TUint32 subBoxLength = 0;
+    TUint32 subBoxType = 0;
+
+    TInt32 length = ptrLimit - iPtr;
+    TInt32 dataLength = 0;
+    TInt32 order = 0;
+
+    HBufC8 *listBuffer = 0;
+    HBufC8 *urlBuffer = 0;
+
+    while ( length > 0 )
+        {
+        if ( ( ptrLimit - iPtr ) < 8  )
+            {
+            // Not enough room for box data
+            User::Leave( KErrCorrupt );
+            }
+
+        subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        subBoxType = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+
+        if ( subBoxLength == 1 )
+            {
+            // The XLBox shall exist and contains the actual length of the box
+            // XLBox is 8 bytes width
+            subBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+            subBoxLength += PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+            length -= KJ2kBoxTypeLength;
+            subBoxLength -= KJ2kBoxTypeLength;
+            }
+
+        if ( ( (TInt32)subBoxLength < 0 ) || ( subBoxLength <= 8 ) || ( ( iPtr + subBoxLength - KJ2kBoxTypeLength ) > ptrLimit ) )
+            {
+            // Not enough room for subbox data or corrupted subbox length
+            User::Leave( KErrCorrupt );
+            }
+
+        switch ( subBoxType )
+            {
+            case KJ2kUUIDListBoxType:
+                {
+                // Validate the UUIDInfo List box
+                // NU | ID-0 | ... | ID-n
+                // where NU is 2 bytes unsigned specifying the number of IDs
+                //       ID is 16 bytes UUID 
+                TUint16 nuField = PtrReadUtil::ReadBigEndianUint16( iPtr );
+                if ( ( subBoxLength - ( 2 + KJ2kBoxTypeLength ) ) != 
+                     ( (TUint32)( nuField * KJ2KUuidIDSize ) ) )
+                    {
+                    // UUIDInfo List box does not confirm to standard format
+                    User::Leave( KErrCorrupt );
+                    }
+
+                if ( listBuffer )
+                    {
+                    // There should be one UUIDInfo List box
+                    User::Leave( KErrCorrupt );
+                    }
+
+                dataLength = subBoxLength - KJ2kBoxTypeLength;
+                listBuffer = HBufC8::NewLC( dataLength );
+                listBuffer->Des().Append( iPtr, dataLength );
+                iPtr += ( dataLength );
+
+                if ( order == 0 )
+                    {
+                    // Increment the order if UUIDInfo List box come first
+                    ++order;
+                    }
+                break;
+                }
+            case KJ2kUUIDUrlBoxType:
+                {
+                // Validate the UUIDInfo Data Entry Url box
+                if ( urlBuffer )
+                    {
+                    // There should be one UUIDInfo Data Entry Url box
+                    User::Leave( KErrCorrupt );
+                    }
+
+                dataLength = subBoxLength - KJ2kBoxTypeLength;
+                urlBuffer = HBufC8::NewLC( dataLength );
+                urlBuffer->Des().Append( iPtr, dataLength );
+                iPtr += ( dataLength );
+
+                if ( order == 0 )
+                    {
+                    // Decrement the order if UUIDInfo Data Entry Url box come first
+                    --order;
+                    }
+                break;
+                }
+            default:
+                {
+                // Unrecognized Box
+                User::Leave( KErrCorrupt );
+                break;
+                }
+            }
+        length -= subBoxLength;
+        }
+
+    if ( listBuffer || urlBuffer )
+        {
+        if ( !( listBuffer ) )
+            {
+            // Create a dummy place holder
+            listBuffer = HBufC8::NewLC( 1 );
+            }
+
+        if ( !( urlBuffer ) )
+            {
+            // Create a dummy place holder
+            urlBuffer = HBufC8::NewLC( 1 );
+            }
+
+        if ( order < 0 )
+            {
+            // UUIDInfo Data Entry Url box come first
+            User::LeaveIfError( iJ2kInfo.iUUIDInfoListList.Append( listBuffer ) );
+            CleanupStack::Pop( 1 ); // listBuffer
+
+            User::LeaveIfError( iJ2kInfo.iUUIDInfoUrlList.Append( urlBuffer ) );
+            CleanupStack::Pop( 1 ); // urlBuffer
+            }
+        else
+            {
+            // UUIDInfo List box come first
+            User::LeaveIfError( iJ2kInfo.iUUIDInfoUrlList.Append( urlBuffer ) );
+            CleanupStack::Pop( 1 ); // urlBuffer
+
+            User::LeaveIfError( iJ2kInfo.iUUIDInfoListList.Append( listBuffer ) );
+            CleanupStack::Pop( 1 ); // listBuffer
+            }
+        }
+    else
+        {
+        // UUIDInfo box does not containing any
+        // UUIDInfo List box or UUIDInfo Data Entry Url box
+        User::Leave( KErrCorrupt );
+        }
+
+    iLastRead += iBoxLength;
+    iState = EStateInUnknown;
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength )
+        {
+        // Test the end of file 
+        ReadDataL( iLastRead, iBufferDes, 1 );
+        if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+             ( iJ2kInfo.iCSOffset != 0 ) )
+            {
+            // CodeStream box has been recognized
+            iState = EStateInCodestreamBox;
+            }
+        else
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::IgnoreBoxL
+// Ignore the content of the box and advance the iterator to the next box.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::IgnoreBoxL()
+    {
+    // Check whether this box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    if ( iBoxLength == 1 )
+        {
+        // The XLBox shall exist and contains the actual length of the box
+        // XLBox is 8 bytes width
+        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+
+        iPtr = iBufferDes.Ptr();
+        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+        }
+
+    // Corrupted box length
+    if ( ( (TInt32)iBoxLength ) < 0 )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // Check whether this box is the last box in the file
+    if ( iBoxLength == 0 )
+        {
+        // This box is the last box in the file
+        if ( iJ2kInfo.iCSOffset != 0 )
+            {
+            // CodeStream box has been recognized
+            // Since we are not able to read til the
+            // end of file/stream, we will skip this
+            // box
+            iState = EStateInCodestreamBox;
+            return;
+            }
+        else
+            {
+            // The CodeStream box is missing from the file
+            // and nothing can be decoded
+            User::Leave( KErrCorrupt );
+            }
+        }
+
+    // Read and ignore the validation of the box
+    ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, iBoxLength );
+
+    if ( (TUint32)iBufferDes.Length() < iBoxLength - KJ2kBoxTypeLength )
+        {
+        // Need more data from the ICL framework
+        User::Leave( KErrUnderflow );
+        }
+
+    iPtr = iBufferDes.Ptr();
+
+    iLastRead += iBoxLength;
+    iState = EStateInUnknown;
+
+    iPtr += iBoxLength - KJ2kBoxTypeLength;
+    if ( (TUint32)iBufferDes.Length() < iBoxLength )
+        {
+        // Test the end of file 
+        ReadDataL( iLastRead, iBufferDes, 1 );
+        if ( ( (TUint32)iBufferDes.Length() == 0 ) &&
+             ( iJ2kInfo.iCSOffset != 0 ) )
+            {
+            // CodeStream box has been recognized
+            iState = EStateInCodestreamBox;
+            }
+        else
+            {
+            // Need more data from the ICL framework
+            User::Leave( KErrUnderflow );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::UpdateStateFromBoxTypeL
+// Update the current state according to the box type
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::UpdateStateFromBoxTypeL()
+    {
+    switch ( iBoxType )
+        {
+        case KJ2kSigBoxType:
+            {
+            iState = EStateInSignatureBox;
+            break;
+            }
+        case KJ2kJP2HeaderBoxType:
+            {
+            iState = EStateInJP2SuperBox;
+            break;
+            }
+        case KJ2kCodestreamBoxType:
+            {
+            if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+                {
+                if ( !( iJ2kInfo.iOption & TJ2kInfo::EJP2Header ) )
+                    {
+                    // In JP2 file format, CodeStream box
+                    // can not come before JP2 Header box
+                    User::Leave( KErrCorrupt );
+                    }
+
+                // Save the CodeStream box's length
+                iJ2kInfo.iCSBoxLength = iBoxLength;
+                iJ2kInfo.iCSOffset = iLastRead;
+
+                if ( iBoxLength == 0 )
+                    {
+                    // CodeStream box is the last box in the file
+                    iState = EStateInCodestreamBox;
+                    }
+                else
+                    {
+                    // Continue checking any boxes after the CodeStream box
+                    if ( iBoxLength == 1 )
+                        {
+                        // The XLBox shall exist and contains the actual length of the box
+                        // XLBox is 8 bytes width
+                        ReadDataL( iLastRead + KJ2kBoxTypeLength, iBufferDes, KJ2kBoxTypeLength );
+
+                        if ( (TUint32)iBufferDes.Length() < KJ2kBoxTypeLength )
+                            {
+                            // Need more data from the ICL framework
+                            User::Leave( KErrUnderflow );
+                            }
+
+                        iPtr = iBufferDes.Ptr();
+                        iBoxLength = PtrReadUtil::ReadBigEndianUint32Inc( iPtr );
+                        iBoxLength += PtrReadUtil::ReadBigEndianUint32( iPtr );
+                        }
+
+                    // Corrupted box length
+                    if ( ( (TInt32)iBoxLength ) < 0 )
+                        {
+                        User::Leave( KErrCorrupt );
+                        }
+                    
+                    iLastRead += iBoxLength;
+                    // Test the end of file 
+                    ReadDataL( iLastRead, iBufferDes, KJ2kBoxTypeLength );
+                    if ( (TUint32)iBufferDes.Length() == 0 )
+                        {
+                        // CodeStream box is the last box in the file
+                        iState = EStateInCodestreamBox;
+                        }
+                    else if ( (TUint32)iBufferDes.Length() == KJ2kBoxTypeLength )
+                        {
+                        iPtr = iBufferDes.Ptr();
+                        }
+                    else
+                        {
+                        // Need more data from the ICL framework
+                        User::Leave( KErrUnderflow );
+                        }
+                    }
+                }
+            else
+                {
+                // CodeStream box must exist in file format only
+                User::Leave( KErrCorrupt );
+                }
+            break;
+            }
+        case KJ2kIPRBoxType:
+            {
+            iState = EStateInIPRBox;
+            break;
+            }
+        case KJ2kXMLBoxType:
+            {
+            iState = EStateInXMLBox;
+            break;
+            }
+        case KJ2kUUIDBoxType:
+            {
+            iState = EStateInUUIDBox;
+            break;
+            }
+        case KJ2kUUIDInfoBoxType:
+            {
+            iState = EStateInUUIDInfoBox;
+            break;
+            }
+        default:
+            {
+            // Check if the first 4 bytes read
+            // is SOC + SIZ
+            if ( iBoxLength == KJ2kSOCType )
+                {
+                if ( iJ2kInfo.iOption & TJ2kInfo::EJP2file )
+                    {
+                    // JP2 codestream shouldn't in JP2 file format
+                    User::Leave( KErrCorrupt );
+                    }
+
+                // SOC + SIZ marker - JP2 Codestream
+                iState = EStateInCodestreamBox;
+                iJ2kInfo.iCSOffset = iLastRead;
+                }
+            else
+                {
+                // Unrecognized box type
+                // there are two ways of handling this
+                // 1. stop parsing and Leave with an KErrCorrupt error
+                //    User::Leave( KErrCorrupt );
+                // 2. just ignore the box and continue on parsing the 
+                //    next box.
+                IgnoreBoxL();
+                }
+            break;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJp2kDecoder::ScanDataL
+// Called from ICL framework to instantiate decoder and parse header.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJp2kDecoder::ScanDataL()
+    {
+    ReadFormatL();
+
+    ASSERT( ImageReadCodec() == NULL );
+
+    CJp2kReadCodec* imageReadCodec = CJp2kReadCodec::NewL( iJ2kInfo );
+    SetImageReadCodec( imageReadCodec );
+
+    ReadFrameHeadersL();
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// -----------------------------------------------------------------------------
+// Global panic function, From JP2KImageClientMain.h
+// -----------------------------------------------------------------------------
+//
+GLDEF_C void Panic( TIclPanic aError ) //lint !e759 already in module
+    {
+    User::Panic( KJ2KPanicCategory, aError );
+    }
+