/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <com/sun/star/embed/XTransactedObject.hpp>
#ifndef _COM_SUN_STAR_EMBED_ElementModes_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <cppuhelper/compbase4.hxx>

#include <unotools/ucbstreamhelper.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/tempfile.hxx>
#include <tools/debug.hxx>
#include <vcl/cvtgrf.hxx>
#include <vcl/gfxlink.hxx>
#include <vcl/metaact.hxx>
#include <tools/zcodec.hxx>

#include "svtools/filter.hxx"
#include "svx/xmlgrhlp.hxx"

#include <algorithm>

// -----------
// - Defines -
// -----------

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::io;

using ::com::sun::star::lang::XMultiServiceFactory;

#define XML_GRAPHICSTORAGE_NAME		"Pictures"
#define XML_PACKAGE_URL_BASE		"vnd.sun.star.Package:"
#define XML_GRAPHICOBJECT_URL_BASE	"vnd.sun.star.GraphicObject:"

// ---------------------------
// - SvXMLGraphicInputStream -
// ---------------------------

const MetaCommentAction* ImplCheckForEPS( GDIMetaFile& rMtf )
{
	static ByteString aComment( (const sal_Char*)"EPSReplacementGraphic" );
	const MetaCommentAction* pComment = NULL;

	if ( ( rMtf.GetActionCount() >= 2 )
			&& ( rMtf.FirstAction()->GetType() == META_EPS_ACTION )
			&& ( ((const MetaAction*)rMtf.GetAction( 1 ))->GetType() == META_COMMENT_ACTION )
			&& ( ((const MetaCommentAction*)rMtf.GetAction( 1 ))->GetComment() == aComment ) )
		pComment = (const MetaCommentAction*)rMtf.GetAction( 1 );

	return pComment;
}

class SvXMLGraphicInputStream : public::cppu::WeakImplHelper1< XInputStream >
{
private:

    virtual sal_Int32	SAL_CALL	readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
	virtual sal_Int32	SAL_CALL	readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
	virtual void		SAL_CALL	skipBytes(sal_Int32 nBytesToSkip) throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
	virtual sal_Int32	SAL_CALL	available() throw(NotConnectedException, RuntimeException);
	virtual void		SAL_CALL	closeInput() throw(NotConnectedException, RuntimeException);

private:

    ::utl::TempFile                 maTmp;
    Reference< XInputStream >       mxStmWrapper;

                                    // not available
                                    SvXMLGraphicInputStream();
                                    SvXMLGraphicInputStream( const SvXMLGraphicInputStream& );
    SvXMLGraphicInputStream&        operator==( SvXMLGraphicInputStream& );

public:

                                    SvXMLGraphicInputStream( const ::rtl::OUString& rGraphicId );
    virtual                         ~SvXMLGraphicInputStream();

    sal_Bool                        Exists() const { return mxStmWrapper.is(); }
};

// -----------------------------------------------------------------------------

SvXMLGraphicInputStream::SvXMLGraphicInputStream( const ::rtl::OUString& rGraphicId )
{
	String			aGraphicId( rGraphicId );
	GraphicObject	aGrfObject( ByteString( aGraphicId, RTL_TEXTENCODING_ASCII_US ) );

    maTmp.EnableKillingFile();

	if( aGrfObject.GetType() != GRAPHIC_NONE )
	{
        SvStream* pStm = ::utl::UcbStreamHelper::CreateStream( maTmp.GetURL(), STREAM_WRITE | STREAM_TRUNC );

        if( pStm )
        {
			Graphic			aGraphic( (Graphic&) aGrfObject.GetGraphic() );
			const GfxLink	aGfxLink( aGraphic.GetLink() );
            sal_Bool        bRet = sal_False;

			if( aGfxLink.GetDataSize() && aGfxLink.GetData() )
            {
				pStm->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() );
			    bRet = ( pStm->GetError() == 0 );
            }
			else
			{
				if( aGraphic.GetType() == GRAPHIC_BITMAP )
				{
					GraphicFilter*  pFilter = GraphicFilter::GetGraphicFilter();
                    String          aFormat;

					if( aGraphic.IsAnimated() )
						aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "gif" ) );
					else
						aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "png" ) );

					bRet = ( pFilter->ExportGraphic( aGraphic, String(), *pStm, pFilter->GetExportFormatNumberForShortName( aFormat ) ) == 0 );
				}
				else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE )
				{
					pStm->SetVersion( SOFFICE_FILEFORMAT_8 );
					pStm->SetCompressMode( COMPRESSMODE_ZBITMAP );
					( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( *pStm );
    			    bRet = ( pStm->GetError() == 0 );
				}
			}

            if( bRet )
            {
                pStm->Seek( 0 );
                mxStmWrapper = new ::utl::OInputStreamWrapper( pStm, sal_True );
            }
            else
                delete pStm;
        }
    }
}

// -----------------------------------------------------------------------------

SvXMLGraphicInputStream::~SvXMLGraphicInputStream()
{
}

// -----------------------------------------------------------------------------

sal_Int32 SAL_CALL SvXMLGraphicInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
    throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException();

    return mxStmWrapper->readBytes( rData, nBytesToRead );
}

// -----------------------------------------------------------------------------

sal_Int32 SAL_CALL SvXMLGraphicInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
    throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException() ;

    return mxStmWrapper->readSomeBytes( rData, nMaxBytesToRead );
}

// -----------------------------------------------------------------------------

void SAL_CALL SvXMLGraphicInputStream::skipBytes( sal_Int32 nBytesToSkip )
    throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException() ;

    mxStmWrapper->skipBytes( nBytesToSkip );
}

// -----------------------------------------------------------------------------

sal_Int32 SAL_CALL SvXMLGraphicInputStream::available() throw( NotConnectedException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException() ;

    return mxStmWrapper->available();
}

// -----------------------------------------------------------------------------

void SAL_CALL SvXMLGraphicInputStream::closeInput() throw( NotConnectedException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException() ;

    mxStmWrapper->closeInput();
}

// ----------------------------
// - SvXMLGraphicOutputStream -
// ----------------------------

class SvXMLGraphicOutputStream : public::cppu::WeakImplHelper1< XOutputStream >
{
private:

    // XOutputStream
    virtual void SAL_CALL           writeBytes( const Sequence< sal_Int8 >& rData ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException );
    virtual void SAL_CALL           flush() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException );
    virtual void SAL_CALL           closeOutput() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException );

private:

    ::utl::TempFile*                mpTmp;
    SvStream*                       mpOStm;
    Reference< XOutputStream >      mxStmWrapper;
    GraphicObject                   maGrfObj;
    sal_Bool                        mbClosed;

                                    // not available
                                    SvXMLGraphicOutputStream( const SvXMLGraphicOutputStream& );
    SvXMLGraphicOutputStream&       operator==( SvXMLGraphicOutputStream& );

public:

                                    SvXMLGraphicOutputStream();
    virtual                         ~SvXMLGraphicOutputStream();

    sal_Bool                        Exists() const { return mxStmWrapper.is(); }
    const GraphicObject&            GetGraphicObject();
};

// -----------------------------------------------------------------------------

SvXMLGraphicOutputStream::SvXMLGraphicOutputStream() :
    mpTmp( new ::utl::TempFile ),
    mbClosed( sal_False )
{
    mpTmp->EnableKillingFile();

    mpOStm = ::utl::UcbStreamHelper::CreateStream( mpTmp->GetURL(), STREAM_WRITE | STREAM_TRUNC );

    if( mpOStm )
        mxStmWrapper = new ::utl::OOutputStreamWrapper( *mpOStm );
}

// -----------------------------------------------------------------------------

SvXMLGraphicOutputStream::~SvXMLGraphicOutputStream()
{
    delete mpTmp;
    delete mpOStm;
}

// -----------------------------------------------------------------------------

void SAL_CALL SvXMLGraphicOutputStream::writeBytes( const Sequence< sal_Int8 >& rData )
    throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException() ;

    mxStmWrapper->writeBytes( rData );
}

// -----------------------------------------------------------------------------

void SAL_CALL SvXMLGraphicOutputStream::flush()
    throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException() ;

    mxStmWrapper->flush();
}

// -----------------------------------------------------------------------------

void SAL_CALL SvXMLGraphicOutputStream::closeOutput()
    throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
{
    if( !mxStmWrapper.is() )
        throw NotConnectedException() ;

    mxStmWrapper->closeOutput();
    mxStmWrapper = Reference< XOutputStream >();

    mbClosed = sal_True;
}

// ------------------------------------------------------------------------------

const GraphicObject& SvXMLGraphicOutputStream::GetGraphicObject()
{
    if( mbClosed && ( maGrfObj.GetType() == GRAPHIC_NONE ) && mpOStm )
    {
    	Graphic aGraphic;

        mpOStm->Seek( 0 );
		sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
		sal_uInt16 pDeterminedFormat = GRFILTER_FORMAT_DONTKNOW;
        GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *mpOStm ,nFormat,&pDeterminedFormat );

		if (pDeterminedFormat == GRFILTER_FORMAT_DONTKNOW)
		{
			//Read the first two byte to check whether it is a gzipped stream, is so it may be in wmz or emz format
			//unzip them and try again

			sal_uInt8    sFirstBytes[ 2 ];

			mpOStm->Seek( STREAM_SEEK_TO_END );
			sal_uIntPtr nStreamLen = mpOStm->Tell();
			mpOStm->Seek( 0 );

			if ( !nStreamLen )
			{
				SvLockBytes* pLockBytes = mpOStm->GetLockBytes();
				if ( pLockBytes  )
					pLockBytes->SetSynchronMode( sal_True );

				mpOStm->Seek( STREAM_SEEK_TO_END );
				nStreamLen = mpOStm->Tell();
				mpOStm->Seek( 0 );
			}
			if( nStreamLen >= 2 )
			{
				//read two byte
				mpOStm->Read( sFirstBytes, 2 );

				if( sFirstBytes[0] == 0x1f && sFirstBytes[1] == 0x8b )
				{
					SvMemoryStream* pDest = new SvMemoryStream;
					ZCodec aZCodec( 0x8000, 0x8000 );
					aZCodec.BeginCompression(ZCODEC_GZ_LIB);
					mpOStm->Seek( 0 );
					aZCodec.Decompress( *mpOStm, *pDest );

					if (aZCodec.EndCompression() && pDest )
					{
						pDest->Seek( STREAM_SEEK_TO_END );
						sal_uIntPtr nStreamLen_ = pDest->Tell();
						if (nStreamLen_)
						{
							pDest->Seek(0L);
					        GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pDest ,nFormat,&pDeterminedFormat );
						}
					}
					delete pDest;
				}
			}
		}

		maGrfObj = aGraphic;
        if( maGrfObj.GetType() != GRAPHIC_NONE )
	    {
		    delete mpOStm, mpOStm = NULL;
			delete mpTmp, mpTmp = NULL;
		}
    }

    return maGrfObj;
}

// ----------------------
// - SvXMLGraphicHelper -
// ----------------------

SvXMLGraphicHelper::SvXMLGraphicHelper( SvXMLGraphicHelperMode eCreateMode ) :
	::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver,
                                      ::com::sun::star::document::XBinaryStreamResolver >( maMutex )
{
	Init( NULL, eCreateMode, sal_False );
}

SvXMLGraphicHelper::SvXMLGraphicHelper() :
	::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver,
                                      ::com::sun::star::document::XBinaryStreamResolver >( maMutex )
{
}

// -----------------------------------------------------------------------------

SvXMLGraphicHelper::~SvXMLGraphicHelper()
{
}

// -----------------------------------------------------------------------------

void SAL_CALL SvXMLGraphicHelper::disposing()
{
}

// -----------------------------------------------------------------------------

sal_Bool SvXMLGraphicHelper::ImplGetStreamNames( const ::rtl::OUString& rURLStr,
												 ::rtl::OUString& rPictureStorageName,
												 ::rtl::OUString& rPictureStreamName )
{
	String		aURLStr( rURLStr );
	sal_Bool	bRet = sal_False;

	if( aURLStr.Len() )
	{
		aURLStr = aURLStr.GetToken( aURLStr.GetTokenCount( ':' ) - 1, ':' );
		const sal_uInt32 nTokenCount = aURLStr.GetTokenCount( '/' );

		if( 1 == nTokenCount )
		{
			rPictureStorageName = String( RTL_CONSTASCII_USTRINGPARAM( XML_GRAPHICSTORAGE_NAME ) );
			rPictureStreamName = aURLStr;
			bRet = sal_True;
		}
		else if( 2 == nTokenCount )
		{
			rPictureStorageName = aURLStr.GetToken( 0, '/' );

			DBG_ASSERT( rPictureStorageName.getLength() &&
					   rPictureStorageName.getStr()[ 0 ] != '#',
					   "invalid relative URL" );

			rPictureStreamName = aURLStr.GetToken( 1, '/' );
			bRet = sal_True;
		}
		else
		{
			DBG_ERROR( "SvXMLGraphicHelper::ImplInsertGraphicURL: invalid scheme" );
		}
	}

	return bRet;
}

// -----------------------------------------------------------------------------

uno::Reference < embed::XStorage > SvXMLGraphicHelper::ImplGetGraphicStorage( const ::rtl::OUString& rStorageName )
{
    uno::Reference < embed::XStorage > xRetStorage;
    if( mxRootStorage.is() )
	{
        try
        {
            xRetStorage = mxRootStorage->openStorageElement(
                maCurStorageName = rStorageName,
                ( GRAPHICHELPER_MODE_WRITE == meCreateMode )
                    ? embed::ElementModes::READWRITE
                    : embed::ElementModes::READ );
        }
        catch ( uno::Exception& )
        {
        }
        //#i43196# try again to open the storage element - this time readonly
        if(!xRetStorage.is())
        {
            try
            {
                xRetStorage = mxRootStorage->openStorageElement( maCurStorageName = rStorageName, embed::ElementModes::READ );
            }
            catch ( uno::Exception& )
            {
            }
        }
    }

	return xRetStorage;
}

// -----------------------------------------------------------------------------

SvxGraphicHelperStream_Impl SvXMLGraphicHelper::ImplGetGraphicStream( const ::rtl::OUString& rPictureStorageName,
															  const ::rtl::OUString& rPictureStreamName,
															  sal_Bool bTruncate )
{
    SvxGraphicHelperStream_Impl aRet;
    aRet.xStorage = ImplGetGraphicStorage( rPictureStorageName );

    if( aRet.xStorage.is() )
	{
        sal_Int32 nMode = embed::ElementModes::READ;
        if ( GRAPHICHELPER_MODE_WRITE == meCreateMode )
        {
            nMode = embed::ElementModes::READWRITE;
            if ( bTruncate )
                nMode |= embed::ElementModes::TRUNCATE;
        }

        aRet.xStream = aRet.xStorage->openStreamElement( rPictureStreamName, nMode );
        if( aRet.xStream.is() && ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) )
		{
//REMOVE				::rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM("Encrypted") );
			::rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
            uno::Reference < beans::XPropertySet > xProps( aRet.xStream, uno::UNO_QUERY );
            xProps->setPropertyValue( aPropName, uno::makeAny( sal_True) );
		}
	}

    return aRet;
}

// -----------------------------------------------------------------------------

String SvXMLGraphicHelper::ImplGetGraphicMimeType( const String& rFileName ) const
{
    struct XMLGraphicMimeTypeMapper
    {
	    const char*	pExt;
	    const char*	pMimeType;
    };

    static XMLGraphicMimeTypeMapper aMapper[] =
    {
        { "gif", "image/gif" },
        { "png", "image/png" },
        { "jpg", "image/jpeg" },
        { "tif", "image/tiff" },
        { "svg", "image/svg+xml" }
    };

    String aMimeType;

    if( ( rFileName.Len() >= 4 ) && ( rFileName.GetChar( rFileName.Len() - 4 ) == '.' ) )
    {
        const ByteString aExt( rFileName.Copy( rFileName.Len() - 3 ), RTL_TEXTENCODING_ASCII_US );

        for( long i = 0, nCount = sizeof( aMapper ) / sizeof( aMapper[ 0 ] ); ( i < nCount ) && !aMimeType.Len(); i++ )
            if( aExt == aMapper[ i ].pExt )
                aMimeType = String( aMapper[ i ].pMimeType, RTL_TEXTENCODING_ASCII_US );
    }

    return aMimeType;
}

// -----------------------------------------------------------------------------

Graphic SvXMLGraphicHelper::ImplReadGraphic( const ::rtl::OUString& rPictureStorageName,
											 const ::rtl::OUString& rPictureStreamName )
{
	Graphic				aGraphic;
    SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, sal_False ) );
    if( aStream.xStream.is() )
    {
        SvStream* pStream = utl::UcbStreamHelper::CreateStream( aStream.xStream );
        GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pStream );
        delete pStream;
    }

	return aGraphic;
}

// -----------------------------------------------------------------------------

sal_Bool SvXMLGraphicHelper::ImplWriteGraphic( const ::rtl::OUString& rPictureStorageName,
											   const ::rtl::OUString& rPictureStreamName,
											   const ::rtl::OUString& rGraphicId )
{
	String			aGraphicId( rGraphicId );
	GraphicObject	aGrfObject( ByteString( aGraphicId, RTL_TEXTENCODING_ASCII_US ) );
	sal_Bool		bRet = sal_False;

	if( aGrfObject.GetType() != GRAPHIC_NONE )
	{
        SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, sal_False ) );
        if( aStream.xStream.is() )
        {
			Graphic			aGraphic( (Graphic&) aGrfObject.GetGraphic() );
			const GfxLink	aGfxLink( aGraphic.GetLink() );
            const ::rtl::OUString  aMimeType( ImplGetGraphicMimeType( rPictureStreamName ) );
            uno::Any        aAny;
            uno::Reference < beans::XPropertySet > xProps( aStream.xStream, uno::UNO_QUERY );

            // set stream properties (MediaType/Compression)
            if( aMimeType.getLength() )
            {
	            aAny <<= aMimeType;
                xProps->setPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), aAny );
            }

            const sal_Bool bCompressed = ( ( 0 == aMimeType.getLength() ) || ( aMimeType == ::rtl::OUString::createFromAscii( "image/tiff" ) ) );
            aAny <<= bCompressed;
            xProps->setPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), aAny );

            SvStream* pStream = utl::UcbStreamHelper::CreateStream( aStream.xStream );
			if( aGfxLink.GetDataSize() && aGfxLink.GetData() )
                pStream->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() );
			else
			{
				if( aGraphic.GetType() == GRAPHIC_BITMAP )
				{
					GraphicFilter*  pFilter = GraphicFilter::GetGraphicFilter();
                    String          aFormat;

					if( aGraphic.IsAnimated() )
						aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "gif" ) );
					else
						aFormat = String( RTL_CONSTASCII_USTRINGPARAM( "png" ) );

                    bRet = ( pFilter->ExportGraphic( aGraphic, String(), *pStream,
													 pFilter->GetExportFormatNumberForShortName( aFormat ) ) == 0 );
				}
				else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE )
				{
					pStream->SetVersion( SOFFICE_FILEFORMAT_8 );
					pStream->SetCompressMode( COMPRESSMODE_ZBITMAP );

					// SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
					GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() );
					const MetaCommentAction* pComment = ImplCheckForEPS( rMtf );
					if ( pComment )
					{
						sal_uInt32	nSize = pComment->GetDataSize();
						const sal_uInt8* pData = pComment->GetData();
						if ( nSize && pData )
							pStream->Write( pData, nSize );

						const MetaEPSAction* pAct = ( (const MetaEPSAction*)rMtf.FirstAction() );
						const GfxLink&		 rLink = pAct->GetLink();

						pStream->Write( rLink.GetData(), rLink.GetDataSize() );
					}
					else
						rMtf.Write( *pStream );

					bRet = ( pStream->GetError() == 0 );
				}
			}
            uno::Reference < embed::XTransactedObject > xStorage(
                                    aStream.xStorage, uno::UNO_QUERY);
            delete pStream;
            aStream.xStream->getOutputStream()->closeOutput();
            if( xStorage.is() )
                xStorage->commit();
		}
	}

	return bRet;
}

// -----------------------------------------------------------------------------

void SvXMLGraphicHelper::ImplInsertGraphicURL( const ::rtl::OUString& rURLStr, sal_uInt32 nInsertPos, rtl::OUString& rRequestedFileName )
{
	rtl::OUString aURLString( rURLStr );
	::rtl::OUString	aPictureStorageName, aPictureStreamName;
	if( ( maURLSet.find( aURLString ) != maURLSet.end() ) )
	{
		URLPairVector::iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() );
		while( aIter != aEnd )
		{
			if( aURLString == (*aIter).first )
			{
				maGrfURLs[ nInsertPos ].second = (*aIter).second;
				aIter = aEnd;
			}
			else
				aIter++;
		}
	}
	else if( ImplGetStreamNames( aURLString, aPictureStorageName, aPictureStreamName ) )
	{
		URLPair& rURLPair = maGrfURLs[ nInsertPos ];

		if( GRAPHICHELPER_MODE_READ == meCreateMode )
		{
			const GraphicObject aObj( ImplReadGraphic( aPictureStorageName, aPictureStreamName ) );

			if( aObj.GetType() != GRAPHIC_NONE )
			{
				const static ::rtl::OUString aBaseURL( RTL_CONSTASCII_USTRINGPARAM( XML_GRAPHICOBJECT_URL_BASE ) );

				maGrfObjs.push_back( aObj );
				rURLPair.second = aBaseURL;
				rURLPair.second += String( aObj.GetUniqueID().GetBuffer(), RTL_TEXTENCODING_ASCII_US );
			}
			else
				rURLPair.second = String();
		}
		else
		{
			const String		aGraphicObjectId( aPictureStreamName );
            const ByteString    aAsciiObjectID( aGraphicObjectId, RTL_TEXTENCODING_ASCII_US );
			const GraphicObject	aGrfObject( aAsciiObjectID );
			if( aGrfObject.GetType() != GRAPHIC_NONE )
			{
				String			aStreamName( aGraphicObjectId );
				Graphic			aGraphic( (Graphic&) aGrfObject.GetGraphic() );
				const GfxLink	aGfxLink( aGraphic.GetLink() );
				String			aExtension;

				if( aGfxLink.GetDataSize() )
				{
					switch( aGfxLink.GetType() )
					{
						case( GFX_LINK_TYPE_EPS_BUFFER ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".eps" ) ); break;
						case( GFX_LINK_TYPE_NATIVE_GIF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".gif" ) ); break;

                        // #15508# added BMP type for better exports (checked, works)
                        case( GFX_LINK_TYPE_NATIVE_BMP ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".bmp" ) ); break;

						case( GFX_LINK_TYPE_NATIVE_JPG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".jpg" ) ); break;
						case( GFX_LINK_TYPE_NATIVE_PNG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) ); break;
						case( GFX_LINK_TYPE_NATIVE_TIF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".tif" ) ); break;
						case( GFX_LINK_TYPE_NATIVE_WMF ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".wmf" ) ); break;
						case( GFX_LINK_TYPE_NATIVE_MET ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".met" ) ); break;
						case( GFX_LINK_TYPE_NATIVE_PCT ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".pct" ) ); break;
						case( GFX_LINK_TYPE_NATIVE_SVG ): aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".svg" ) ); break;

						default:
							aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".grf" ) );
						break;
					}
				}
				else
				{
					if( aGrfObject.GetType() == GRAPHIC_BITMAP )
					{
						if( aGrfObject.IsAnimated() )
							aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".gif" ) );
						else
							aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".png" ) );
					}
					else if( aGrfObject.GetType() == GRAPHIC_GDIMETAFILE )
					{
						// SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
						GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() );
						if ( ImplCheckForEPS( rMtf ) )
							aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".eps" ) );
						else
							aExtension = String( RTL_CONSTASCII_USTRINGPARAM( ".svm" ) );
					}
				}

				rtl::OUString aURLEntry;
				const String sPictures( RTL_CONSTASCII_USTRINGPARAM( "Pictures/" ) );

				if ( rRequestedFileName.getLength() )
				{
					aURLEntry = sPictures;
					aURLEntry += rRequestedFileName;
					aURLEntry += aExtension;

					URLPairVector::iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() );
					while( aIter != aEnd )
					{
						if( aURLEntry == (*aIter).second )
							break;
						aIter++;
					}
					if ( aIter == aEnd )
						aStreamName = rRequestedFileName;
				}

				aStreamName += aExtension;

				if( mbDirect && aStreamName.Len() )
					ImplWriteGraphic( aPictureStorageName, aStreamName, aGraphicObjectId );

				rURLPair.second = sPictures;
				rURLPair.second += aStreamName;
			}
#if OSL_DEBUG_LEVEL > 0
            else
            {
                ByteString sMessage = "graphic object with ID '";
                sMessage += aAsciiObjectID;
                sMessage += "' has an unknown type";
                OSL_ENSURE( false, sMessage.GetBuffer() );
            }
#endif
		}

		maURLSet.insert( aURLString );
	}
}

// -----------------------------------------------------------------------------

void SvXMLGraphicHelper::Init( const uno::Reference < embed::XStorage >& rXMLStorage,
							   SvXMLGraphicHelperMode eCreateMode,
							   sal_Bool bDirect )
{
    mxRootStorage = rXMLStorage;
	meCreateMode = eCreateMode;
	mbDirect = ( ( GRAPHICHELPER_MODE_READ == meCreateMode ) ? bDirect : sal_True );
}

// -----------------------------------------------------------------------------

SvXMLGraphicHelper* SvXMLGraphicHelper::Create( const uno::Reference < embed::XStorage >& rXMLStorage,
												SvXMLGraphicHelperMode eCreateMode,
												sal_Bool bDirect )
{
	SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper;

	pThis->acquire();
    pThis->Init( rXMLStorage, eCreateMode, bDirect );

	return pThis;
}

// -----------------------------------------------------------------------------

SvXMLGraphicHelper*	SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode eCreateMode )
{
	SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper;

	pThis->acquire();
	pThis->Init( NULL, eCreateMode, sal_False );

	return pThis;
}

// -----------------------------------------------------------------------------

void SvXMLGraphicHelper::Destroy( SvXMLGraphicHelper* pSvXMLGraphicHelper )
{
	if( pSvXMLGraphicHelper )
	{
		pSvXMLGraphicHelper->dispose();
		pSvXMLGraphicHelper->release();
	}
}

// -----------------------------------------------------------------------------

// XGraphicObjectResolver
::rtl::OUString SAL_CALL SvXMLGraphicHelper::resolveGraphicObjectURL( const ::rtl::OUString& rURL )
	throw(uno::RuntimeException)
{
	::osl::MutexGuard   aGuard( maMutex );
	const sal_Int32     nIndex = maGrfURLs.size();

	rtl::OUString aURL( rURL );
	rtl::OUString aUserData;
	rtl::OUString aRequestedFileName;

	sal_Int32 nUser = rURL.indexOf( '?', 0 );
	if ( nUser >= 0 )
	{
		aURL = rtl::OUString( rURL.copy( 0, nUser ) );
		nUser++;
		aUserData = rURL.copy( nUser, rURL.getLength() - nUser );
	}
	if ( aUserData.getLength() )
	{
        sal_Int32 nIndex2 = 0;
        do
        {
			rtl::OUString aToken = aUserData.getToken( 0, ';', nIndex2 );
			sal_Int32 n = aToken.indexOf( '=' );
			if ( ( n > 0 ) && ( ( n + 1 ) < aToken.getLength() ) )
			{
				rtl::OUString aParam( aToken.copy( 0, n ) );
				rtl::OUString aValue( aToken.copy( n + 1, aToken.getLength() - ( n + 1 ) ) );

				const rtl::OUString sRequestedName( RTL_CONSTASCII_USTRINGPARAM("requestedName") );
				if ( aParam.match( sRequestedName ) )
					aRequestedFileName = aValue;
			}
        }
        while ( nIndex2 >= 0 );
	}

    maGrfURLs.push_back( ::std::make_pair( aURL, ::rtl::OUString() ) );
	ImplInsertGraphicURL( aURL, nIndex, aRequestedFileName );

    return maGrfURLs[ nIndex ].second;
}

// -----------------------------------------------------------------------------

// XBinaryStreamResolver
Reference< XInputStream > SAL_CALL SvXMLGraphicHelper::getInputStream( const ::rtl::OUString& rURL )
    throw( RuntimeException )
{
    Reference< XInputStream >   xRet;
    ::rtl::OUString                    aPictureStorageName, aGraphicId;


	if( ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) &&
        ImplGetStreamNames( rURL, aPictureStorageName, aGraphicId ) )
    {
        SvXMLGraphicInputStream* pInputStream = new SvXMLGraphicInputStream( aGraphicId );

        if( pInputStream->Exists() )
            xRet = pInputStream;
        else
            delete pInputStream;
    }

    return xRet;
}

// -----------------------------------------------------------------------------

Reference< XOutputStream > SAL_CALL SvXMLGraphicHelper::createOutputStream()
    throw( RuntimeException )
{
    Reference< XOutputStream > xRet;

	if( GRAPHICHELPER_MODE_READ == meCreateMode )
    {
        SvXMLGraphicOutputStream* pOutputStream = new SvXMLGraphicOutputStream;

        if( pOutputStream->Exists() )
            maGrfStms.push_back( xRet = pOutputStream );
        else
            delete pOutputStream;
    }

    return xRet;
}

// -----------------------------------------------------------------------------

::rtl::OUString SAL_CALL SvXMLGraphicHelper::resolveOutputStream( const Reference< XOutputStream >& rxBinaryStream )
    throw( RuntimeException )
{
    ::rtl::OUString aRet;

	if( ( GRAPHICHELPER_MODE_READ == meCreateMode ) && rxBinaryStream.is() )
    {
        if( ::std::find( maGrfStms.begin(), maGrfStms.end(), rxBinaryStream ) != maGrfStms.end() )
        {
            SvXMLGraphicOutputStream* pOStm = static_cast< SvXMLGraphicOutputStream* >( rxBinaryStream.get() );

            if( pOStm )
            {
                const GraphicObject&    rGrfObj = pOStm->GetGraphicObject();
                const ::rtl::OUString          aId( ::rtl::OUString::createFromAscii( rGrfObj.GetUniqueID().GetBuffer() ) );

                if( aId.getLength() )
                {
                    aRet = ::rtl::OUString::createFromAscii( XML_GRAPHICOBJECT_URL_BASE );
                    aRet += aId;
                }
            }
        }
    }

    return aRet;
}


// --------------------------------------------------------------------------------

// for instantiation via service manager
namespace svx
{

namespace impl
{
typedef ::cppu::WeakComponentImplHelper4<
        lang::XInitialization,
        document::XGraphicObjectResolver,
        document::XBinaryStreamResolver,
        lang::XServiceInfo >
    SvXMLGraphicImportExportHelper_Base;
class MutexContainer
{
public:
    virtual ~MutexContainer();

protected:
    mutable ::osl::Mutex m_aMutex;
};
MutexContainer::~MutexContainer()
{}
} // namespace impl

class SvXMLGraphicImportExportHelper :
    public impl::MutexContainer,
    public impl::SvXMLGraphicImportExportHelper_Base
{
public:
    SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode );

protected:
    // is called from WeakComponentImplHelper when XComponent::dispose() was
    // called from outside
    virtual void SAL_CALL disposing();

    // ____ XInitialization ____
    // one argument is allowed, which is the XStorage
    virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
        throw (Exception,
               RuntimeException);

    // ____ XGraphicObjectResolver ____
    virtual ::rtl::OUString SAL_CALL resolveGraphicObjectURL( const ::rtl::OUString& aURL )
        throw (RuntimeException);

    // ____ XBinaryStreamResolver ____
    virtual Reference< io::XInputStream > SAL_CALL getInputStream( const ::rtl::OUString& aURL )
        throw (RuntimeException);
    virtual Reference< io::XOutputStream > SAL_CALL createOutputStream()
        throw (RuntimeException);
    virtual ::rtl::OUString SAL_CALL resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream )
        throw (RuntimeException);

    // ____ XServiceInfo ____
    virtual ::rtl::OUString SAL_CALL getImplementationName()
        throw (RuntimeException);
    virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
        throw (RuntimeException);
    virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
        throw (RuntimeException);

private:
    SvXMLGraphicHelperMode              m_eGraphicHelperMode;
    Reference< XGraphicObjectResolver > m_xGraphicObjectResolver;
    Reference< XBinaryStreamResolver >  m_xBinaryStreamResolver;
};

SvXMLGraphicImportExportHelper::SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ) :
        impl::SvXMLGraphicImportExportHelper_Base( m_aMutex ),
        m_eGraphicHelperMode( eMode )
{}

void SAL_CALL SvXMLGraphicImportExportHelper::disposing()
{
    Reference< XComponent > xComp( m_xGraphicObjectResolver, UNO_QUERY );
    OSL_ASSERT( xComp.is());
    if( xComp.is())
        xComp->dispose();
    // m_xBinaryStreamResolver is a reference to the same object => don't call
    // dispose() again
}

// ____ XInitialization ____
void SAL_CALL SvXMLGraphicImportExportHelper::initialize(
    const Sequence< Any >& aArguments )
    throw (Exception, RuntimeException)
{
    Reference< embed::XStorage > xStorage;
    if( aArguments.getLength() > 0 )
        aArguments[0] >>= xStorage;

    SvXMLGraphicHelper * pHelper( SvXMLGraphicHelper::Create( xStorage, m_eGraphicHelperMode ));
    m_xGraphicObjectResolver.set( pHelper );
    m_xBinaryStreamResolver.set( pHelper );
    // SvXMLGraphicHelper::Create calls acquire.  Since we have two references
    // now it is safe (and necessary) to undo this acquire
    pHelper->release();
}

// ____ XGraphicObjectResolver ____
::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveGraphicObjectURL( const ::rtl::OUString& aURL )
    throw (uno::RuntimeException)
{
    return m_xGraphicObjectResolver->resolveGraphicObjectURL( aURL );
}


// ____ XBinaryStreamResolver ____
Reference< io::XInputStream > SAL_CALL SvXMLGraphicImportExportHelper::getInputStream( const ::rtl::OUString& aURL )
    throw (uno::RuntimeException)
{
    return m_xBinaryStreamResolver->getInputStream( aURL );
}
Reference< io::XOutputStream > SAL_CALL SvXMLGraphicImportExportHelper::createOutputStream()
    throw (uno::RuntimeException)
{
    return m_xBinaryStreamResolver->createOutputStream();
}
::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream )
    throw (uno::RuntimeException)
{
    return m_xBinaryStreamResolver->resolveOutputStream( aBinaryStream );
}

// ____ XServiceInfo ____
::rtl::OUString SAL_CALL SvXMLGraphicImportExportHelper::getImplementationName()
    throw (uno::RuntimeException)
{
    if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ )
        return SvXMLGraphicImportHelper_getImplementationName();
    return SvXMLGraphicExportHelper_getImplementationName();
}
::sal_Bool SAL_CALL SvXMLGraphicImportExportHelper::supportsService( const ::rtl::OUString& ServiceName )
    throw (uno::RuntimeException)
{
    Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames());
    const ::rtl::OUString * pBegin = aServiceNames.getConstArray();
    const ::rtl::OUString * pEnd = pBegin + aServiceNames.getLength();
    return (::std::find( pBegin, pEnd, ServiceName ) != pEnd);
}
Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicImportExportHelper::getSupportedServiceNames()
    throw (uno::RuntimeException)
{
    if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ )
        return SvXMLGraphicImportHelper_getSupportedServiceNames();
    return SvXMLGraphicExportHelper_getSupportedServiceNames();
}

// import
Reference< XInterface > SAL_CALL SvXMLGraphicImportHelper_createInstance(const Reference< XMultiServiceFactory > & /* rSMgr */ )
    throw( Exception )
{
    return static_cast< XWeak* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_READ ));
}
::rtl::OUString SAL_CALL SvXMLGraphicImportHelper_getImplementationName()
    throw()
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicImportHelper" ));
}
Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicImportHelper_getSupportedServiceNames()
    throw()
{
    // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service
    Sequence< ::rtl::OUString > aSupportedServiceNames( 2 );
    aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) );
    aSupportedServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) );
    return aSupportedServiceNames;
}

// export
Reference< XInterface > SAL_CALL SvXMLGraphicExportHelper_createInstance(const Reference< XMultiServiceFactory > & /* rSMgr */ )
    throw( Exception )
{
    return static_cast< XWeak* >( new SvXMLGraphicImportExportHelper( GRAPHICHELPER_MODE_WRITE ));
}
::rtl::OUString SAL_CALL SvXMLGraphicExportHelper_getImplementationName()
    throw()
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.GraphicExportHelper" ));
}
Sequence< ::rtl::OUString > SAL_CALL SvXMLGraphicExportHelper_getSupportedServiceNames()
    throw()
{
    // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service
    Sequence< ::rtl::OUString > aSupportedServiceNames( 2 );
    aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.GraphicObjectResolver" ) );
    aSupportedServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStreamResolver" ) );
    return aSupportedServiceNames;
}

} // namespace svx
