svgtopt/SVG/SVGImpl/src/SVGImageElementImpl.cpp
changeset 0 d46562c3d99d
child 17 db5c883ad1c5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/SVG/SVGImpl/src/SVGImageElementImpl.cpp	Thu Jan 07 16:19:02 2010 +0200
@@ -0,0 +1,1543 @@
+/*
+* Copyright (c) 2003 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:  SVG Implementation source file
+ *
+*/
+
+
+#if !defined(__E32BASE_H__)
+#include <e32base.h>
+#endif
+
+#include "SVGImageElementImpl.h"
+#include "SVGDocumentImpl.h"
+#include "SVGEngineImpl.h"
+#include "SVGSchemaData.h"
+
+#include "GfxAffineTransform.h"
+
+#include <imcvcodc.h>
+
+#include <caf/caf.h>
+
+const TInt  KErrNoAttributeSet  = -1;
+#define KSVGWAITFORIMAGEDOWNLOAD 1
+
+#define PERIODIC_DELAY    300000
+#define PERIODIC_INTERVAL 1000000
+
+_LIT( KSvg,  ".svg" );
+_LIT( KSvgb, ".svgb" );
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl* CSvgImageElementImpl::NewL(  const TUint8 aElemID,
+                                                  CSvgDocumentImpl* aDoc )
+    {
+    CSvgImageElementImpl*   self    = new ( ELeave )
+                                      CSvgImageElementImpl( aDoc );
+    CleanupStack::PushL( self );
+    self->ConstructL(  aElemID, aDoc );
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl* CSvgImageElementImpl::NewLC(  const TUint8 aElemID,
+                                                   CSvgDocumentImpl* aDoc )
+    {
+    CSvgImageElementImpl*   self    = new ( ELeave )
+                                      CSvgImageElementImpl( aDoc );
+    CleanupStack::PushL( self );
+    self->ConstructL(  aElemID,aDoc );
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::ConstructL(  const TUint8 aElemID,
+                                       CSvgDocumentImpl* /* aDoc */ )
+    {
+    CSvgElementImpl::InitializeL(  aElemID );
+
+
+    iUsedImage = EFalse;
+//    iBitmap = new ( ELeave ) CFbsBitmap();
+    iReqAttrFlag=KSVG_IMAGE_ELEMFLAG;
+
+    iSvgStyleProperties = new(ELeave) RPointerArray<CCssValue>(KCSS_MAX_ATTR);
+    User::LeaveIfError( iSvgStyleProperties->Append( NULL ) );
+    iSvgStyleProperties->Remove( 0 );
+    iSvgTransformable = CSvgTransformableImpl::NewL();
+    iSvgUriReferenceImpl = CSvgUriReferenceImpl::NewL();
+
+    iBitmapLoadCalled = EFalse;
+
+    iImgRect.iHeight = TFloatFixPt(-1);
+    iImgRect.iWidth = TFloatFixPt(-1);
+
+    iIsBase64 = EFalse;
+    }
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::~CSvgImageElementImpl()
+    {
+    // Reset the notifiers first.
+    NotifyResetReference();
+
+    // Check whether there this element refers to an image element.
+    // This would be the case when use is used to refer to a parent 
+    // image element.
+    if ( iRefElement )
+        {
+        iRefElement->RemoveImageElementListener( this );
+        iRefElement = NULL;
+        }
+        
+    if ( iImageLoader )
+        {
+        delete iImageLoader;
+        iImageLoader = NULL;
+        }
+
+    if ( !iUsedImage )
+        {
+        delete iBitmap;
+        delete iMask;
+        }
+    if ( !iUsedImage && iPar )
+        {
+        if ( iPar )
+            {
+            delete iPar;
+            iPar = NULL;
+            }
+        }
+
+    if ( iImageData )
+        {
+        delete iImageData;
+        iImageData = NULL;
+        }
+
+    if ( iSvgUriReferenceImpl )
+        {
+        delete iSvgUriReferenceImpl;
+        iSvgUriReferenceImpl = NULL;
+        }
+
+
+    if ( iSvgStyleProperties )
+        {
+        iSvgStyleProperties->Close();
+        delete iSvgStyleProperties;
+        iSvgStyleProperties = NULL;
+        }
+
+    iImageElementListeners.Close();
+
+    if ( iSessionConnected )
+        {
+        iSession.Close();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::GetBBox( TGfxRectangle2D& aBbox )
+    {
+    iImgRect.GetBounds( GetCTM(), aBbox );
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox )
+    {
+    TGfxAffineTransform identityTx;
+    iImgRect.GetBounds( identityTx, aBbox );
+    }
+
+// *******************************************************
+// From SVG DOM
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::X()
+    {
+    return iImgRect.iX;
+    }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::Y()
+    {
+    return iImgRect.iY;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::Width()
+    {
+    	if (iImgRect.iWidth == TFloatFixPt(-1))
+    	{
+    		return TFloatFixPt(0);
+    	}
+
+    	return iImgRect.iWidth;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::Height()
+    {
+    	if (iImgRect.iHeight == TFloatFixPt(-1) )
+    	{
+    		return TFloatFixPt(0);
+    	}
+
+    	return iImgRect.iHeight;
+    }
+
+// *******************************************************
+// SVG Implementation
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetWidth( TFloatFixPt aWidth )
+    {
+    iRenderImage = !(aWidth <= TFloatFixPt(0));
+    
+    iImgRect.iWidth = aWidth;
+
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetHeight( TFloatFixPt aHeight )
+    {
+    iRenderImage = !(aHeight <= TFloatFixPt(0));
+    
+    iImgRect.iHeight = aHeight;
+    
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetParL( const TDesC& aName )
+    {
+    iPar = aName.AllocL();
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+const TDesC& CSvgImageElementImpl::Par()
+    {
+    if ( iPar )
+        return *iPar;
+    else
+        return KNullDesC;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetUriL( const TDesC& aUri )
+    {
+    // Indicate that the Uri is set. This is used to decide whether 
+    // to indicate an error if xlink:href attribute was not specified
+    // on the image element.
+    iIsUriSet = ETrue;
+    _LIT( KXlinkHref, "xlink:href" );
+    SetXlinkAttributeL(KXlinkHref, aUri);
+    CheckRequiredAttributes();
+
+	if ( Href().Length() == 0)
+	{
+		//empty URI string...do nothing
+		//JSR 226 tests start out with empty string
+		return;
+	}
+
+	//We have to be careful in this method searching the entire string
+	//because we can get the entire
+	//base64 encoded image coming through this call
+
+    // Verify xlink for JavaInterface
+    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+    //if ( document && aUri.Length() > 0)
+    if ( document )
+        {
+        // Check for local URI (#uri)
+        //if ( aUri.Locate( '#' ) != KErrNotFound || aUri.Length() == 0)
+          if ( Href().Left(1) == _L("#") )
+            {
+            document->SetError( KErrNotFound, _L( "Usage of local URI in <image>: " ), aUri );
+            }
+          else
+            {
+            _LIT( KHttp, "http://" );
+            _LIT( KData, "data:");
+
+            if ( ( Href().Length() >= 7 ) && ( Href().Left( 7 ) == KHttp ) )
+                {
+                //using an http address for the image
+                return;
+                }
+            else if ( ( Href().Length() >= 5 ) && ( Href().Left( 5 ) == KData ) )
+            	{
+            	//this is a base 64 image
+            	iIsBase64 = ETrue;
+            	return;
+            	}
+            else
+                {
+                _LIT( KJpgFile, ".jpg");
+                _LIT( KPngFile, ".png");
+                _LIT( KSvgFile, ".svg");
+
+                // Check for relative URI
+          		if ( aUri.Locate( '/' ) == KErrNotFound)
+          		{
+          			//plain image used...but is this relative?!?
+          			//does JSR 226 need an error thrown on this?
+          			//i.e. image.jpg
+          			if (aUri.Right(4) == KJpgFile)
+          			{
+          				//this is a plain image.jpg
+          				return;
+          			}
+          			else if (aUri.Right(4) == KPngFile)
+          			{
+          				//this is a plain image.png file
+          				return;
+          			}
+          			else if (aUri.Right(4) == KSvgFile)
+          			{
+          				//this is a filename.svg file
+          				document->SetError(KErrNotFound, _L("Usage of SVG file in xlink-href:"), aUri);
+          			}
+          			return;
+          		}
+                /*if ( aUri.Find( KFile ) != 1 || !TChar( aUri[0] ).IsAlpha() )
+                    {
+                    document->SetError( KErrNotFound, _L( "Usage of relative URI in <image>: " ), aUri );
+                    }
+                else
+                	{
+                		//this is an absolute image
+                		//i.e. c:/folder/image.jpg
+                	}*/
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::LoadUriL()
+    {
+    if ( Href().Length() == 0 )
+        {
+        #ifdef _DEBUG
+        RDebug::Printf("CSvgImageElementImpl::LoadUriL()--iUri is NULL or empty.");
+        #endif
+        return;
+        }
+    iBitmapLoadCalled = ETrue;
+    iSessionConnected = EFalse;
+
+    // Cannot continue without SvgEngine instance or
+    // MSvgRequestObserver is not set
+
+    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+    if ( document == NULL )
+        {
+        #ifdef _DEBUG
+        RDebug::Printf("CSvgImageElementImpl::LoadUriL--document handle null");
+        #endif
+        return;
+        }
+
+    // Request
+    if ( ( Href().Length() >= 4 && Href().Right( 4 ) == KSvg ) ||
+         ( Href().Length() >= 5 && Href().Right( 5 ) == KSvgb ) )
+        {
+        iIsSvgFile = ETrue;
+        }
+
+    // Don't call LoadUriL if LoadingListener exists and LoadingListener::WillAssignImageData returns ETrue
+    if ( document )
+        {
+        const RPointerArray<MSvgLoadingListener>* listeners = document->GetLoadingListeners();
+        if ( listeners && listeners->Count() > 0 )
+            {
+            if ( (*listeners)[0]->WillAssignImageData() )
+                {
+                (*listeners)[0]->ImageDataReference( Href() );
+                return;
+                }
+            }
+        }
+
+    // Embedded image
+    if ( ( Href().Length() >= 5 ) && ( Href().Left( 5 ) == _L( "data:" ) ) )
+        {
+        ProcessEncodedImageL( Href() );
+        return;
+        }
+
+    iBitmapOrgReady = EFalse;
+    iBitmapReady = EFalse;
+
+    CSvgEngineImpl* engine  = document->Engine();
+    if ( engine == NULL || engine->iRequestObserver == NULL )
+        {
+        #ifdef _DEBUG
+        RDebug::Printf("CSvgImageElementImpl::LoadUriL--engine handle null");
+        #endif
+        return;
+        }
+    
+    // Connect session
+    RFile fileHandle;
+    if ( iSession.Connect() != KErrNone )
+        {
+        return;
+        }
+    iSessionConnected = ETrue;
+    TInt status = engine->iRequestObserver->FetchImage( Href(), iSession, fileHandle );
+    if ( status == KErrNone )
+        {
+        // prevent division by zero (DrawL) when image fails to load
+        CFbsBitmap* aBitmap = new ( ELeave ) CFbsBitmap();
+        CleanupStack::PushL( aBitmap );
+        TInt lCreateErr = aBitmap->Create( TSize( 1, 1 ), EColor64K );
+        if ( lCreateErr != KErrNone )
+            {
+            // Error in creation, destroy the bitmap and return
+            CleanupStack::PopAndDestroy( aBitmap );
+            return;
+            }
+        // Ownership is about to be tranferred to Image Element
+        CleanupStack::Pop( aBitmap );
+        TInt lDecodeErr = StartImageDecoding( fileHandle, aBitmap, ETrue );
+        if ( lDecodeErr != KErrNone )
+            {
+            // No error Processing
+            }
+        }
+    else
+        {
+        iSession.Close();
+        iSessionConnected = EFalse;
+        }
+    }
+
+void CSvgImageElementImpl::PrepareImageFromSvgFile(const TDesC8& aImageData)
+    {
+    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+    if ( !document )
+        {
+        return;
+        }
+
+    CSvgEngineImpl* engine  = document->Engine();
+    if ( !engine )
+        {
+        return;
+        }
+    TSize bitmapSize( (TInt32)Width(), (TInt32)Height() );
+    if ( !iBitmap )
+        {
+        iBitmap = new CFbsBitmap();
+        }
+    if(!iMask)
+	    {
+		iMask = new CFbsBitmap();        	
+	    }
+    if(iMask)
+        {
+		iMask->Create( bitmapSize, EGray256);        	
+        }
+    // Can't use ELeave because this function can't leave
+    // Using ELeave but didn't handle (no trap or propagate to parents) causes more confusing.
+    // Check for NULL is good enough.
+    // Ignore CodeScanner error (Code Review Guide)
+    if (iBitmap)
+        {
+	    iBitmap->Create( bitmapSize, EColor16MU );
+        
+        TBool preserveRatio = !( iPar != NULL && *iPar == _L( "none" ) );
+        // RenderFileToBuffer if uri is a svg file
+        TInt err = engine->RenderFileToBuffer( aImageData, iBitmap,iMask, preserveRatio );
+        ImageLoadingCompleted(err);
+        }
+    iSession.Close();
+    }
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+
+void CSvgImageElementImpl::ProcessEncodedImageL( const TDesC& aXlinkHrefValue )
+    {
+    // find positions for ';' and ',' to determine encoding, mimetype
+    TInt startIndex = aXlinkHrefValue.Locate( ';' );
+    TInt endIndex = aXlinkHrefValue.Locate( ',' );
+
+    // mimetype is after 'data:' : xlink:href="data:image/png;base64,
+    // ignore mimetype extraction, decode will detect mimetype from decoded data.
+
+    if ( startIndex != KErrNotFound && endIndex != KErrNotFound &&
+         startIndex < endIndex )
+        {
+        // extract encoding type
+        TPtrC encoding( aXlinkHrefValue.Left( endIndex ).Right( endIndex - startIndex - 1 ) );
+        // handle Base64 encoding
+        _LIT( KEncodingBase64, "base64" );
+        if ( encoding == KEncodingBase64 )
+            {
+            // find index of first character after white-space
+            TInt index = endIndex + 1;
+            while ( index < aXlinkHrefValue.Length() && TChar( aXlinkHrefValue[index] ).IsSpace() )
+                index++;
+
+            // must be 8-bit
+            TInt length = aXlinkHrefValue.Length() - index;
+            HBufC8* encoded = HBufC8::NewLC( length );
+            encoded->Des().Copy( aXlinkHrefValue.Right( length ) );
+
+            // Assign to member variable to destroy after image is process.
+            iImageData = HBufC8::NewL( length );
+            TPtr8 decodedDes = iImageData->Des();
+
+            // decode
+            TImCodecB64 encodingBase64;
+            TInt decodeError = encodingBase64.Decode( *encoded, decodedDes );
+            CleanupStack::PopAndDestroy( encoded );
+
+            if ( decodeError == KErrNone )
+                {
+                // prevent division by zero (DrawL) when image fails to load
+                CFbsBitmap* lBitmap = new ( ELeave ) CFbsBitmap();
+                CleanupStack::PushL( lBitmap );
+                TInt lCreateErr = lBitmap->Create( TSize( 1, 1 ), EColor64K );
+                if ( lCreateErr != KErrNone )
+                    {
+                    // Error creating bitmap, delete bitmap and return
+                    CleanupStack::PopAndDestroy( lBitmap );
+                    return;
+                    }
+                // Ownership of aBitmap is about to be transferred to image
+                // element
+                CleanupStack::Pop( lBitmap );
+                // If bitmap was already present, release it
+                if ( iBitmap )
+                    {
+                	delete iBitmap;
+                	iBitmap = NULL;
+                    }
+                iBitmap = lBitmap;
+                TInt lImgDecErr = StartImageDecoding( *iImageData,  
+                        ETrue ); // ETrue means Synchronous Loading
+                if ( lImgDecErr != KErrNone )
+                    {
+                    // No Error Processing
+                    }
+                }
+            }
+        }
+    }
+
+// *******************************************************
+// From MXmlElement
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::SetAttributeL( const TDesC& aName,
+                                          const TDesC& aValue )
+    {
+    _LIT( KTmpUri, "xlink:href" );
+    _LIT( KTmpPreserveAspectRatio, "preserveAspectRatio" );
+
+    if ( this->SetXlinkAttributeL( aName, aValue ) )
+        {
+        if ( aName == KTmpUri )
+            {
+            SetUriL( aValue );
+            CheckRequiredAttributes();
+            }
+        return KErrNone;
+        }
+
+
+    CSvgElementImpl::SetAttributeL(aName,aValue);
+
+    if ( aName == KTmpPreserveAspectRatio )
+        {
+        SetParL( aValue );
+        }
+
+    return KErrNoAttributeSet;
+    }
+
+
+
+// From MXmlElementOpt
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::GetAttributeFloat( const TInt aNameId,
+                                              TFloatFixPt& aValue )
+    {
+    switch ( aNameId )
+        {
+        case KAtrX:
+        case KAtrRefX:
+        aValue = X();
+        break;
+        case KAtrY:
+        case KAtrRefY:
+        aValue = Y();
+        break;
+        case KAtrHeight:
+        aValue = Height();
+        break;
+        case KAtrWidth:
+        aValue = Width();
+        break;
+        default:
+        return CSvgElementImpl::GetAttributeFloat( aNameId, aValue );
+        }
+
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::SetAttributeFloatL( const TInt aNameId,
+                                               const TFloatFixPt aValue )
+    {
+    switch ( aNameId )
+        {
+        case KAtrX:
+        iImgRect.iX = aValue;
+        break;
+        case KAtrY:
+        iImgRect.iY = aValue;
+        break;
+
+        case KAtrHeight:
+        SetHeight( aValue );
+        CheckRequiredAttributes();
+        break;
+
+        case KAtrWidth:
+        SetWidth( aValue );
+        CheckRequiredAttributes();
+        break;
+
+        default:
+        return CSvgElementImpl::SetAttributeFloatL( aNameId, aValue );
+        }
+
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::SetAttributeDesL( const TInt aNameId,
+                                             const TDesC& aValue )
+    {
+    switch ( aNameId )
+        {
+        case KAtrXlinkhref:
+        SetUriL( aValue );
+        CheckRequiredAttributes();
+        break;
+        default:
+        return CSvgElementImpl::SetAttributeDesL( aNameId, aValue );
+        }
+    return KErrNone;
+    }
+
+void CSvgImageElementImpl::ImageLoadingCompleted( TInt aError )
+    {
+ 	iBitmapReady = aError != KErrCancel;    
+    if ( aError == KErrNone )
+        {
+        
+	    PrepareImageWithMask();
+        iBitmapOrgReady = ETrue;
+        // Notify clones that the bitmap is ready.
+   
+   
+        NotifyImageDecoded();
+        
+   		// The redraw needs to be done once the image element is decoded, 
+   		// so that the image is rendered in place in the content.
+   		// If the decoding is done asynchronously, the client does not know
+   		// when the decoding was completed hence it cannot perform a redraw()
+   		// In such a scenario, the image element itself triggers a redraw.
+
+    	if(iImageLoader && !(iImageLoader->IsSynchronousLoading()))
+    		{
+    		CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+    		if(document)
+    			{
+    			CSvgEngineImpl* engine  =document->Engine();
+        		if(engine)
+        			{
+        			engine->ImageLoadingCompleted(aError);
+        			}
+    			}	
+    		}
+         } // if ( aError == KErrNone )
+    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+    if(document)
+        {
+        document->ImageLoadingCompleted(aError);    
+        }
+
+    
+   
+   
+    if ( iSessionConnected )
+        {
+        iSession.Close();
+        iSessionConnected = EFalse;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// void CSvgImageElementImpl::PrepareImageWithMask()
+//  Combines mask information into main bitmap for use with OpenVG
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::PrepareImageWithMask()
+    {
+    if ( iBitmap && iMask )
+        {
+        TSize size = iMask->SizeInPixels();
+        // If size of bitmap and mask do not match, cannot process mask
+        if ( size != iBitmap->SizeInPixels() )
+            {
+            return;
+            }
+        iBitmap->LockHeap();
+        iMask->LockHeap();
+        
+        TUint32* bitmapData = (TUint32*)iBitmap->DataAddress();
+        TUint8* maskData = (TUint8*)iMask->DataAddress();
+        
+        TInt lBmpSLLen = CFbsBitmap::ScanLineLength( size.iWidth,
+        iBitmap->DisplayMode() ); 
+        
+        TInt lMaskSLLen = CFbsBitmap::ScanLineLength( size.iWidth, 
+                iMask->DisplayMode() );
+                
+        TInt count = size.iWidth * size.iHeight;
+        TUint32* lBitmapCurPtr = bitmapData; 
+        TUint8* lMaskCurPtr = maskData; 
+        
+        for ( TInt lIndex = 1; lIndex < count; lIndex++ )
+            {
+             // Converting from ARGB to RGBA8888
+            *lBitmapCurPtr = ( *lBitmapCurPtr & 0x00FFFFFF ) << 8 | *lMaskCurPtr;
+            // Check if one row is complete
+            if ( lIndex % size.iWidth == 0 )
+                {
+                // One row of pixels is complete. Now reposition the 
+                // lBitmapCurPtr, lMaskCurPtr to point to beginning of new row. 
+                // Current row is given by (index/widthMask) 
+                // 
+                // In order to get offset to first pixel, we need to 
+                // perform following 
+                //     BasePtr + Current row * (row width in bytes) 
+                lBitmapCurPtr =(TUint32*)((TUint8*)bitmapData + ( ( lIndex / size.iWidth ) 
+                        * lBmpSLLen ));
+                lMaskCurPtr = maskData + ( ( lIndex  / size.iWidth ) 
+                        * lMaskSLLen ); 
+                } 
+          else 
+                { 
+                // Still within the row, keep incrementing 
+                lBitmapCurPtr++; 
+                lMaskCurPtr++; 
+                } 
+            }
+        iMask->UnlockHeap();
+        iBitmap->UnlockHeap();
+        }
+    }
+
+// *******************************************************
+// From CSvgElementImpl
+
+// perform a deep clone of this object
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+MXmlElement* CSvgImageElementImpl::CloneL(MXmlElement* aParentElement)
+    {
+    CSvgImageElementImpl* newElement = CSvgImageElementImpl::NewL(  this->ElemID(), ((CSvgDocumentImpl*)iOwnerDocument) );
+
+    CleanupStack::PushL(newElement);
+    newElement->iParentNode = aParentElement;
+    // copy everything over
+    this->CopyL(newElement);
+    CleanupStack::Pop();
+    // Add the cloned element to image decode notification list. 
+    // This is done to ensure that the image is decoded only once.
+    AddImageElementListener( newElement );
+    newElement->SetReferenceElement( this );
+    return newElement;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgImageElementImpl::DrawL( CGfx2dGc* aGc, CSvgElementImpl* aElement )
+    {
+    // Set Gc
+    this->DrawShapeL( aGc, aElement );
+
+    if ( iBitmap == NULL )
+        return ETrue;
+    TSize imageSize = iBitmap->SizeInPixels(); //.
+    if ( imageSize.iWidth == 0 || imageSize.iHeight == 0 )
+        return ETrue;
+
+    const TGfxAffineTransform& currentTM = GetCTM();
+
+    aGc->SetTransform( currentTM );
+
+    if ( iBitmapReady && iRenderImage && iBitmap )
+        {
+        aGc->DrawImage( iBitmap, iImgRect, iMask != NULL );
+        }
+    else if ( iBitmapOrgReady && iRenderImage )
+        {
+        aGc->SetForegroundColor( TGfxColor( 0xaaaaaa ) );
+        aGc->SetPaint( NULL );
+        aGc->DrawL( &iImgRect );
+        }
+    return ETrue;
+    }
+
+// *******************************************************
+// Private
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageElementImpl( CSvgDocumentImpl* aDoc ) :  
+    iRenderImage ( ETrue ),
+    iIsUriSet( EFalse ),
+    iImageDecodingDone(EFalse),
+    iBitmapReady( EFalse )
+    {
+    SetOwnerDocument(aDoc);
+    iBitmap = NULL;
+    iMask   = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// perform a deep copy of this object
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CopyL( CSvgImageElementImpl* aDestElement )
+    {
+    if(aDestElement)
+        {
+          // copy stuff from superclass
+        this->CSvgElementImpl::CopyL(aDestElement);
+
+        // copy items special to CSvgImageElementImpl
+        aDestElement->iUsedImage      = ETrue;          // this is not original image
+        delete aDestElement->iBitmap;                  // delete old
+        aDestElement->iBitmap         = this->iBitmap; // borrow new
+        aDestElement->iImgRect        = this->iImgRect;
+        aDestElement->iPar            = this->iPar;
+        aDestElement->iBitmapOrgReady = ETrue;
+        aDestElement->iBitmapReady    = ETrue;
+        aDestElement->iRenderImage    = ETrue;
+		aDestElement->iIsBase64 = this->iIsBase64;
+
+        // copy the reference to idoc (CSvgDocumentImpl)
+        aDestElement->iOwnerDocument = this->iOwnerDocument;
+        }
+
+
+    }
+
+/********************* Helping Class **************************/
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil* CSvgImageElementImpl::CSvgImageLoaderUtil::NewL( 
+    MSVGImageLoadingObserver* aObserver,
+    RFile& aFileHandle,
+    TBool aSyncLoading )
+    {
+    CSvgImageLoaderUtil* self = new ( ELeave ) CSvgImageLoaderUtil( );
+    CleanupStack::PushL( self );
+    self->ConstructL( aObserver, aFileHandle, aSyncLoading );
+    CleanupStack::Pop();
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil* CSvgImageElementImpl::CSvgImageLoaderUtil::NewL( 
+    MSVGImageLoadingObserver* aObserver,
+    const TDesC8& aEncodedData,
+    TBool aSyncLoading )
+    {
+    CSvgImageLoaderUtil* self = new ( ELeave ) CSvgImageLoaderUtil( );
+    CleanupStack::PushL( self );
+    self->ConstructL( aObserver, aEncodedData, aSyncLoading );
+    CleanupStack::Pop();
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil::~CSvgImageLoaderUtil()
+    {
+    Cancel();
+    if(iImageDecoder)
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;
+        }
+    if ( iActiveSchedulerWait )
+        {
+        delete iActiveSchedulerWait;
+        }
+    if(iImageByteData)
+    	{
+    	delete iImageByteData;
+    	iImageByteData=NULL;
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// Set the display mode (color mode), the default value is EColor64K.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::SetDisplayMode( TDisplayMode aDisplayMode )
+    {
+    iDisplayMode = aDisplayMode;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns the FrameInfo of Image
+// ---------------------------------------------------------------------------
+TFrameInfo CSvgImageElementImpl::CSvgImageLoaderUtil::GetFrameInfo()
+    {
+	return iImageDecoder->FrameInfo(); 
+    }
+
+
+// ---------------------------------------------------------------------------
+// Request asynchronously for the image, sized to the image size.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::RequestForImageL( CFbsBitmap& aBitmap,
+                                                                  CFbsBitmap& aMask,
+                                                                  TBool       aHasAlpha,
+                                                                  TFrameInfo  aFrameInfo )
+    {
+    if ( iImageDecoder != NULL )
+        {
+        if ( aHasAlpha )
+            {
+            User::LeaveIfError( aMask.Create( aFrameInfo.iOverallSizeInPixels, EGray256 ) );
+            User::LeaveIfError( aBitmap.Create( aFrameInfo.iOverallSizeInPixels, EColor16MU ) );
+            iImageDecoder->Convert( &iStatus, aBitmap, aMask, 0 );
+            }
+        else
+            {
+            User::LeaveIfError( aBitmap.Create( aFrameInfo.iOverallSizeInPixels, EColor64K ) );
+            iImageDecoder->Convert( &iStatus, aBitmap, 0 );
+            }
+
+        SetActive();
+        if ( iActiveSchedulerWait )
+            {
+            iActiveSchedulerWait->Start();
+            }
+        }
+    else
+        {
+        iObserver->ImageLoadingCompleted( KErrNotFound );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Override method from CActive, called upon successful completion of request
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::RunL()
+    {
+    if ( iActiveSchedulerWait )
+        {
+        iActiveSchedulerWait->AsyncStop();
+        }
+    if ( iObserver )
+        {
+        iObserver->ImageLoadingCompleted( iStatus.Int() );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Override method from CActive, called upon a cancel of request
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::DoCancel()
+    {
+    if ( iImageDecoder != NULL )
+        {
+        iImageDecoder->Cancel();
+        }
+    
+    // must delete decoder immediate or exception occurs in destructor.
+    delete iImageDecoder;
+    iImageDecoder = NULL;
+    iObserver->ImageLoadingCompleted( KErrCancel );
+    }
+
+// ---------------------------------------------------------------------------
+// Override method from CActive, called upon an error from request
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::CSvgImageLoaderUtil::RunError( TInt aError )
+    {
+    // must delete decoder immediate or exception occurs in destructor.
+    delete iImageDecoder;
+    iImageDecoder = NULL;
+    iObserver->ImageLoadingCompleted( aError );
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil::CSvgImageLoaderUtil() : CActive( EPriorityNormal )
+    {
+    SetDisplayMode( EColor64K );
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------------------------
+// Second phase Construction
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::ConstructL( 
+    MSVGImageLoadingObserver* aObserver, 
+    RFile& aFileHandle,
+    TBool aSyncLoading )
+    {
+    iObserver = aObserver;
+    iIsSyncLoading=aSyncLoading;
+    
+    // Reset to start of file
+    TInt zero = 0;
+    aFileHandle.Seek( ESeekStart, zero );
+
+    TInt fileSize = 0;
+    TInt sizeError = aFileHandle.Size( fileSize );
+    if ( sizeError != KErrNone )
+    	{
+      
+     	return;
+       	}
+
+ 	
+	iImageByteData = HBufC8::New ( fileSize );
+
+	 if (!iImageByteData)
+    	{
+        
+       	return;
+       	}
+	
+	TPtr8 binaryBufferPtr = iImageByteData->Des();
+	
+	// Read the image data into a buffer.
+	TInt readError = aFileHandle.Read(binaryBufferPtr, fileSize);
+	if ( readError != KErrNone )
+    	{
+        delete iImageByteData;
+        iImageByteData = NULL;
+        return;
+    	}
+    // Unused parameter	
+    RFs session;
+    iImageDecoder = CImageDecoder::DataNewL( session, *iImageByteData, CImageDecoder::TOptions( CImageDecoder::EAllowGeneratedMask | 
+        CImageDecoder::EOptionAlwaysThread )); 
+    iImageDecoder->SetDecoderThreadPriority( EPriorityNormal );
+	
+    if ( aSyncLoading )
+        {
+        iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait();
+        }
+    }
+
+void CSvgImageElementImpl::CSvgImageLoaderUtil::ConstructL( MSVGImageLoadingObserver* aObserver,
+                                                            const TDesC8& aEncodedData,
+                                                            TBool aSyncLoading )
+    {
+    iObserver = aObserver;
+    iIsSyncLoading=aSyncLoading;
+    // Unused parameter
+    RFs session;
+    iImageDecoder = CImageDecoder::DataNewL( session, aEncodedData, CImageDecoder::TOptions( CImageDecoder::EAllowGeneratedMask | 
+        CImageDecoder::EOptionAlwaysThread ));
+    iImageDecoder->SetDecoderThreadPriority( EPriorityNormal );
+    if ( aSyncLoading )
+        {
+        iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait();
+        }
+    }
+
+TInt CSvgImageElementImpl::GetAttributeDes( const TInt aNameId,
+                                                     TPtrC16& aValue )
+{
+ if(aNameId == KAtrPreserveAspectRatio)
+     {
+     aValue.Set( Par() );
+     return KErrNone;
+     }
+ // added for updation of Get/Set
+ if( aNameId == KAtrXlinkhref )
+    {
+     aValue.Set( Href() );
+     return KErrNone;
+    }
+ return CSvgElementImpl::GetAttributeDes( aNameId, aValue );
+
+}
+
+// MSvgImageDecodingRequester method
+TInt CSvgImageElementImpl::StartImageDecoding( const TDesC8& aImageData,
+                                               TBool aSyncLoading )
+    {
+    if ( iBitmap != NULL )
+        {
+        
+        if( iIsSvgFile )
+            {
+        	// SVG files are decoded by engine and do not follow the ImageDecoder Path
+        	PrepareImageFromSvgFile(aImageData);             
+            return KErrNone;
+            }
+    	if( iImageDecodingDone )
+    	    {
+    	    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+    	    if(document)
+    	        {
+    	        TInt incCnt = document->GetImageElementsCount() + 1;
+        	    document->SetImageElementsCount(incCnt);
+                }
+            
+    	    }
+    	else
+    	    {
+    	    iImageDecodingDone = ETrue;
+    	    }
+        // Check if the iImageLoader already exists for the ImageElement
+        TInt err = KErrNone;
+        
+        if( iImageLoader == NULL )
+        {
+        	TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
+            aImageData,
+            aSyncLoading ));  // EFalse means Asynchronous decoding	
+        }
+        else
+        {
+        	// Cancel the currently active request if the request is pending.
+        	if( iImageLoader)
+        	{
+        		delete iImageLoader;
+        		iImageLoader = NULL;
+        	}
+        	
+        	TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
+            aImageData,
+            aSyncLoading ));  // EFalse means Asynchronous decoding	
+        }
+        
+        if ( err != KErrNone || !iImageLoader )
+            {
+            #ifdef _DEBUG
+            RDebug::Printf("CSvgImageElementImpl::StartImageDecoding failed");
+            #endif
+            ImageLoadingCompleted(err);
+            return err;
+            }
+
+        TFrameInfo lFrameInfo( iImageLoader->GetFrameInfo() );
+		TBool      lHasAlpha = (lFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
+       
+        if( lHasAlpha )
+            {
+        	if( iMask )
+        	    {
+        		delete iMask;
+        		iMask = NULL;
+        	    }
+        	
+        	iMask = new (ELeave) CFbsBitmap();
+            }
+        
+        TRAPD(err2, iImageLoader->RequestForImageL( *iBitmap, *iMask, lHasAlpha, lFrameInfo ));
+        if ( err2 != KErrNone )
+            {
+            #ifdef _DEBUG
+            RDebug::Printf("CSvgImageElementImpl::StartImageDecoding RequestForImageL() failed");
+            #endif
+            ImageLoadingCompleted(err2);
+            return err2;
+            }
+        }
+    return KErrNone;
+    }
+
+
+TInt CSvgImageElementImpl::StartImageDecoding( RFile& aImageFile,
+                                               CFbsBitmap* aBitmap,
+                                               TBool aSyncLoading )
+    {
+    if ( iBitmap )
+        {
+        // Destroy the existing bitmap
+        delete iBitmap;
+        }
+    // Take ownership of the bitmap
+    iBitmap = aBitmap;
+
+    if ( iBitmap != NULL )
+        {
+        if( iIsSvgFile )
+            {
+               	
+        	TInt length;
+        	aImageFile.Size(length);
+        	
+        	HBufC8 *aImageData = HBufC8::NewL( length );
+           	TPtr8 des = aImageData->Des();
+        	
+        	TInt readError = aImageFile.Read( des );
+        	if ( readError != KErrNone )
+        		{
+            	delete aImageData;
+        		return KErrGeneral;
+        		}
+        	else
+        		{
+        		// SVG files are decoded by engine and do not follow the ImageDecoder Path
+        		PrepareImageFromSvgFile(des);             
+            	return KErrNone;
+        		}        	
+            }
+    	if( iImageDecodingDone )
+    	    {
+    	    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+    	    if(document)
+    	        {
+    	        TInt incCnt = document->GetImageElementsCount() + 1;
+        	    document->SetImageElementsCount(incCnt);
+                }
+            
+    	    }
+    	else
+    	    {
+    	    iImageDecodingDone = ETrue;
+    	    }
+        
+        TInt err = KErrNone;
+        // Check if the iImageLoader already exists for the ImageElement
+        if( iImageLoader == NULL )
+            {
+        	TRAP( err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
+            aImageFile,
+            aSyncLoading ));  // EFalse means Asynchronous decoding	
+            }
+        else
+            {
+        	// Cancel the currently active request if the request is pending.
+        	if( iImageLoader)
+        	   {
+        	   delete iImageLoader;
+        	   iImageLoader = NULL;
+        	   }
+        	
+        	TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
+            aImageFile,
+            aSyncLoading ));  // EFalse means Asynchronous decoding	
+            }
+        
+        if ( err != KErrNone || !iImageLoader )
+            {
+            #ifdef _DEBUG
+            RDebug::Printf("CSvgImageElementImpl::StartImageDecoding failed");
+            #endif
+            ImageLoadingCompleted(err);
+            return err;
+            }
+        // Get the Frame info and based on it create the iMask if required.
+        TFrameInfo lFrameInfo( iImageLoader->GetFrameInfo() );
+		TBool      lHasAlpha = (lFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
+       
+        if( lHasAlpha )
+            {
+        	if( iMask )
+        	    {
+        		delete iMask;
+        		iMask = NULL;
+        	    }
+        	
+        	iMask = new (ELeave) CFbsBitmap();
+            }
+            
+            
+        TRAPD(err2, iImageLoader->RequestForImageL( *iBitmap, *iMask, lHasAlpha, lFrameInfo ));
+        
+        if ( err2 != KErrNone )
+            {
+            #ifdef _DEBUG
+            RDebug::Printf("CSvgImageElementImpl::StartImageDecoding RequestForImageL() failed");
+            #endif
+            ImageLoadingCompleted(err);
+            return err2;
+            }
+        }
+    return KErrNone;
+    }
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::SetReferenceElement
+//  Informs the image element that it is referring to a particular image 
+//  element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetReferenceElement( CSvgImageElementImpl* 
+    aImageElement )
+    {
+    iRefElement = aImageElement;
+    }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::GetReferenceElement
+//  Get Function for reference element
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl* CSvgImageElementImpl::ReferenceElement()
+    {
+    return iRefElement;
+    }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::AddImageElementListener
+//  Adds an image element listener - used in the case of cloning of image 
+//  element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::AddImageElementListener( 
+    MSvgImageElementListener* aListener )
+    {
+    if ( iImageElementListeners.Find( aListener ) != KErrNotFound )
+        {
+        return;
+        }
+    if ( iImageElementListeners.Append( aListener ) != KErrNone )
+        {
+        #ifdef _DEBUG
+        RDebug::Printf("iImageElementListeners.Append failed");
+        #endif
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::RemoveImageElementListener
+//  Removes an image element listener - used in the case of cloning of image 
+//  element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::RemoveImageElementListener( 
+    MSvgImageElementListener* aListener )
+    {
+    TInt index = iImageElementListeners.Find( aListener );
+    if ( index == KErrNotFound )
+        {
+        return;
+        }
+    iImageElementListeners.Remove( index );
+    }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::BitmapDecoded
+//  This is the callback implementation for updating the decoded image 
+//  and mask from referenced image element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::BitmapDecoded( CFbsBitmap* aBitmap, 
+    CFbsBitmap* aMask )
+    {
+    // Save the pointers to the decoded bitmap in this element,
+    // this can be used in subsequent draw.
+    // Note: Both the bitmap and mask are not owned by this element.
+    // It is owned by the reference element.
+    iBitmap = aBitmap;
+    iMask = aMask;
+
+    iBitmapReady = iBitmap != NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::ResetReference
+//  This is the callback implementation for resetting reference element 
+//  pointer
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::ResetReference()
+    {
+    // Stop referring to the reference element.
+    iRefElement = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::NotifyImageDecoded
+//  Notify listeners that image has been decoded.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::NotifyImageDecoded()
+    {
+    TInt imageEleListenersCnt = iImageElementListeners.Count();
+    for ( TInt i = 0; i < imageEleListenersCnt; i++ )
+        {
+        iImageElementListeners[i]->BitmapDecoded( iBitmap, iMask );
+        }
+}
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::ResetReference
+//  Notify listeners to reset their reference element pointers
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::NotifyResetReference()
+    {
+    TInt imageEleListenersCnt = iImageElementListeners.Count();
+    for ( TInt i = 0; i < imageEleListenersCnt; i++ )
+        {
+        iImageElementListeners[i]->ResetReference();
+        }
+}
+
+void CSvgImageElementImpl::Print( TBool aIsEncodeOn )
+{
+	if (!aIsEncodeOn)
+	{
+		#ifdef _DEBUG
+		RDebug::Printf("<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xlink:href=\"hmm\" \\>", (int)X(), (int)Y(), (int)Width(), (int)Height()/*, Href()*/);
+		#endif
+	}
+}
+
+CFbsBitmap* CSvgImageElementImpl::GetBitmap()
+    {
+    return iBitmap;
+    }
+
+void CSvgImageElementImpl::SetBitmap( CFbsBitmap* aBitmap )    
+    {
+    if ( iBitmap )
+        {
+    	delete iBitmap;
+    	iBitmap = NULL;
+        }
+	iBitmap = aBitmap;
+    }
+
+void CSvgImageElementImpl::AssignImageData( HBufC8* aData )
+    {
+    if(iImageData)
+        {
+        delete iImageData;
+        iImageData = NULL;
+        }
+    iImageData = aData;
+    }
+
+TInt CSvgImageElementImpl::CheckRequiredAttributes()
+{
+	if ( !( iImgRect.iHeight >= TFloatFixPt(0) ) )
+	{
+		//need a height
+		iReqAttrFlag = KAtrHeight;
+		return iReqAttrFlag;
+	}
+
+	if ( !( iImgRect.iWidth >= TFloatFixPt(0)) )
+	{
+		iReqAttrFlag = KAtrWidth;
+		return iReqAttrFlag;
+	}
+
+	
+	if ( !iIsUriSet )
+	{
+		iReqAttrFlag = KAtrXlinkhref;
+		return iReqAttrFlag;
+	}
+
+	iReqAttrFlag = 0;
+	
+	// check if the diplay property is turned off programatically
+	if( WasTurnedOff() )
+	{
+	    _LIT(KInline, "inline");
+	    // turn it on. this means all the required attributes Are present and
+	    // hence we can render it.
+	    CSvgElementImpl::SetPropertyL(KCSS_ATTR_DISPLAY, KInline);
+	    SetTurnOff( EFalse );
+	}
+	
+	return 0;
+}
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::IsSynchronousLoading
+// Returns whether the image decoding was synchronous or not
+// ---------------------------------------------------------------------------
+TBool CSvgImageElementImpl::CSvgImageLoaderUtil::IsSynchronousLoading()
+	{
+	return iIsSyncLoading;
+	}