summaryrefslogtreecommitdiff
path: root/svtools/source/filter/filter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/filter/filter.cxx')
-rw-r--r--svtools/source/filter/filter.cxx2260
1 files changed, 2260 insertions, 0 deletions
diff --git a/svtools/source/filter/filter.cxx b/svtools/source/filter/filter.cxx
new file mode 100644
index 000000000000..78d97cc25c5c
--- /dev/null
+++ b/svtools/source/filter/filter.cxx
@@ -0,0 +1,2260 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#if defined UNX && defined ALPHA
+#include <fstream.hxx>
+#endif
+#include <vos/mutex.hxx>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/salctype.hxx>
+#include <vcl/pngread.hxx>
+#include <vcl/pngwrite.hxx>
+#include <vcl/svgread.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/file.hxx>
+#include <svtools/filter.hxx>
+#include "FilterConfigCache.hxx"
+#include <svtools/FilterConfigItem.hxx>
+#include <svtools/fltcall.hxx>
+#include <svtools/wmf.hxx>
+#include "gifread.hxx"
+#include "jpeg.hxx"
+#include "xbmread.hxx"
+#include "xpmread.hxx"
+#include <svl/solar.hrc>
+#include <svtools/svtools.hrc>
+#include "sgffilt.hxx"
+#include "osl/module.hxx"
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/XWeak.hpp>
+#include <com/sun/star/uno/XAggregation.hpp>
+#ifndef _COM_SUN_STAR_UNO_XTYPEPROVIDER_HPP_
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#endif
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/svg/XSVGWriter.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/instance.hxx>
+
+#include "SvFilterOptionsDialog.hxx"
+
+#define PMGCHUNG_msOG 0x6d734f47 // Microsoft Office Animated GIF
+
+#if (defined OS2 && !defined ICC)
+
+#define IMPORT_FUNCTION_NAME "_GraphicImport"
+#define EXPORT_FUNCTION_NAME "_GraphicExport"
+#define IMPDLG_FUNCTION_NAME "_DoImportDialog"
+#define EXPDLG_FUNCTION_NAME "_DoExportDialog"
+
+#else
+
+#define IMPORT_FUNCTION_NAME "GraphicImport"
+#define EXPORT_FUNCTION_NAME "GraphicExport"
+#define IMPDLG_FUNCTION_NAME "DoImportDialog"
+#define EXPDLG_FUNCTION_NAME "DoExportDialog"
+
+#endif
+
+
+// -----------
+// - statics -
+// -----------
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+static List* pFilterHdlList = NULL;
+
+static ::osl::Mutex& getListMutex()
+{
+ static ::osl::Mutex s_aListProtection;
+ return s_aListProtection;
+}
+
+static GraphicFilter* pGraphicFilter=0;
+
+// -------------------------
+// - ImpFilterOutputStream -
+// -------------------------
+
+class ImpFilterOutputStream : public ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream >
+{
+protected:
+
+ SvStream& mrStm;
+
+ virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& rData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { mrStm.Write( rData.getConstArray(), rData.getLength() ); }
+ virtual void SAL_CALL flush() throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { mrStm.Flush(); }
+ virtual void SAL_CALL closeOutput() throw() {}
+
+public:
+
+ ImpFilterOutputStream( SvStream& rStm ) : mrStm( rStm ) {}
+ ~ImpFilterOutputStream() {}
+};
+
+sal_Bool ImplDirEntryHelper::Exists( const INetURLObject& rObj )
+{
+ sal_Bool bExists = sal_False;
+
+ try
+ {
+ ::rtl::OUString aTitle;
+ ::ucbhelper::Content aCnt( rObj.GetMainURL( INetURLObject::NO_DECODE ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ bExists = aCnt.isDocument();
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ::com::sun::star::ucb::ContentCreationException& )
+ {
+ DBG_ERRORFILE( "ContentCreationException" );
+ }
+ catch( ... )
+ {
+// DBG_ERRORFILE( "Any other exception" );
+ }
+ return bExists;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImplDirEntryHelper::Kill( const String& rMainUrl )
+{
+ try
+ {
+ ::ucbhelper::Content aCnt( rMainUrl,
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+
+ aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
+ ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
+ }
+ catch( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ DBG_ERRORFILE( "CommandAbortedException" );
+ }
+ catch( ... )
+ {
+ DBG_ERRORFILE( "Any other exception" );
+ }
+}
+
+// --------------------
+// - Helper functions -
+// --------------------
+
+//--------------------------------------------------------------------------
+
+sal_uInt8* ImplSearchEntry( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nComp, sal_uLong nSize )
+{
+ while ( nComp-- >= nSize )
+ {
+ sal_uLong i;
+ for ( i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ break;
+ }
+ if ( i == nSize )
+ return pSource;
+ pSource++;
+ }
+ return NULL;
+}
+
+//--------------------------------------------------------------------------
+
+inline String ImpGetExtension( const String &rPath )
+{
+ String aExt;
+ INetURLObject aURL( rPath );
+ aExt = aURL.GetFileExtension().toAsciiUpperCase();
+ return aExt;
+}
+
+/*************************************************************************
+|*
+|* ImpPeekGraphicFormat()
+|*
+|* Beschreibung:
+|* Diese Funktion kann zweierlei:
+|* 1.) Datei anlesen, Dateiformat ermitteln
+|* Eingabe-prarameter:
+|* rPath - Dateipfad
+|* rFormatExtension - Inhalt egal
+|* bTest - setze sal_False
+|* Ausgabe-parameter:
+|* Funkionswert - sal_True wenn Erfolg
+|* rFormatExtension - Bei Erfolg: uebliche Dateiendung
+|* des Formats (Grossbuchstaben)
+|* 2.) Datei anlesen, Dateiformat ueberpruefen
+|* Eingabe-prarameter:
+|* rPath - Dateipfad
+|* rFormatExtension - uebliche Dateiendung des Formats
+|* (Grossbuchstaben)
+|* bTest - setze sal_True
+|* Ausgabe-parameter:
+|* Funkionswert - sal_False, wenn die Datei bestimmt nicht
+|* vom uebgebenen Format ist.
+|* sal_True, wenn die Datei WAHRSCHEINLICH von
+|* dem Format ist, ODER WENN DAS FORMAT
+|* DIESER FUNKTION NICHT BEKANNT IST!
+|*
+|* Ersterstellung OH 26.05.95
+|* Letzte Aenderung OH 07.08.95
+|*
+*************************************************************************/
+
+static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtension, sal_Bool bTest )
+{
+ sal_uInt16 i;
+ sal_uInt8 sFirstBytes[ 256 ];
+ sal_uLong nFirstLong,nSecondLong;
+ sal_uLong nStreamPos = rStream.Tell();
+
+ rStream.Seek( STREAM_SEEK_TO_END );
+ sal_uLong nStreamLen = rStream.Tell() - nStreamPos;
+ rStream.Seek( nStreamPos );
+
+ if ( !nStreamLen )
+ {
+ SvLockBytes* pLockBytes = rStream.GetLockBytes();
+ if ( pLockBytes )
+ pLockBytes->SetSynchronMode( sal_True );
+
+ rStream.Seek( STREAM_SEEK_TO_END );
+ nStreamLen = rStream.Tell() - nStreamPos;
+ rStream.Seek( nStreamPos );
+ }
+ // Die ersten 256 Bytes in einen Buffer laden:
+ if( nStreamLen >= 256 )
+ rStream.Read( sFirstBytes, 256 );
+ else
+ {
+ rStream.Read( sFirstBytes, nStreamLen );
+
+ for( i = (sal_uInt16) nStreamLen; i < 256; i++ )
+ sFirstBytes[ i ]=0;
+ }
+
+ if( rStream.GetError() )
+ return sal_False;
+
+ // Die ersten 8 Bytes in nFirstLong, nSecondLong unterbringen,
+ // Big-Endian:
+ for( i = 0, nFirstLong = 0L, nSecondLong = 0L; i < 4; i++ )
+ {
+ nFirstLong=(nFirstLong<<8)|(sal_uLong)sFirstBytes[i];
+ nSecondLong=(nSecondLong<<8)|(sal_uLong)sFirstBytes[i+4];
+ }
+
+ // Folgende Variable ist nur bei bTest==sal_True interessant. Sie
+ // bleibt sal_False, wenn das Format (rFormatExtension) hier noch nicht
+ // einprogrammiert wurde.
+ sal_Bool bSomethingTested = sal_False;
+
+ // Nun werden die verschieden Formate ueberprueft. Dabei ist die
+ // Reihenfolge nicht egal. Z.b. koennte eine MET-Datei auch durch
+ // den BMP-Test gehen, umgekehrt kann eine BMP-Datei kaum durch den
+ // MET-Test gehen. Also sollte MET vor BMP getestet werden.
+ // Theoretisch waere aber vielleicht auch eine BMP-Datei denkbar,
+ // die durch den MET-Test geht.
+ // Diese Probleme gibt es natuerlich nicht nur bei MET und BMP.
+ // Deshalb wird im Falle der Uberpruefung eines Formats (bTest==sal_True)
+ // nur genau dieses eine Format getestet. Alles andere koennte fatale
+ // Folgen haben, z.B. wenn der Benutzer sagt, es sei BMP-Datei (und es
+ // ist BMP-Datei), und hier wuerde die Datei durch den MET-Test gehen...
+
+ //--------------------------- MET ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "MET", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if( sFirstBytes[2] == 0xd3 )
+ {
+ rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ rStream.Seek( nStreamPos );
+ sal_uInt16 nFieldSize;
+ sal_uInt8 nMagic;
+ sal_Bool bOK=sal_True;
+ rStream >> nFieldSize >> nMagic;
+ for (i=0; i<3; i++) {
+ if (nFieldSize<6) { bOK=sal_False; break; }
+ if (nStreamLen < rStream.Tell() + nFieldSize ) { bOK=sal_False; break; }
+ rStream.SeekRel(nFieldSize-3);
+ rStream >> nFieldSize >> nMagic;
+ if (nMagic!=0xd3) { bOK=sal_False; break; }
+ }
+ rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ if (bOK && !rStream.GetError()) {
+ rFormatExtension= UniString::CreateFromAscii( "MET", 3 );
+ return sal_True;
+ }
+ }
+ }
+
+ //--------------------------- BMP ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "BMP", 3 ) == COMPARE_EQUAL ) )
+ {
+ sal_uInt8 nOffs;
+
+ bSomethingTested=sal_True;
+
+ // OS/2-Bitmaparray ('BA') koennen wir evtl. auch lesen,
+ // dementspr. muessen wir den Offset anpassen,
+ // um auf die erste Bitmap im Array zu stossen
+ if ( sFirstBytes[0] == 0x42 && sFirstBytes[1] == 0x41 )
+ nOffs = 14;
+ else
+ nOffs = 0;
+
+ // Jetzt testen wir zunaechst auf 'BM'
+ if ( sFirstBytes[0+nOffs]==0x42 && sFirstBytes[1+nOffs]==0x4d )
+ {
+ // unter OS/2 koennen die Reserved-Flags != 0 sein
+ // (was sie eigentlich nicht duerften);
+ // in diesem Fall testen wir die Groesse des BmpInfoHeaders
+ if ( ( sFirstBytes[6+nOffs]==0x00 &&
+ sFirstBytes[7+nOffs]==0x00 &&
+ sFirstBytes[8+nOffs]==0x00 &&
+ sFirstBytes[9+nOffs]==0x00 ) ||
+ sFirstBytes[14+nOffs] == 0x28 ||
+ sFirstBytes[14+nOffs] == 0x0c )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "BMP", 3 );
+ return sal_True;
+ }
+ }
+ }
+
+ //--------------------------- WMF/EMF ------------------------------------
+
+ if( !bTest ||
+ ( rFormatExtension.CompareToAscii( "WMF", 3 ) == COMPARE_EQUAL ) ||
+ ( rFormatExtension.CompareToAscii( "EMF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = sal_True;
+
+ if ( nFirstLong==0xd7cdc69a || nFirstLong==0x01000900 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "WMF", 3 );
+ return sal_True;
+ }
+ else if( nFirstLong == 0x01000000 && sFirstBytes[ 40 ] == 0x20 && sFirstBytes[ 41 ] == 0x45 &&
+ sFirstBytes[ 42 ] == 0x4d && sFirstBytes[ 43 ] == 0x46 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "EMF", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- PCX ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PCX", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if (sFirstBytes[0]==0x0a)
+ {
+ sal_uInt8 nVersion=sFirstBytes[1];
+ sal_uInt8 nEncoding=sFirstBytes[2];
+ if( ( nVersion==0 || nVersion==2 || nVersion==3 || nVersion==5 ) && nEncoding<=1 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PCX", 3 );
+ return sal_True;
+ }
+ }
+ }
+
+ //--------------------------- TIF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "TIF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if ( nFirstLong==0x49492a00 || nFirstLong==0x4d4d002a )
+ {
+ rFormatExtension=UniString::CreateFromAscii( "TIF", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- GIF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "GIF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if ( nFirstLong==0x47494638 && (sFirstBytes[4]==0x37 || sFirstBytes[4]==0x39) && sFirstBytes[5]==0x61 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "GIF", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- PNG ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PNG", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if (nFirstLong==0x89504e47 && nSecondLong==0x0d0a1a0a)
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PNG", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- JPG ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "JPG", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if ( ( nFirstLong==0xffd8ffe0 && sFirstBytes[6]==0x4a && sFirstBytes[7]==0x46 && sFirstBytes[8]==0x49 && sFirstBytes[9]==0x46 ) ||
+ ( nFirstLong==0xffd8fffe ) || ( 0xffd8ff00 == ( nFirstLong & 0xffffff00 ) ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "JPG", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- SVM ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "SVM", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if( nFirstLong==0x53564744 && sFirstBytes[4]==0x49 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
+ return sal_True;
+ }
+ else if( sFirstBytes[0]==0x56 && sFirstBytes[1]==0x43 && sFirstBytes[2]==0x4C &&
+ sFirstBytes[3]==0x4D && sFirstBytes[4]==0x54 && sFirstBytes[5]==0x46 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- PCD ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PCD", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = sal_True;
+ if( nStreamLen >= 2055 )
+ {
+ char sBuf[8];
+ rStream.Seek( nStreamPos + 2048 );
+ rStream.Read( sBuf, 7 );
+
+ if( strncmp( sBuf, "PCD_IPI", 7 ) == 0 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PCD", 3 );
+ return sal_True;
+ }
+ }
+ }
+
+ //--------------------------- PSD ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PSD", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = sal_True;
+ if ( ( nFirstLong == 0x38425053 ) && ( (nSecondLong >> 16 ) == 1 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PSD", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- EPS ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "EPS", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = sal_True;
+ if ( ( nFirstLong == 0xC5D0D3C6 ) || ( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 ) &&
+ ImplSearchEntry( &sFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "EPS", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- DXF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "DXF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+
+ i=0;
+ while (i<256 && sFirstBytes[i]<=32)
+ i++;
+
+ if (i<256)
+ {
+ if( sFirstBytes[i]=='0' )
+ i++;
+ else
+ i=256;
+ }
+ while( i<256 && sFirstBytes[i]<=32 )
+ i++;
+
+ if (i+7<256)
+ {
+ if (strncmp((char*)(sFirstBytes+i),"SECTION",7)==0)
+ {
+ rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
+ return sal_True;
+ }
+ }
+
+ if( strncmp( (char*) sFirstBytes, "AutoCAD Binary DXF", 18 ) == 0 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- PCT ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "PCT", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = sal_True;
+ sal_uInt8 sBuf[3];
+ // store number format
+ sal_uInt16 oldNumberFormat = rStream.GetNumberFormatInt();
+ sal_uInt32 nOffset; // in ms documents the pict format is used without the first 512 bytes
+ for ( nOffset = 0; ( nOffset <= 512 ) && ( ( nStreamPos + nOffset + 14 ) <= nStreamLen ); nOffset += 512 )
+ {
+ short y1,x1,y2,x2;
+ sal_Bool bdBoxOk = sal_True;
+
+ rStream.Seek( nStreamPos + nOffset);
+ // size of the pict in version 1 pict ( 2bytes) : ignored
+ rStream.SeekRel(2);
+ // bounding box (bytes 2 -> 9)
+ rStream.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
+ rStream >> y1 >> x1 >> y2 >> x2;
+ rStream.SetNumberFormatInt(oldNumberFormat); // reset format
+
+ if (x1 > x2 || y1 > y2 || // bad bdbox
+ (x1 == x2 && y1 == y2) || // 1 pixel picture
+ x2-x1 > 2048 || y2-y1 > 2048 ) // picture anormaly big
+ bdBoxOk = sal_False;
+
+ // read version op
+ rStream.Read( sBuf,3 );
+ // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
+ // normal version 2 - page A23 and A24
+ if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x02)
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
+ return sal_True;
+ }
+ // normal version 1 - page A25
+ else if (sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 && bdBoxOk) {
+ rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
+ return sal_True;
+ }
+ // previous code kept in order to do not break any compatibility
+ // probably eroneous
+ else if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x01 && bdBoxOk)
+ {
+ rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
+ return sal_True;
+ }
+ }
+ }
+
+ //------------------------- PBM + PGM + PPM ---------------------------
+ if( !bTest ||
+ ( rFormatExtension.CompareToAscii( "PBM", 3 ) == COMPARE_EQUAL ) ||
+ ( rFormatExtension.CompareToAscii( "PGM", 3 ) == COMPARE_EQUAL ) ||
+ ( rFormatExtension.CompareToAscii( "PPM", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if ( sFirstBytes[ 0 ] == 'P' )
+ {
+ switch( sFirstBytes[ 1 ] )
+ {
+ case '1' :
+ case '4' :
+ rFormatExtension = UniString::CreateFromAscii( "PBM", 3 );
+ return sal_True;
+
+ case '2' :
+ case '5' :
+ rFormatExtension = UniString::CreateFromAscii( "PGM", 3 );
+ return sal_True;
+
+ case '3' :
+ case '6' :
+ rFormatExtension = UniString::CreateFromAscii( "PPM", 3 );
+ return sal_True;
+ }
+ }
+ }
+
+ //--------------------------- RAS( SUN RasterFile )------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "RAS", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if( nFirstLong == 0x59a66a95 )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "RAS", 3 );
+ return sal_True;
+ }
+ }
+
+ //--------------------------- XPM ------------------------------------
+ if( !bTest )
+ {
+ bSomethingTested = sal_True;
+ if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"/* XPM */", 256, 9 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "XPM", 3 );
+ return sal_True;
+ }
+ }
+ else if( rFormatExtension.CompareToAscii( "XPM", 3 ) == COMPARE_EQUAL )
+ {
+ bSomethingTested = sal_True;
+ return sal_True;
+ }
+
+ //--------------------------- XBM ------------------------------------
+ if( !bTest )
+ {
+ sal_uLong nSize = ( nStreamLen > 2048 ) ? 2048 : nStreamLen;
+ sal_uInt8* pBuf = new sal_uInt8 [ nSize ];
+
+ rStream.Seek( nStreamPos );
+ rStream.Read( pBuf, nSize );
+ sal_uInt8* pPtr = ImplSearchEntry( pBuf, (sal_uInt8*)"#define", nSize, 7 );
+
+ if( pPtr )
+ {
+ if( ImplSearchEntry( pPtr, (sal_uInt8*)"_width", pBuf + nSize - pPtr, 6 ) )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "XBM", 3 );
+ delete[] pBuf;
+ return sal_True;
+ }
+ }
+ delete[] pBuf;
+ }
+ else if( rFormatExtension.CompareToAscii( "XBM", 3 ) == COMPARE_EQUAL )
+ {
+ bSomethingTested = sal_True;
+ return sal_True;
+ }
+
+ //--------------------------- SVG ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+
+ // just a simple test for the extension
+ if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL )
+ return sal_True;
+ }
+
+ //--------------------------- TGA ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = sal_True;
+
+ // just a simple test for the extension
+ if( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL )
+ return sal_True;
+ }
+
+ //--------------------------- SGV ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested = sal_True;
+
+ // just a simple test for the extension
+ if( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL )
+ return sal_True;
+ }
+
+ //--------------------------- SGF ------------------------------------
+ if( !bTest || ( rFormatExtension.CompareToAscii( "SGF", 3 ) == COMPARE_EQUAL ) )
+ {
+ bSomethingTested=sal_True;
+ if( sFirstBytes[ 0 ] == 'J' && sFirstBytes[ 1 ] == 'J' )
+ {
+ rFormatExtension = UniString::CreateFromAscii( "SGF", 3 );
+ return sal_True;
+ }
+ }
+
+ return bTest && !bSomethingTested;
+}
+
+//--------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::ImpTestOrFindFormat( const String& rPath, SvStream& rStream, sal_uInt16& rFormat )
+{
+ sal_uInt16 n = pConfig->GetImportFormatCount();
+
+ // ggf. Filter bzw. Format durch anlesen ermitteln,
+ // oder durch anlesen zusichern, dass das Format stimmt:
+ if( rFormat == GRFILTER_FORMAT_DONTKNOW )
+ {
+ String aFormatExt;
+ if( ImpPeekGraphicFormat( rStream, aFormatExt, sal_False ) )
+ {
+ for( sal_uInt16 i = 0; i < n; i++ )
+ {
+ if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aFormatExt ) )
+ {
+ rFormat = i;
+ return GRFILTER_OK;
+ }
+ }
+ }
+ // ggf. Filter anhand der Datei-Endung raussuchen:
+ if( rPath.Len() )
+ {
+ String aExt( ImpGetExtension( rPath ) );
+ for( sal_uInt16 i = 0; i < n; i++ )
+ {
+ if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
+ {
+ rFormat = i;
+ return GRFILTER_OK;
+ }
+ }
+ }
+ return GRFILTER_FORMATERROR;
+ }
+ else
+ {
+ String aTmpStr( pConfig->GetImportFormatExtension( rFormat ) );
+ if( !ImpPeekGraphicFormat( rStream, aTmpStr, sal_True ) )
+ return GRFILTER_FORMATERROR;
+ if ( pConfig->GetImportFormatExtension( rFormat ).EqualsIgnoreCaseAscii( "pcd" ) )
+ {
+ sal_Int32 nBase = 2; // default Base0
+ if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base4" ) )
+ nBase = 1;
+ else if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base16" ) )
+ nBase = 0;
+ String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
+ FilterConfigItem aFilterConfigItem( aFilterConfigPath );
+ aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
+ }
+ }
+
+ return GRFILTER_OK;
+}
+
+//--------------------------------------------------------------------------
+
+static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem )
+{
+ Graphic aGraphic;
+ ByteString aResMgrName( "svt", 3 );
+ ResMgr* pResMgr;
+
+ pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
+
+ sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) ), 0 );
+ sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) ), 0 );
+
+ if ( rGraphic.GetType() != GRAPHIC_NONE )
+ {
+ sal_Int32 nMode = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "ExportMode" ) ), -1 );
+
+ if ( nMode == -1 ) // the property is not there, this is possible, if the graphic filter
+ { // is called via UnoGraphicExporter and not from a graphic export Dialog
+ nMode = 0; // then we are defaulting this mode to 0
+ if ( nLogicalWidth || nLogicalHeight )
+ nMode = 2;
+ }
+
+
+ Size aOriginalSize;
+ Size aPrefSize( rGraphic.GetPrefSize() );
+ MapMode aPrefMapMode( rGraphic.GetPrefMapMode() );
+ if ( aPrefMapMode == MAP_PIXEL )
+ aOriginalSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
+ else
+ aOriginalSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
+ if ( !nLogicalWidth )
+ nLogicalWidth = aOriginalSize.Width();
+ if ( !nLogicalHeight )
+ nLogicalHeight = aOriginalSize.Height();
+ if( rGraphic.GetType() == GRAPHIC_BITMAP )
+ {
+
+ // Aufloesung wird eingestellt
+ if( nMode == 1 )
+ {
+ Bitmap aBitmap( rGraphic.GetBitmap() );
+ MapMode aMap( MAP_100TH_INCH );
+
+ sal_Int32 nDPI = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), 75 );
+ Fraction aFrac( 1, Min( Max( nDPI, sal_Int32( 75 ) ), sal_Int32( 600 ) ) );
+
+ aMap.SetScaleX( aFrac );
+ aMap.SetScaleY( aFrac );
+
+ Size aOldSize = aBitmap.GetSizePixel();
+ aBitmap.SetPrefMapMode( aMap );
+ aBitmap.SetPrefSize( Size( aOldSize.Width() * 100,
+ aOldSize.Height() * 100 ) );
+
+ aGraphic = Graphic( aBitmap );
+ }
+ // Groesse wird eingestellt
+ else if( nMode == 2 )
+ {
+ BitmapEx aBitmapEx( rGraphic.GetBitmapEx() );
+ aBitmapEx.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
+ aBitmapEx.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) );
+ aGraphic = Graphic( aBitmapEx );
+ }
+ else
+ aGraphic = rGraphic;
+
+ sal_Int32 nColors = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Color" ) ), 0 ); // #92767#
+ if ( nColors ) // graphic conversion necessary ?
+ {
+ BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
+ aBmpEx.Convert( (BmpConversion)nColors ); // the entries in the xml section have the same meaning as
+ aGraphic = aBmpEx; // they have in the BmpConversion enum, so it should be
+ } // allowed to cast them
+ }
+ else
+ {
+ if( ( nMode == 1 ) || ( nMode == 2 ) )
+ {
+ GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
+ ::com::sun::star::awt::Size aDefaultSize( 10000, 10000 );
+ Size aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth, nLogicalHeight ), MAP_100TH_MM, aMtf.GetPrefMapMode() ) );
+
+ if( aNewSize.Width() && aNewSize.Height() )
+ {
+ const Size aPreferredSize( aMtf.GetPrefSize() );
+ aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ),
+ Fraction( aNewSize.Height(), aPreferredSize.Height() ) );
+ }
+ aGraphic = Graphic( aMtf );
+ }
+ else
+ aGraphic = rGraphic;
+ }
+
+ }
+ else
+ aGraphic = rGraphic;
+
+ delete pResMgr;
+
+ return aGraphic;
+}
+
+static String ImpCreateFullFilterPath( const String& rPath, const String& rFilterName )
+{
+ ::rtl::OUString aPathURL;
+
+ ::osl::FileBase::getFileURLFromSystemPath( rPath, aPathURL );
+ aPathURL += String( '/' );
+
+ ::rtl::OUString aSystemPath;
+ ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
+ aSystemPath += ::rtl::OUString( rFilterName );
+
+ return String( aSystemPath );
+}
+
+
+// --------------------------
+// - ImpFilterLibCacheEntry -
+// --------------------------
+
+class ImpFilterLibCache;
+
+struct ImpFilterLibCacheEntry
+{
+ ImpFilterLibCacheEntry* mpNext;
+ osl::Module maLibrary;
+ String maFiltername;
+ PFilterCall mpfnImport;
+ PFilterDlgCall mpfnImportDlg;
+
+ ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername );
+ int operator==( const String& rFiltername ) const { return maFiltername == rFiltername; }
+
+ PFilterCall GetImportFunction();
+ PFilterDlgCall GetImportDlgFunction();
+ PFilterCall GetExportFunction() { return (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) ); }
+ PFilterDlgCall GetExportDlgFunction() { return (PFilterDlgCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) ); }
+};
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername ) :
+ mpNext ( NULL ),
+ maLibrary ( rPathname ),
+ maFiltername ( rFiltername ),
+ mpfnImport ( NULL ),
+ mpfnImportDlg ( NULL )
+{
+}
+
+// ------------------------------------------------------------------------
+
+PFilterCall ImpFilterLibCacheEntry::GetImportFunction()
+{
+ if( !mpfnImport )
+ mpfnImport = (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPORT_FUNCTION_NAME ) );
+
+ return mpfnImport;
+}
+
+// ------------------------------------------------------------------------
+
+PFilterDlgCall ImpFilterLibCacheEntry::GetImportDlgFunction()
+{
+ if( !mpfnImportDlg )
+ mpfnImportDlg = (PFilterDlgCall)maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPDLG_FUNCTION_NAME ) );
+
+ return mpfnImportDlg;
+}
+
+// ---------------------
+// - ImpFilterLibCache -
+// ---------------------
+
+class ImpFilterLibCache
+{
+ ImpFilterLibCacheEntry* mpFirst;
+ ImpFilterLibCacheEntry* mpLast;
+
+public:
+ ImpFilterLibCache();
+ ~ImpFilterLibCache();
+
+ ImpFilterLibCacheEntry* GetFilter( const String& rFilterPath, const String& rFiltername );
+};
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCache::ImpFilterLibCache() :
+ mpFirst ( NULL ),
+ mpLast ( NULL )
+{
+}
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCache::~ImpFilterLibCache()
+{
+ ImpFilterLibCacheEntry* pEntry = mpFirst;
+ while( pEntry )
+ {
+ ImpFilterLibCacheEntry* pNext = pEntry->mpNext;
+ delete pEntry;
+ pEntry = pNext;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+ImpFilterLibCacheEntry* ImpFilterLibCache::GetFilter( const String& rFilterPath, const String& rFilterName )
+{
+ ImpFilterLibCacheEntry* pEntry = mpFirst;
+
+ while( pEntry )
+ {
+ if( *pEntry == rFilterName )
+ break;
+ else
+ pEntry = pEntry->mpNext;
+ }
+ if( !pEntry )
+ {
+ String aPhysicalName( ImpCreateFullFilterPath( rFilterPath, rFilterName ) );
+ pEntry = new ImpFilterLibCacheEntry( aPhysicalName, rFilterName );
+
+ if ( pEntry->maLibrary.is() )
+ {
+ if( !mpFirst )
+ mpFirst = mpLast = pEntry;
+ else
+ mpLast = mpLast->mpNext = pEntry;
+ }
+ else
+ {
+ delete pEntry;
+ pEntry = NULL;
+ }
+ }
+ return pEntry;
+};
+
+// ------------------------------------------------------------------------
+
+namespace { struct Cache : public rtl::Static<ImpFilterLibCache, Cache> {}; }
+
+// -----------------
+// - GraphicFilter -
+// -----------------
+
+GraphicFilter::GraphicFilter( sal_Bool bConfig ) :
+ bUseConfig ( bConfig ),
+ nExpGraphHint ( 0 )
+{
+ ImplInit();
+}
+
+// ------------------------------------------------------------------------
+
+GraphicFilter::~GraphicFilter()
+{
+ {
+ ::osl::MutexGuard aGuard( getListMutex() );
+ pFilterHdlList->Remove( (void*)this );
+ if ( !pFilterHdlList->Count() )
+ {
+ delete pFilterHdlList, pFilterHdlList = NULL;
+ delete pConfig;
+ }
+ }
+
+
+ delete pErrorEx;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicFilter::ImplInit()
+{
+ {
+ ::osl::MutexGuard aGuard( getListMutex() );
+
+ if ( !pFilterHdlList )
+ {
+ pFilterHdlList = new List;
+ pConfig = new FilterConfigCache( bUseConfig );
+ }
+ else
+ pConfig = ((GraphicFilter*)pFilterHdlList->First())->pConfig;
+
+ pFilterHdlList->Insert( (void*)this );
+ }
+
+ if( bUseConfig )
+ {
+#if defined WNT
+ rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program"));
+#else
+ rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program"));
+#endif
+ rtl::Bootstrap::expandMacros(url); //TODO: detect failure
+ utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath);
+ }
+
+ pErrorEx = new FilterErrorEx;
+ bAbort = sal_False;
+}
+
+// ------------------------------------------------------------------------
+
+sal_uLong GraphicFilter::ImplSetError( sal_uLong nError, const SvStream* pStm )
+{
+ pErrorEx->nFilterError = nError;
+ pErrorEx->nStreamError = pStm ? pStm->GetError() : ERRCODE_NONE;
+ return nError;
+}
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetImportFormatCount()
+{
+ return pConfig->GetImportFormatCount();
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetImportFormatNumber( const String& rFormatName )
+{
+ return pConfig->GetImportFormatNumber( rFormatName );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetImportFormatNumberForMediaType( const String& rMediaType )
+{
+ return pConfig->GetImportFormatNumberForMediaType( rMediaType );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetImportFormatNumberForShortName( const String& rShortName )
+{
+ return pConfig->GetImportFormatNumberForShortName( rShortName );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( const String& rType )
+{
+ return pConfig->GetImportFormatNumberForTypeName( rType );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatName( sal_uInt16 nFormat )
+{
+ return pConfig->GetImportFormatName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatTypeName( sal_uInt16 nFormat )
+{
+ return pConfig->GetImportFilterTypeName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatMediaType( sal_uInt16 nFormat )
+{
+ return pConfig->GetImportFormatMediaType( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportFormatShortName( sal_uInt16 nFormat )
+{
+ return pConfig->GetImportFormatShortName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportOSFileType( sal_uInt16 )
+{
+ String aOSFileType;
+ return aOSFileType;
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ return pConfig->GetImportWildcard( nFormat, nEntry );
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool GraphicFilter::IsImportPixelFormat( sal_uInt16 nFormat )
+{
+ return pConfig->IsImportPixelFormat( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetExportFormatCount()
+{
+ return pConfig->GetExportFormatCount();
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetExportFormatNumber( const String& rFormatName )
+{
+ return pConfig->GetExportFormatNumber( rFormatName );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetExportFormatNumberForMediaType( const String& rMediaType )
+{
+ return pConfig->GetExportFormatNumberForMediaType( rMediaType );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetExportFormatNumberForShortName( const String& rShortName )
+{
+ return pConfig->GetExportFormatNumberForShortName( rShortName );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( const String& rType )
+{
+ return pConfig->GetExportFormatNumberForTypeName( rType );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatName( sal_uInt16 nFormat )
+{
+ return pConfig->GetExportFormatName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatTypeName( sal_uInt16 nFormat )
+{
+ return pConfig->GetExportFilterTypeName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatMediaType( sal_uInt16 nFormat )
+{
+ return pConfig->GetExportFormatMediaType( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportFormatShortName( sal_uInt16 nFormat )
+{
+ return pConfig->GetExportFormatShortName( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportOSFileType( sal_uInt16 )
+{
+ String aOSFileType;
+ return aOSFileType;
+}
+
+// ------------------------------------------------------------------------
+
+String GraphicFilter::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ return pConfig->GetExportWildcard( nFormat, nEntry );
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool GraphicFilter::IsExportPixelFormat( sal_uInt16 nFormat )
+{
+ return pConfig->IsExportPixelFormat( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::CanImportGraphic( const INetURLObject& rPath,
+ sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
+{
+ sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
+ DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
+
+ String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
+ if ( pStream )
+ {
+ nRetValue = CanImportGraphic( aMainUrl, *pStream, nFormat, pDeterminedFormat );
+ delete pStream;
+ }
+ return nRetValue;
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::CanImportGraphic( const String& rMainUrl, SvStream& rIStream,
+ sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
+{
+ sal_uLong nStreamPos = rIStream.Tell();
+ sal_uInt16 nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat );
+
+ rIStream.Seek(nStreamPos);
+
+ if( nRes==GRFILTER_OK && pDeterminedFormat!=NULL )
+ *pDeterminedFormat = nFormat;
+
+ return (sal_uInt16) ImplSetError( nRes, &rIStream );
+}
+
+// ------------------------------------------------------------------------
+//SJ: TODO, we need to create a GraphicImporter component
+sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
+ sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, sal_uInt32 nImportFlags )
+{
+ sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
+ DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
+
+ String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
+ if ( pStream )
+ {
+ nRetValue = ImportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pDeterminedFormat, nImportFlags );
+ delete pStream;
+ }
+ return nRetValue;
+}
+
+sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
+ sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags )
+{
+ return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL );
+}
+
+//-------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
+ sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags,
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData )
+{
+ String aFilterName;
+ sal_uLong nStmBegin;
+ sal_uInt16 nStatus;
+ GraphicReader* pContext = rGraphic.GetContext();
+ GfxLinkType eLinkType = GFX_LINK_TYPE_NONE;
+ sal_Bool bDummyContext = ( pContext == (GraphicReader*) 1 );
+ const sal_Bool bLinkSet = rGraphic.IsLink();
+ FilterConfigItem* pFilterConfigItem = NULL;
+
+ Size aPreviewSizeHint( 0, 0 );
+ sal_Bool bAllowPartialStreamRead = sal_False;
+ sal_Bool bCreateNativeLink = sal_True;
+
+ ResetLastError();
+
+ if ( pFilterData )
+ {
+ sal_Int32 i;
+ for ( i = 0; i < pFilterData->getLength(); i++ )
+ {
+ if ( (*pFilterData)[ i ].Name.equalsAscii( "PreviewSizeHint" ) )
+ {
+ awt::Size aSize;
+ if ( (*pFilterData)[ i ].Value >>= aSize )
+ {
+ aPreviewSizeHint = Size( aSize.Width, aSize.Height );
+ if ( aSize.Width || aSize.Height )
+ nImportFlags |= GRFILTER_I_FLAGS_FOR_PREVIEW;
+ else
+ nImportFlags &=~GRFILTER_I_FLAGS_FOR_PREVIEW;
+ }
+ }
+ else if ( (*pFilterData)[ i ].Name.equalsAscii( "AllowPartialStreamRead" ) )
+ {
+ (*pFilterData)[ i ].Value >>= bAllowPartialStreamRead;
+ if ( bAllowPartialStreamRead )
+ nImportFlags |= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
+ else
+ nImportFlags &=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
+ }
+ else if ( (*pFilterData)[ i ].Name.equalsAscii( "CreateNativeLink" ) )
+ {
+ (*pFilterData)[ i ].Value >>= bCreateNativeLink;
+ }
+ }
+ }
+
+ if( !pContext || bDummyContext )
+ {
+ if( bDummyContext )
+ {
+ rGraphic.SetContext( NULL );
+ nStmBegin = 0;
+ }
+ else
+ nStmBegin = rIStream.Tell();
+
+ bAbort = sal_False;
+ nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat );
+ // Falls Pending, geben wir GRFILTER_OK zurueck,
+ // um mehr Bytes anzufordern
+ if( rIStream.GetError() == ERRCODE_IO_PENDING )
+ {
+ rGraphic.SetContext( (GraphicReader*) 1 );
+ rIStream.ResetError();
+ rIStream.Seek( nStmBegin );
+ return (sal_uInt16) ImplSetError( GRFILTER_OK );
+ }
+
+ rIStream.Seek( nStmBegin );
+
+ if( ( nStatus != GRFILTER_OK ) || rIStream.GetError() )
+ return (sal_uInt16) ImplSetError( ( nStatus != GRFILTER_OK ) ? nStatus : GRFILTER_OPENERROR, &rIStream );
+
+ if( pDeterminedFormat )
+ *pDeterminedFormat = nFormat;
+
+ aFilterName = pConfig->GetImportFilterName( nFormat );
+ }
+ else
+ {
+ if( pContext && !bDummyContext )
+ aFilterName = pContext->GetUpperFilterName();
+
+ nStmBegin = 0;
+ nStatus = GRFILTER_OK;
+ }
+
+ // read graphic
+ if ( pConfig->IsImportInternalFilter( nFormat ) )
+ {
+ if( aFilterName.EqualsIgnoreCaseAscii( IMP_GIF ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ if( !ImportGIF( rIStream, rGraphic ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ eLinkType = GFX_LINK_TYPE_NATIVE_GIF;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_PNG ) )
+ {
+ if ( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ vcl::PNGReader aPNGReader( rIStream );
+
+ // ignore animation for previews and set preview size
+ if( aPreviewSizeHint.Width() || aPreviewSizeHint.Height() )
+ {
+ // position the stream at the end of the image if requested
+ if( !bAllowPartialStreamRead )
+ aPNGReader.GetChunks();
+ }
+ else
+ {
+ // check if this PNG contains a GIF chunk!
+ const std::vector< vcl::PNGReader::ChunkData >& rChunkData = aPNGReader.GetChunks();
+ std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() );
+ std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() );
+ while( aIter != aEnd )
+ {
+ // Microsoft Office is storing Animated GIFs in following chunk
+ if ( aIter->nType == PMGCHUNG_msOG )
+ {
+ sal_uInt32 nChunkSize = aIter->aData.size();
+ if ( nChunkSize > 11 )
+ {
+ const std::vector< sal_uInt8 >& rData = aIter->aData;
+ SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, STREAM_READ );
+ ImportGIF( aIStrm, rGraphic );
+ eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
+ break;
+ }
+ }
+ aIter++;
+ }
+ }
+
+ if ( eLinkType == GFX_LINK_TYPE_NONE )
+ {
+ BitmapEx aBmpEx( aPNGReader.Read( aPreviewSizeHint ) );
+ if ( aBmpEx.IsEmpty() )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ rGraphic = aBmpEx;
+ eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
+ }
+ }
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_JPEG ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ // set LOGSIZE flag always, if not explicitly disabled
+ // (see #90508 and #106763)
+ if( 0 == ( nImportFlags & GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG ) )
+ nImportFlags |= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
+
+ if( !ImportJPEG( rIStream, rGraphic, NULL, nImportFlags ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ eLinkType = GFX_LINK_TYPE_NATIVE_JPG;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVG ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ vcl::SVGReader aSVGReader( rIStream );
+ GDIMetaFile aSVGMtf;
+
+ if( 0 == aSVGReader.Read( aSVGMtf ).GetActionCount() )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ rGraphic = Graphic( aSVGMtf );
+
+ // Dont set any GfxLink here, since the MetaRenderGraphicAction
+ // inside the just read MetaFile contains excatly this native data;
+ // setting a ǴfxLink would also affect other program parts, since
+ // GfxLinks are preferably written to the file format in general,
+ // which would be a bad idea in case of SVG files, since earlier
+ // implementations are not able to handle native SVG data in any
+ // case. (KA 01/19/2011)
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ if( !ImportXBM( rIStream, rGraphic ) )
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XPM ) )
+ {
+ if( rGraphic.GetContext() == (GraphicReader*) 1 )
+ rGraphic.SetContext( NULL );
+
+ if( !ImportXPM( rIStream, rGraphic ) )
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP ) ||
+ aFilterName.EqualsIgnoreCaseAscii( IMP_SVMETAFILE ) )
+ {
+ // SV interne Importfilter fuer Bitmaps und MetaFiles
+ rIStream >> rGraphic;
+ if( rIStream.GetError() )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_WMF ) ||
+ aFilterName.EqualsIgnoreCaseAscii( IMP_EMF ) )
+ {
+ GDIMetaFile aMtf;
+ if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL ) )
+ nStatus = GRFILTER_FORMATERROR;
+ else
+ {
+ rGraphic = aMtf;
+ eLinkType = GFX_LINK_TYPE_NATIVE_WMF;
+ }
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGF )
+ || aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGV ) )
+ {
+ sal_uInt16 nVersion;
+ unsigned char nTyp = CheckSgfTyp( rIStream, nVersion );
+
+ switch( nTyp )
+ {
+ case SGF_BITIMAGE:
+ {
+ SvMemoryStream aTempStream;
+ if( aTempStream.GetError() )
+ return GRFILTER_OPENERROR;
+
+ if( !SgfBMapFilter( rIStream, aTempStream ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ aTempStream.Seek( 0L );
+ aTempStream >> rGraphic;
+
+ if( aTempStream.GetError() )
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ break;
+
+ case SGF_SIMPVECT:
+ {
+ GDIMetaFile aMtf;
+ if( !SgfVectFilter( rIStream, aMtf ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ rGraphic = Graphic( aMtf );
+ }
+ break;
+
+ case SGF_STARDRAW:
+ {
+ if( nVersion != SGV_VERSION )
+ nStatus = GRFILTER_VERSIONERROR;
+ else
+ {
+ GDIMetaFile aMtf;
+ if( !SgfSDrwFilter( rIStream, aMtf,
+ INetURLObject(aFilterPath) ) )
+ {
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else
+ rGraphic = Graphic( aMtf );
+ }
+ }
+ break;
+
+ default:
+ {
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ break;
+ }
+ }
+ else
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else
+ {
+ ImpFilterLibCacheEntry* pFilter = NULL;
+
+ // find first filter in filter pathes
+ xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
+ ImpFilterLibCache &rCache = Cache::get();
+ for( i = 0; ( i < nTokenCount ) && ( pFilter == NULL ); i++ )
+ pFilter = rCache.GetFilter( aFilterPath.GetToken(i), aFilterName );
+ if( !pFilter )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ PFilterCall pFunc = pFilter->GetImportFunction();
+
+ if( !pFunc )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ String aShortName;
+ if( nFormat != GRFILTER_FORMAT_DONTKNOW )
+ {
+ aShortName = GetImportFormatShortName( nFormat ).ToUpperAscii();
+ if ( ( pFilterConfigItem == NULL ) && aShortName.EqualsAscii( "PCD" ) )
+ {
+ String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
+ pFilterConfigItem = new FilterConfigItem( aFilterConfigPath );
+ }
+ }
+ if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem, sal_False ) )
+ nStatus = GRFILTER_FORMATERROR;
+ else
+ {
+ // try to set link type if format matches
+ if( nFormat != GRFILTER_FORMAT_DONTKNOW )
+ {
+ if( aShortName.CompareToAscii( TIF_SHORTNAME ) == COMPARE_EQUAL )
+ eLinkType = GFX_LINK_TYPE_NATIVE_TIF;
+ else if( aShortName.CompareToAscii( MET_SHORTNAME ) == COMPARE_EQUAL )
+ eLinkType = GFX_LINK_TYPE_NATIVE_MET;
+ else if( aShortName.CompareToAscii( PCT_SHORTNAME ) == COMPARE_EQUAL )
+ eLinkType = GFX_LINK_TYPE_NATIVE_PCT;
+ }
+ }
+ }
+ }
+ }
+
+ if( nStatus == GRFILTER_OK && bCreateNativeLink && ( eLinkType != GFX_LINK_TYPE_NONE ) && !rGraphic.GetContext() && !bLinkSet )
+ {
+ const sal_uLong nStmEnd = rIStream.Tell();
+ const sal_uLong nBufSize = nStmEnd - nStmBegin;
+
+ if( nBufSize )
+ {
+ sal_uInt8* pBuf=0;
+ try
+ {
+ pBuf = new sal_uInt8[ nBufSize ];
+ }
+ catch (std::bad_alloc)
+ {
+ nStatus = GRFILTER_TOOBIG;
+ }
+
+ if( nStatus == GRFILTER_OK )
+ {
+ rIStream.Seek( nStmBegin );
+ rIStream.Read( pBuf, nBufSize );
+ rGraphic.SetLink( GfxLink( pBuf, nBufSize, eLinkType, sal_True ) );
+ }
+ }
+ }
+
+ // Set error code or try to set native buffer
+ if( nStatus != GRFILTER_OK )
+ {
+ if( bAbort )
+ nStatus = GRFILTER_ABORT;
+
+ ImplSetError( nStatus, &rIStream );
+ rIStream.Seek( nStmBegin );
+ rGraphic.Clear();
+ }
+
+ delete pFilterConfigItem;
+ return nStatus;
+}
+
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
+ sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
+{
+ sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
+ DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" );
+ sal_Bool bAlreadyExists = ImplDirEntryHelper::Exists( rPath );
+
+ String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_WRITE | STREAM_TRUNC );
+ if ( pStream )
+ {
+ nRetValue = ExportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pFilterData );
+ delete pStream;
+
+ if( ( GRFILTER_OK != nRetValue ) && !bAlreadyExists )
+ ImplDirEntryHelper::Kill( aMainUrl );
+ }
+ return nRetValue;
+}
+
+// ------------------------------------------------------------------------
+
+sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& rPath,
+ SvStream& rOStm, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
+{
+ sal_uInt16 nFormatCount = GetExportFormatCount();
+
+ ResetLastError();
+ nExpGraphHint = 0;
+
+ if( nFormat == GRFILTER_FORMAT_DONTKNOW )
+ {
+ INetURLObject aURL( rPath );
+ String aExt( aURL.GetFileExtension().toAsciiUpperCase() );
+
+
+ for( sal_uInt16 i = 0; i < nFormatCount; i++ )
+ {
+ if ( pConfig->GetExportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
+ {
+ nFormat=i;
+ break;
+ }
+ }
+ }
+ if( nFormat >= nFormatCount )
+ return (sal_uInt16) ImplSetError( GRFILTER_FORMATERROR );
+
+ FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
+ String aFilterName( pConfig->GetExportFilterName( nFormat ) );
+
+ bAbort = sal_False;
+ sal_uInt16 nStatus = GRFILTER_OK;
+ GraphicType eType;
+ Graphic aGraphic( rGraphic );
+
+ aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem );
+ eType = aGraphic.GetType();
+
+ if( pConfig->IsExportPixelFormat( nFormat ) )
+ {
+ if( eType != GRAPHIC_BITMAP )
+ {
+ Size aSizePixel;
+ sal_uLong nColorCount,nBitsPerPixel,nNeededMem,nMaxMem;
+ VirtualDevice aVirDev;
+
+ // Maximalen Speicherbedarf fuer das Bildes holen:
+// if( GetOptionsConfig() )
+// nMaxMem = (UINT32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32();
+// else
+ nMaxMem = 1024;
+
+ nMaxMem *= 1024; // In Bytes
+
+ // Berechnen, wie gross das Bild normalerweise werden wuerde:
+ aSizePixel=aVirDev.LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode());
+
+ // Berechnen, wieviel Speicher das Bild benoetigen wuerde:
+ nColorCount=aVirDev.GetColorCount();
+ if (nColorCount<=2) nBitsPerPixel=1;
+ else if (nColorCount<=4) nBitsPerPixel=2;
+ else if (nColorCount<=16) nBitsPerPixel=4;
+ else if (nColorCount<=256) nBitsPerPixel=8;
+ else if (nColorCount<=65536) nBitsPerPixel=16;
+ else nBitsPerPixel=24;
+ nNeededMem=((sal_uLong)aSizePixel.Width()*(sal_uLong)aSizePixel.Height()*nBitsPerPixel+7)/8;
+
+ // ggf. Groesse des Bildes einschraenken:
+ if (nMaxMem<nNeededMem)
+ {
+ double fFak=sqrt(((double)nMaxMem)/((double)nNeededMem));
+ aSizePixel.Width()=(sal_uLong)(((double)aSizePixel.Width())*fFak);
+ aSizePixel.Height()=(sal_uLong)(((double)aSizePixel.Height())*fFak);
+ }
+
+ aVirDev.SetMapMode(MapMode(MAP_PIXEL));
+ aVirDev.SetOutputSizePixel(aSizePixel);
+ Graphic aGraphic2=aGraphic;
+ aGraphic2.Draw(&aVirDev,Point(0,0),aSizePixel); // Gemein: dies aendert den MapMode
+ aVirDev.SetMapMode(MapMode(MAP_PIXEL));
+ aGraphic=Graphic(aVirDev.GetBitmap(Point(0,0),aSizePixel));
+ }
+ }
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ if( GRFILTER_OK == nStatus )
+ {
+ if ( pConfig->IsExportInternalFilter( nFormat ) )
+ {
+ if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
+ {
+ Bitmap aBmp( aGraphic.GetBitmap() );
+ sal_Int32 nColorRes = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Colors" ) ), 0 );
+ if ( nColorRes && ( nColorRes <= (sal_uInt16)BMP_CONVERSION_24BIT) )
+ {
+ if( !aBmp.Convert( (BmpConversion) nColorRes ) )
+ aBmp = aGraphic.GetBitmap();
+ }
+ ResMgr* pResMgr = CREATERESMGR( svt );
+ sal_Bool bRleCoding = aConfigItem.ReadBool( String( RTL_CONSTASCII_USTRINGPARAM( "RLE_Coding" ) ), sal_True );
+ // Wollen wir RLE-Kodiert speichern?
+ aBmp.Write( rOStm, bRleCoding );
+ delete pResMgr;
+
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) )
+ {
+ sal_Int32 nVersion = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), 0 ) ;
+ if ( nVersion )
+ rOStm.SetVersion( nVersion );
+ GDIMetaFile aMTF;
+
+ if ( eType != GRAPHIC_BITMAP )
+ aMTF = aGraphic.GetGDIMetaFile();
+ else
+ {
+ VirtualDevice aVirDev;
+
+ aMTF.Record( &aVirDev );
+ aGraphic.Draw( &aVirDev, Point(), aGraphic.GetPrefSize() );
+ aMTF.Stop();
+ aMTF.SetPrefSize( aGraphic.GetPrefSize() );
+ aMTF.SetPrefMapMode( aGraphic.GetPrefMapMode() );
+ }
+ aMTF.Write( rOStm, GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC );
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) )
+ {
+ if( eType == GRAPHIC_GDIMETAFILE )
+ {
+ if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ else
+ {
+ Bitmap aBmp( aGraphic.GetBitmap() );
+ GDIMetaFile aMTF;
+ VirtualDevice aVirDev;
+
+ aMTF.Record( &aVirDev );
+ aVirDev.DrawBitmap( Point(), aBmp );
+ aMTF.Stop();
+ aMTF.SetPrefSize( aBmp.GetSizePixel() );
+
+ if( !ConvertGDIMetaFileToWMF( aMTF, rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) )
+ {
+ if( eType == GRAPHIC_GDIMETAFILE )
+ {
+ if ( !ConvertGDIMetaFileToEMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ else
+ {
+ Bitmap aBmp( aGraphic.GetBitmap() );
+ GDIMetaFile aMTF;
+ VirtualDevice aVirDev;
+
+ aMTF.Record( &aVirDev );
+ aVirDev.DrawBitmap( Point(), aBmp );
+ aMTF.Stop();
+ aMTF.SetPrefSize( aBmp.GetSizePixel() );
+
+ if( !ConvertGDIMetaFileToEMF( aMTF, rOStm, &aConfigItem ) )
+ nStatus = GRFILTER_FORMATERROR;
+ }
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
+ {
+ bool bExportedGrayJPEG = false;
+ if( !ExportJPEG( rOStm, aGraphic, pFilterData, &bExportedGrayJPEG ) )
+ nStatus = GRFILTER_FORMATERROR;
+ nExpGraphHint = bExportedGrayJPEG ? GRFILTER_OUTHINT_GREY : 0;
+
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
+ {
+ vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData );
+ if ( pFilterData )
+ {
+ sal_Int32 k, j, i = 0;
+ for ( i = 0; i < pFilterData->getLength(); i++ )
+ {
+ if ( (*pFilterData)[ i ].Name.equalsAscii( "AdditionalChunks" ) )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence;
+ if ( (*pFilterData)[ i ].Value >>= aAdditionalChunkSequence )
+ {
+ for ( j = 0; j < aAdditionalChunkSequence.getLength(); j++ )
+ {
+ if ( aAdditionalChunkSequence[ j ].Name.getLength() == 4 )
+ {
+ sal_uInt32 nChunkType = 0;
+ for ( k = 0; k < 4; k++ )
+ {
+ nChunkType <<= 8;
+ nChunkType |= (sal_uInt8)aAdditionalChunkSequence[ j ].Name[ k ];
+ }
+ com::sun::star::uno::Sequence< sal_Int8 > aByteSeq;
+ if ( aAdditionalChunkSequence[ j ].Value >>= aByteSeq )
+ {
+ std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks();
+ if ( rChunkData.size() )
+ {
+ sal_uInt32 nChunkLen = aByteSeq.getLength();
+
+ vcl::PNGWriter::ChunkData aChunkData;
+ aChunkData.nType = nChunkType;
+ if ( nChunkLen )
+ {
+ aChunkData.aData.resize( nChunkLen );
+ rtl_copyMemory( &aChunkData.aData[ 0 ], aByteSeq.getConstArray(), nChunkLen );
+ }
+ std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1;
+ rChunkData.insert( aIter, aChunkData );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ aPNGWriter.Write( rOStm );
+
+ if( rOStm.GetError() )
+ nStatus = GRFILTER_IOERROR;
+ }
+ else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) )
+ {
+ sal_Bool bDone = sal_False;
+
+ // do we have a native SVG RenderGraphic, whose data can be written directly?
+ if( ( GRAPHIC_GDIMETAFILE == eType ) && aGraphic.IsRenderGraphic() )
+ {
+ const ::vcl::RenderGraphic aRenderGraphic( aGraphic.GetRenderGraphic() );
+
+ if( aRenderGraphic.GetGraphicDataLength() &&
+ aRenderGraphic.GetGraphicDataMimeType().equalsIgnoreAsciiCase(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/svg+xml" ) ) ) )
+ {
+ rOStm.Write( aRenderGraphic.GetGraphicData().get(),
+ aRenderGraphic.GetGraphicDataLength() );
+
+ if( rOStm.GetError() )
+ {
+ nStatus = GRFILTER_IOERROR;
+ }
+ }
+ }
+
+ if( !bDone )
+ {
+ // do the normal GDIMetaFile export instead
+ try
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
+
+ if( xMgr.is() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), ::com::sun::star::uno::UNO_QUERY );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.svg.SVGWriter" ) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xSaxWriter.is() && xSVGWriter.is() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource(
+ xSaxWriter, ::com::sun::star::uno::UNO_QUERY );
+
+ if( xActiveDataSource.is() )
+ {
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf(
+ static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) );
+
+ SvMemoryStream aMemStm( 65535, 65535 );
+
+ aMemStm.SetCompressMode( COMPRESSMODE_FULL );
+ ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm );
+
+ xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >(
+ xStmIf, ::com::sun::star::uno::UNO_QUERY ) );
+ ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() );
+ xSVGWriter->write( xSaxWriter, aMtfSeq );
+ }
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ nStatus = GRFILTER_IOERROR;
+ }
+ }
+ }
+ else
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ else
+ {
+ xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
+ for ( i = 0; i < nTokenCount; i++ )
+ {
+ String aPhysicalName( ImpCreateFullFilterPath( aFilterPath.GetToken( i ), aFilterName ) );
+ osl::Module aLibrary( aPhysicalName );
+
+ PFilterCall pFunc = (PFilterCall) aLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) );
+ // Dialog in DLL ausfuehren
+ if( pFunc )
+ {
+ if ( !(*pFunc)( rOStm, aGraphic, &aConfigItem, sal_False ) )
+ nStatus = GRFILTER_FORMATERROR;
+ break;
+ }
+ else
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ }
+ if( nStatus != GRFILTER_OK )
+ {
+ if( bAbort )
+ nStatus = GRFILTER_ABORT;
+
+ ImplSetError( nStatus, &rOStm );
+ }
+ return nStatus;
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool GraphicFilter::Setup( sal_uInt16 )
+{
+ return sal_False;
+}
+
+/* ------------------------------------------------------------------------
+ No Import filter has a dialog, so
+ the following two methods are obsolete */
+
+sal_Bool GraphicFilter::HasImportDialog( sal_uInt16 )
+{
+ return sal_True;
+// return pConfig->IsImportDialog( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool GraphicFilter::DoImportDialog( Window*, sal_uInt16 )
+{
+ return sal_True;
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool GraphicFilter::HasExportDialog( sal_uInt16 nFormat )
+{
+ return pConfig->IsExportDialog( nFormat );
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool GraphicFilter::DoExportDialog( Window* pWindow, sal_uInt16 nFormat )
+{
+ return DoExportDialog( pWindow, nFormat, FUNIT_MM );
+}
+
+sal_Bool GraphicFilter::DoExportDialog( Window*, sal_uInt16 nFormat, FieldUnit )
+{
+ sal_Bool bRet = sal_False;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xSMgr( ::comphelper::getProcessServiceFactory() );
+
+ uno::Reference< com::sun::star::uno::XInterface > xFilterOptionsDialog
+ ( xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.svtools.SvFilterOptionsDialog" ) ),
+ com::sun::star::uno::UNO_QUERY );
+ if ( xFilterOptionsDialog.is() )
+ {
+ com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XExecutableDialog > xExecutableDialog
+ ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xPropertyAccess
+ ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
+ if ( xExecutableDialog.is() && xPropertyAccess.is() )
+ {
+ com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aMediaDescriptor( 1 );
+ aMediaDescriptor[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
+ rtl::OUString aStr( pConfig->GetExportInternalFilterName( nFormat ) );
+ aMediaDescriptor[ 0 ].Value <<= aStr;
+ xPropertyAccess->setPropertyValues( aMediaDescriptor );
+ bRet = xExecutableDialog->execute() == com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
+ }
+ }
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+const FilterErrorEx& GraphicFilter::GetLastError() const
+{
+ return *pErrorEx;
+}
+
+// ------------------------------------------------------------------------
+
+void GraphicFilter::ResetLastError()
+{
+ pErrorEx->nFilterError = pErrorEx->nStreamError = 0UL;
+}
+
+// ------------------------------------------------------------------------
+
+const Link GraphicFilter::GetFilterCallback() const
+{
+ const Link aLink( LINK( this, GraphicFilter, FilterCallback ) );
+ return aLink;
+}
+
+// ------------------------------------------------------------------------
+
+IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData )
+{
+ long nRet = 0L;
+
+ if( pData )
+ {
+ sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
+ ByteString aShortName;
+ switch( pData->mnFormat )
+ {
+ case( CVT_BMP ): aShortName = BMP_SHORTNAME; break;
+ case( CVT_GIF ): aShortName = GIF_SHORTNAME; break;
+ case( CVT_JPG ): aShortName = JPG_SHORTNAME; break;
+ case( CVT_MET ): aShortName = MET_SHORTNAME; break;
+ case( CVT_PCT ): aShortName = PCT_SHORTNAME; break;
+ case( CVT_PNG ): aShortName = PNG_SHORTNAME; break;
+ case( CVT_SVM ): aShortName = SVM_SHORTNAME; break;
+ case( CVT_TIF ): aShortName = TIF_SHORTNAME; break;
+ case( CVT_WMF ): aShortName = WMF_SHORTNAME; break;
+ case( CVT_EMF ): aShortName = EMF_SHORTNAME; break;
+ case( CVT_SVG ): aShortName = SVG_SHORTNAME; break;
+
+ default:
+ break;
+ }
+ if( GRAPHIC_NONE == pData->maGraphic.GetType() || pData->maGraphic.GetContext() ) // Import
+ {
+ // Import
+ nFormat = GetImportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
+ nRet = ImportGraphic( pData->maGraphic, String(), pData->mrStm ) == 0;
+ }
+ else if( aShortName.Len() )
+ {
+ // Export
+ nFormat = GetExportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
+ nRet = ExportGraphic( pData->maGraphic, String(), pData->mrStm, nFormat ) == 0;
+ }
+ }
+ return nRet;
+}
+
+// ------------------------------------------------------------------------
+
+GraphicFilter* GraphicFilter::GetGraphicFilter()
+{
+ if( !pGraphicFilter )
+ {
+ pGraphicFilter = new GraphicFilter;
+ pGraphicFilter->GetImportFormatCount();
+ }
+ return pGraphicFilter;
+}
+
+int GraphicFilter::LoadGraphic( const String &rPath, const String &rFilterName,
+ Graphic& rGraphic, GraphicFilter* pFilter,
+ sal_uInt16* pDeterminedFormat )
+{
+ if ( !pFilter )
+ pFilter = GetGraphicFilter();
+
+ const sal_uInt16 nFilter = rFilterName.Len() && pFilter->GetImportFormatCount()
+ ? pFilter->GetImportFormatNumber( rFilterName )
+ : GRFILTER_FORMAT_DONTKNOW;
+
+ SvStream* pStream = NULL;
+ INetURLObject aURL( rPath );
+
+ if ( aURL.HasError() || INET_PROT_NOT_VALID == aURL.GetProtocol() )
+ {
+ aURL.SetSmartProtocol( INET_PROT_FILE );
+ aURL.SetSmartURL( rPath );
+ }
+ else if ( INET_PROT_FILE != aURL.GetProtocol() )
+ {
+ pStream = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
+ }
+
+ int nRes = GRFILTER_OK;
+ if ( !pStream )
+ nRes = pFilter->ImportGraphic( rGraphic, aURL, nFilter, pDeterminedFormat );
+ else
+ nRes = pFilter->ImportGraphic( rGraphic, rPath, *pStream, nFilter, pDeterminedFormat );
+
+#ifdef DBG_UTIL
+ if( nRes )
+ DBG_WARNING2( "GrafikFehler [%d] - [%s]", nRes, rPath.GetBuffer() );
+#endif
+
+ return nRes;
+}