update dev300-m58
[ooovba.git] / svtools / source / filter.vcl / filter / filter.cxx
blob8b3c190ffe3ae0966f39082da6f02d97fd5b440c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: filter.cxx,v $
10 * $Revision: 1.77 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #if defined UNX && defined ALPHA
35 #include <fstream.hxx>
36 #endif
37 #include <vos/mutex.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <ucbhelper/content.hxx>
40 #include <cppuhelper/implbase1.hxx>
41 #include <tools/urlobj.hxx>
42 #include <vcl/salctype.hxx>
43 #include <vcl/pngread.hxx>
44 #include <vcl/pngwrite.hxx>
45 #include <vcl/virdev.hxx>
46 #include <vcl/svapp.hxx>
47 #include <osl/file.hxx>
48 #include <svtools/filter.hxx>
49 #include "FilterConfigCache.hxx"
50 #include <svtools/FilterConfigItem.hxx>
51 #include <svtools/fltcall.hxx>
52 #include <svtools/wmf.hxx>
53 #include "gifread.hxx"
54 #include "jpeg.hxx"
55 #include "xbmread.hxx"
56 #include "xpmread.hxx"
57 #include <svtools/solar.hrc>
58 #include "strings.hrc"
59 #include "sgffilt.hxx"
60 #include "osl/module.hxx"
61 #include <com/sun/star/uno/Reference.h>
62 #include <com/sun/star/awt/Size.hpp>
63 #include <com/sun/star/uno/XInterface.hpp>
64 #include <com/sun/star/uno/XWeak.hpp>
65 #include <com/sun/star/uno/XAggregation.hpp>
66 #ifndef _COM_SUN_STAR_UNO_XTYPEPROVIDER_HPP_
67 #include <com/sun/star/lang/XTypeProvider.hpp>
68 #endif
69 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
70 #include <com/sun/star/io/XActiveDataSource.hpp>
71 #include <com/sun/star/io/XOutputStream.hpp>
72 #include <com/sun/star/svg/XSVGWriter.hpp>
73 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
74 #include <com/sun/star/ucb/CommandAbortedException.hpp>
75 #include <unotools/ucbstreamhelper.hxx>
76 #include <unotools/localfilehelper.hxx>
77 #include <comphelper/processfactory.hxx>
78 #include <rtl/bootstrap.hxx>
79 #include <rtl/instance.hxx>
81 #include "SvFilterOptionsDialog.hxx"
83 #define PMGCHUNG_msOG 0x6d734f47 // Microsoft Office Animated GIF
85 #if defined WIN || (defined OS2 && !defined ICC)
87 #define IMPORT_FUNCTION_NAME "_GraphicImport"
88 #define EXPORT_FUNCTION_NAME "_GraphicExport"
89 #define IMPDLG_FUNCTION_NAME "_DoImportDialog"
90 #define EXPDLG_FUNCTION_NAME "_DoExportDialog"
92 #else
94 #define IMPORT_FUNCTION_NAME "GraphicImport"
95 #define EXPORT_FUNCTION_NAME "GraphicExport"
96 #define IMPDLG_FUNCTION_NAME "DoImportDialog"
97 #define EXPDLG_FUNCTION_NAME "DoExportDialog"
99 #endif
101 // Compilerfehler, wenn Optimierung bei WNT & MSC
102 #ifdef _MSC_VER
103 #pragma optimize( "", off )
104 #endif
106 // -----------
107 // - statics -
108 // -----------
110 using namespace ::rtl;
111 using namespace ::com::sun::star;
113 static List* pFilterHdlList = NULL;
115 static ::osl::Mutex& getListMutex()
117 static ::osl::Mutex s_aListProtection;
118 return s_aListProtection;
121 static GraphicFilter* pGraphicFilter=0;
123 // -------------------------
124 // - ImpFilterOutputStream -
125 // -------------------------
127 class ImpFilterOutputStream : public ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream >
129 protected:
131 SvStream& mrStm;
133 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() ); }
134 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(); }
135 virtual void SAL_CALL closeOutput() throw() {}
137 public:
139 ImpFilterOutputStream( SvStream& rStm ) : mrStm( rStm ) {}
140 ~ImpFilterOutputStream() {}
143 BOOL ImplDirEntryHelper::Exists( const INetURLObject& rObj )
145 BOOL bExists = FALSE;
149 ::rtl::OUString aTitle;
150 ::ucbhelper::Content aCnt( rObj.GetMainURL( INetURLObject::NO_DECODE ),
151 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
153 bExists = aCnt.isDocument();
155 catch( ::com::sun::star::ucb::CommandAbortedException& )
157 DBG_ERRORFILE( "CommandAbortedException" );
159 catch( ::com::sun::star::ucb::ContentCreationException& )
161 DBG_ERRORFILE( "ContentCreationException" );
163 catch( ... )
165 // DBG_ERRORFILE( "Any other exception" );
167 return bExists;
170 // -----------------------------------------------------------------------------
172 void ImplDirEntryHelper::Kill( const String& rMainUrl )
176 ::ucbhelper::Content aCnt( rMainUrl,
177 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
179 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
180 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
182 catch( ::com::sun::star::ucb::CommandAbortedException& )
184 DBG_ERRORFILE( "CommandAbortedException" );
186 catch( ... )
188 DBG_ERRORFILE( "Any other exception" );
192 // --------------------
193 // - Helper functions -
194 // --------------------
196 //--------------------------------------------------------------------------
198 BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
200 while ( nComp-- >= nSize )
202 ULONG i;
203 for ( i = 0; i < nSize; i++ )
205 if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
206 break;
208 if ( i == nSize )
209 return pSource;
210 pSource++;
212 return NULL;
215 //--------------------------------------------------------------------------
217 inline String ImpGetExtension( const String &rPath )
219 String aExt;
220 INetURLObject aURL( rPath );
221 aExt = aURL.GetFileExtension().toAsciiUpperCase();
222 return aExt;
225 /*************************************************************************
227 |* ImpPeekGraphicFormat()
229 |* Beschreibung:
230 |* Diese Funktion kann zweierlei:
231 |* 1.) Datei anlesen, Dateiformat ermitteln
232 |* Eingabe-prarameter:
233 |* rPath - Dateipfad
234 |* rFormatExtension - Inhalt egal
235 |* bTest - setze FALSE
236 |* Ausgabe-parameter:
237 |* Funkionswert - TRUE wenn Erfolg
238 |* rFormatExtension - Bei Erfolg: uebliche Dateiendung
239 |* des Formats (Grossbuchstaben)
240 |* 2.) Datei anlesen, Dateiformat ueberpruefen
241 |* Eingabe-prarameter:
242 |* rPath - Dateipfad
243 |* rFormatExtension - uebliche Dateiendung des Formats
244 |* (Grossbuchstaben)
245 |* bTest - setze TRUE
246 |* Ausgabe-parameter:
247 |* Funkionswert - FALSE, wenn die Datei bestimmt nicht
248 |* vom uebgebenen Format ist.
249 |* TRUE, wenn die Datei WAHRSCHEINLICH von
250 |* dem Format ist, ODER WENN DAS FORMAT
251 |* DIESER FUNKTION NICHT BEKANNT IST!
253 |* Ersterstellung OH 26.05.95
254 |* Letzte Aenderung OH 07.08.95
256 *************************************************************************/
258 static BOOL ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtension, BOOL bTest )
260 USHORT i;
261 BYTE sFirstBytes[ 256 ];
262 ULONG nFirstLong,nSecondLong;
263 ULONG nStreamPos = rStream.Tell();
265 rStream.Seek( STREAM_SEEK_TO_END );
266 ULONG nStreamLen = rStream.Tell() - nStreamPos;
267 rStream.Seek( nStreamPos );
269 if ( !nStreamLen )
271 SvLockBytes* pLockBytes = rStream.GetLockBytes();
272 if ( pLockBytes )
273 pLockBytes->SetSynchronMode( TRUE );
275 rStream.Seek( STREAM_SEEK_TO_END );
276 nStreamLen = rStream.Tell() - nStreamPos;
277 rStream.Seek( nStreamPos );
279 // Die ersten 256 Bytes in einen Buffer laden:
280 if( nStreamLen >= 256 )
281 rStream.Read( sFirstBytes, 256 );
282 else
284 rStream.Read( sFirstBytes, nStreamLen );
286 for( i = (USHORT) nStreamLen; i < 256; i++ )
287 sFirstBytes[ i ]=0;
290 if( rStream.GetError() )
291 return FALSE;
293 // Die ersten 8 Bytes in nFirstLong, nSecondLong unterbringen,
294 // Big-Endian:
295 for( i = 0, nFirstLong = 0L, nSecondLong = 0L; i < 4; i++ )
297 nFirstLong=(nFirstLong<<8)|(ULONG)sFirstBytes[i];
298 nSecondLong=(nSecondLong<<8)|(ULONG)sFirstBytes[i+4];
301 // Folgende Variable ist nur bei bTest==TRUE interessant. Sie
302 // bleibt FALSE, wenn das Format (rFormatExtension) hier noch nicht
303 // einprogrammiert wurde.
304 BOOL bSomethingTested = FALSE;
306 // Nun werden die verschieden Formate ueberprueft. Dabei ist die
307 // Reihenfolge nicht egal. Z.b. koennte eine MET-Datei auch durch
308 // den BMP-Test gehen, umgekehrt kann eine BMP-Datei kaum durch den
309 // MET-Test gehen. Also sollte MET vor BMP getestet werden.
310 // Theoretisch waere aber vielleicht auch eine BMP-Datei denkbar,
311 // die durch den MET-Test geht.
312 // Diese Probleme gibt es natuerlich nicht nur bei MET und BMP.
313 // Deshalb wird im Falle der Uberpruefung eines Formats (bTest==TRUE)
314 // nur genau dieses eine Format getestet. Alles andere koennte fatale
315 // Folgen haben, z.B. wenn der Benutzer sagt, es sei BMP-Datei (und es
316 // ist BMP-Datei), und hier wuerde die Datei durch den MET-Test gehen...
318 //--------------------------- MET ------------------------------------
319 if( !bTest || ( rFormatExtension.CompareToAscii( "MET", 3 ) == COMPARE_EQUAL ) )
321 bSomethingTested=TRUE;
322 if( sFirstBytes[2] == 0xd3 )
324 rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
325 rStream.Seek( nStreamPos );
326 USHORT nFieldSize;
327 BYTE nMagic;
328 BOOL bOK=TRUE;
329 rStream >> nFieldSize >> nMagic;
330 for (i=0; i<3; i++) {
331 if (nFieldSize<6) { bOK=FALSE; break; }
332 if (nStreamLen < rStream.Tell() + nFieldSize ) { bOK=FALSE; break; }
333 rStream.SeekRel(nFieldSize-3);
334 rStream >> nFieldSize >> nMagic;
335 if (nMagic!=0xd3) { bOK=FALSE; break; }
337 rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
338 if (bOK && !rStream.GetError()) {
339 rFormatExtension= UniString::CreateFromAscii( "MET", 3 );
340 return TRUE;
345 //--------------------------- BMP ------------------------------------
346 if( !bTest || ( rFormatExtension.CompareToAscii( "BMP", 3 ) == COMPARE_EQUAL ) )
348 BYTE nOffs;
350 bSomethingTested=TRUE;
352 // OS/2-Bitmaparray ('BA') koennen wir evtl. auch lesen,
353 // dementspr. muessen wir den Offset anpassen,
354 // um auf die erste Bitmap im Array zu stossen
355 if ( sFirstBytes[0] == 0x42 && sFirstBytes[1] == 0x41 )
356 nOffs = 14;
357 else
358 nOffs = 0;
360 // Jetzt testen wir zunaechst auf 'BM'
361 if ( sFirstBytes[0+nOffs]==0x42 && sFirstBytes[1+nOffs]==0x4d )
363 // unter OS/2 koennen die Reserved-Flags != 0 sein
364 // (was sie eigentlich nicht duerften);
365 // in diesem Fall testen wir die Groesse des BmpInfoHeaders
366 if ( ( sFirstBytes[6+nOffs]==0x00 &&
367 sFirstBytes[7+nOffs]==0x00 &&
368 sFirstBytes[8+nOffs]==0x00 &&
369 sFirstBytes[9+nOffs]==0x00 ) ||
370 sFirstBytes[14+nOffs] == 0x28 ||
371 sFirstBytes[14+nOffs] == 0x0c )
373 rFormatExtension = UniString::CreateFromAscii( "BMP", 3 );
374 return TRUE;
379 //--------------------------- WMF/EMF ------------------------------------
381 if( !bTest ||
382 ( rFormatExtension.CompareToAscii( "WMF", 3 ) == COMPARE_EQUAL ) ||
383 ( rFormatExtension.CompareToAscii( "EMF", 3 ) == COMPARE_EQUAL ) )
385 bSomethingTested = TRUE;
387 if ( nFirstLong==0xd7cdc69a || nFirstLong==0x01000900 )
389 rFormatExtension = UniString::CreateFromAscii( "WMF", 3 );
390 return TRUE;
392 else if( nFirstLong == 0x01000000 && sFirstBytes[ 40 ] == 0x20 && sFirstBytes[ 41 ] == 0x45 &&
393 sFirstBytes[ 42 ] == 0x4d && sFirstBytes[ 43 ] == 0x46 )
395 rFormatExtension = UniString::CreateFromAscii( "EMF", 3 );
396 return TRUE;
400 //--------------------------- PCX ------------------------------------
401 if( !bTest || ( rFormatExtension.CompareToAscii( "PCX", 3 ) == COMPARE_EQUAL ) )
403 bSomethingTested=TRUE;
404 if (sFirstBytes[0]==0x0a)
406 BYTE nVersion=sFirstBytes[1];
407 BYTE nEncoding=sFirstBytes[2];
408 if( ( nVersion==0 || nVersion==2 || nVersion==3 || nVersion==5 ) && nEncoding<=1 )
410 rFormatExtension = UniString::CreateFromAscii( "PCX", 3 );
411 return TRUE;
416 //--------------------------- TIF ------------------------------------
417 if( !bTest || ( rFormatExtension.CompareToAscii( "TIF", 3 ) == COMPARE_EQUAL ) )
419 bSomethingTested=TRUE;
420 if ( nFirstLong==0x49492a00 || nFirstLong==0x4d4d002a )
422 rFormatExtension=UniString::CreateFromAscii( "TIF", 3 );
423 return TRUE;
427 //--------------------------- GIF ------------------------------------
428 if( !bTest || ( rFormatExtension.CompareToAscii( "GIF", 3 ) == COMPARE_EQUAL ) )
430 bSomethingTested=TRUE;
431 if ( nFirstLong==0x47494638 && (sFirstBytes[4]==0x37 || sFirstBytes[4]==0x39) && sFirstBytes[5]==0x61 )
433 rFormatExtension = UniString::CreateFromAscii( "GIF", 3 );
434 return TRUE;
438 //--------------------------- PNG ------------------------------------
439 if( !bTest || ( rFormatExtension.CompareToAscii( "PNG", 3 ) == COMPARE_EQUAL ) )
441 bSomethingTested=TRUE;
442 if (nFirstLong==0x89504e47 && nSecondLong==0x0d0a1a0a)
444 rFormatExtension = UniString::CreateFromAscii( "PNG", 3 );
445 return TRUE;
449 //--------------------------- JPG ------------------------------------
450 if( !bTest || ( rFormatExtension.CompareToAscii( "JPG", 3 ) == COMPARE_EQUAL ) )
452 bSomethingTested=TRUE;
453 if ( ( nFirstLong==0xffd8ffe0 && sFirstBytes[6]==0x4a && sFirstBytes[7]==0x46 && sFirstBytes[8]==0x49 && sFirstBytes[9]==0x46 ) ||
454 ( nFirstLong==0xffd8fffe ) || ( 0xffd8ff00 == ( nFirstLong & 0xffffff00 ) ) )
456 rFormatExtension = UniString::CreateFromAscii( "JPG", 3 );
457 return TRUE;
461 //--------------------------- SVM ------------------------------------
462 if( !bTest || ( rFormatExtension.CompareToAscii( "SVM", 3 ) == COMPARE_EQUAL ) )
464 bSomethingTested=TRUE;
465 if( nFirstLong==0x53564744 && sFirstBytes[4]==0x49 )
467 rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
468 return TRUE;
470 else if( sFirstBytes[0]==0x56 && sFirstBytes[1]==0x43 && sFirstBytes[2]==0x4C &&
471 sFirstBytes[3]==0x4D && sFirstBytes[4]==0x54 && sFirstBytes[5]==0x46 )
473 rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
474 return TRUE;
478 //--------------------------- PCD ------------------------------------
479 if( !bTest || ( rFormatExtension.CompareToAscii( "PCD", 3 ) == COMPARE_EQUAL ) )
481 bSomethingTested = TRUE;
482 if( nStreamLen >= 2055 )
484 char sBuf[8];
485 rStream.Seek( nStreamPos + 2048 );
486 rStream.Read( sBuf, 7 );
488 if( strncmp( sBuf, "PCD_IPI", 7 ) == 0 )
490 rFormatExtension = UniString::CreateFromAscii( "PCD", 3 );
491 return TRUE;
496 //--------------------------- PSD ------------------------------------
497 if( !bTest || ( rFormatExtension.CompareToAscii( "PSD", 3 ) == COMPARE_EQUAL ) )
499 bSomethingTested = TRUE;
500 if ( ( nFirstLong == 0x38425053 ) && ( (nSecondLong >> 16 ) == 1 ) )
502 rFormatExtension = UniString::CreateFromAscii( "PSD", 3 );
503 return TRUE;
507 //--------------------------- EPS ------------------------------------
508 if( !bTest || ( rFormatExtension.CompareToAscii( "EPS", 3 ) == COMPARE_EQUAL ) )
510 bSomethingTested = TRUE;
511 if ( ( nFirstLong == 0xC5D0D3C6 ) || ( ImplSearchEntry( sFirstBytes, (BYTE*)"%!PS-Adobe", 10, 10 ) &&
512 ImplSearchEntry( &sFirstBytes[15], (BYTE*)"EPS", 3, 3 ) ) )
514 rFormatExtension = UniString::CreateFromAscii( "EPS", 3 );
515 return TRUE;
519 //--------------------------- DXF ------------------------------------
520 if( !bTest || ( rFormatExtension.CompareToAscii( "DXF", 3 ) == COMPARE_EQUAL ) )
522 bSomethingTested=TRUE;
524 i=0;
525 while (i<256 && sFirstBytes[i]<=32)
526 i++;
528 if (i<256)
530 if( sFirstBytes[i]=='0' )
531 i++;
532 else
533 i=256;
535 while( i<256 && sFirstBytes[i]<=32 )
536 i++;
538 if (i+7<256)
540 if (strncmp((char*)(sFirstBytes+i),"SECTION",7)==0)
542 rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
543 return TRUE;
547 if( strncmp( (char*) sFirstBytes, "AutoCAD Binary DXF", 18 ) == 0 )
549 rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
550 return TRUE;
554 //--------------------------- PCT ------------------------------------
555 if( !bTest || ( rFormatExtension.CompareToAscii( "PCT", 3 ) == COMPARE_EQUAL ) )
557 bSomethingTested = TRUE;
558 BYTE sBuf[4];
559 sal_uInt32 nOffset; // in ms documents the pict format is used without the first 512 bytes
560 for ( nOffset = 10; ( nOffset <= 522 ) && ( ( nStreamPos + nOffset + 3 ) <= nStreamLen ); nOffset += 512 )
562 rStream.Seek( nStreamPos + nOffset );
563 rStream.Read( sBuf,3 );
564 if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && ( sBuf[ 2 ] == 0x01 || sBuf[ 2 ] == 0x02 ) )
566 rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
567 return TRUE;
572 //------------------------- PBM + PGM + PPM ---------------------------
573 if( !bTest ||
574 ( rFormatExtension.CompareToAscii( "PBM", 3 ) == COMPARE_EQUAL ) ||
575 ( rFormatExtension.CompareToAscii( "PGM", 3 ) == COMPARE_EQUAL ) ||
576 ( rFormatExtension.CompareToAscii( "PPM", 3 ) == COMPARE_EQUAL ) )
578 bSomethingTested=TRUE;
579 if ( sFirstBytes[ 0 ] == 'P' )
581 switch( sFirstBytes[ 1 ] )
583 case '1' :
584 case '4' :
585 rFormatExtension = UniString::CreateFromAscii( "PBM", 3 );
586 return TRUE;
588 case '2' :
589 case '5' :
590 rFormatExtension = UniString::CreateFromAscii( "PGM", 3 );
591 return TRUE;
593 case '3' :
594 case '6' :
595 rFormatExtension = UniString::CreateFromAscii( "PPM", 3 );
596 return TRUE;
601 //--------------------------- RAS( SUN RasterFile )------------------
602 if( !bTest || ( rFormatExtension.CompareToAscii( "RAS", 3 ) == COMPARE_EQUAL ) )
604 bSomethingTested=TRUE;
605 if( nFirstLong == 0x59a66a95 )
607 rFormatExtension = UniString::CreateFromAscii( "RAS", 3 );
608 return TRUE;
612 //--------------------------- XPM ------------------------------------
613 if( !bTest )
615 bSomethingTested = TRUE;
616 if( ImplSearchEntry( sFirstBytes, (BYTE*)"/* XPM */", 256, 9 ) )
618 rFormatExtension = UniString::CreateFromAscii( "XPM", 3 );
619 return TRUE;
622 else if( rFormatExtension.CompareToAscii( "XPM", 3 ) == COMPARE_EQUAL )
624 bSomethingTested = TRUE;
625 return TRUE;
628 //--------------------------- XBM ------------------------------------
629 if( !bTest )
631 ULONG nSize = ( nStreamLen > 2048 ) ? 2048 : nStreamLen;
632 BYTE* pBuf = new BYTE [ nSize ];
634 rStream.Seek( nStreamPos );
635 rStream.Read( pBuf, nSize );
636 BYTE* pPtr = ImplSearchEntry( pBuf, (BYTE*)"#define", nSize, 7 );
638 if( pPtr )
640 if( ImplSearchEntry( pPtr, (BYTE*)"_width", pBuf + nSize - pPtr, 6 ) )
642 rFormatExtension = UniString::CreateFromAscii( "XBM", 3 );
643 delete[] pBuf;
644 return TRUE;
647 delete[] pBuf;
649 else if( rFormatExtension.CompareToAscii( "XBM", 3 ) == COMPARE_EQUAL )
651 bSomethingTested = TRUE;
652 return TRUE;
655 //--------------------------- TGA ------------------------------------
656 if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) )
658 bSomethingTested = TRUE;
659 if( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL )
660 return TRUE;
663 //--------------------------- SGV ------------------------------------
664 if( !bTest || ( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) )
666 bSomethingTested = TRUE;
667 if( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL )
668 return TRUE;
671 //--------------------------- SGF ------------------------------------
672 if( !bTest || ( rFormatExtension.CompareToAscii( "SGF", 3 ) == COMPARE_EQUAL ) )
674 bSomethingTested=TRUE;
675 if( sFirstBytes[ 0 ] == 'J' && sFirstBytes[ 1 ] == 'J' )
677 rFormatExtension = UniString::CreateFromAscii( "SGF", 3 );
678 return TRUE;
682 return bTest && !bSomethingTested;
685 //--------------------------------------------------------------------------
687 sal_uInt16 GraphicFilter::ImpTestOrFindFormat( const String& rPath, SvStream& rStream, sal_uInt16& rFormat )
689 sal_uInt16 n = pConfig->GetImportFormatCount();
691 // ggf. Filter bzw. Format durch anlesen ermitteln,
692 // oder durch anlesen zusichern, dass das Format stimmt:
693 if( rFormat == GRFILTER_FORMAT_DONTKNOW )
695 String aFormatExt;
696 if( ImpPeekGraphicFormat( rStream, aFormatExt, FALSE ) )
698 for( sal_uInt16 i = 0; i < n; i++ )
700 if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aFormatExt ) )
702 rFormat = i;
703 return GRFILTER_OK;
707 // ggf. Filter anhand der Datei-Endung raussuchen:
708 if( rPath.Len() )
710 String aExt( ImpGetExtension( rPath ) );
711 for( sal_uInt16 i = 0; i < n; i++ )
713 if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
715 rFormat = i;
716 return GRFILTER_OK;
720 return GRFILTER_FORMATERROR;
722 else
724 String aTmpStr( pConfig->GetImportFormatExtension( rFormat ) );
725 if( !ImpPeekGraphicFormat( rStream, aTmpStr, TRUE ) )
726 return GRFILTER_FORMATERROR;
727 if ( pConfig->GetImportFormatExtension( rFormat ).EqualsIgnoreCaseAscii( "pcd" ) )
729 sal_Int32 nBase = 2; // default Base0
730 if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base4" ) )
731 nBase = 1;
732 else if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base16" ) )
733 nBase = 0;
734 String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
735 FilterConfigItem aFilterConfigItem( aFilterConfigPath );
736 aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
740 return GRFILTER_OK;
743 //--------------------------------------------------------------------------
745 static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem )
747 Graphic aGraphic;
748 ByteString aResMgrName( "svt", 3 );
749 ResMgr* pResMgr;
751 pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
753 sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) ), 0 );
754 sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) ), 0 );
756 if ( rGraphic.GetType() != GRAPHIC_NONE )
758 sal_Int32 nMode = rConfigItem.ReadInt32( String( ResId( KEY_MODE, *pResMgr ) ), -1 );
760 if ( nMode == -1 ) // the property is not there, this is possible, if the graphic filter
761 { // is called via UnoGraphicExporter and not from a graphic export Dialog
762 nMode = 0; // then we are defaulting this mode to 0
763 if ( nLogicalWidth || nLogicalHeight )
764 nMode = 2;
768 Size aOriginalSize;
769 Size aPrefSize( rGraphic.GetPrefSize() );
770 MapMode aPrefMapMode( rGraphic.GetPrefMapMode() );
771 if ( aPrefMapMode == MAP_PIXEL )
772 aOriginalSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
773 else
774 aOriginalSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
775 if ( !nLogicalWidth )
776 nLogicalWidth = aOriginalSize.Width();
777 if ( !nLogicalHeight )
778 nLogicalHeight = aOriginalSize.Height();
779 if( rGraphic.GetType() == GRAPHIC_BITMAP )
782 // Aufloesung wird eingestellt
783 if( nMode == 1 )
785 Bitmap aBitmap( rGraphic.GetBitmap() );
786 MapMode aMap( MAP_100TH_INCH );
788 sal_Int32 nDPI = rConfigItem.ReadInt32( String( ResId( KEY_RES, *pResMgr ) ), 75 );
789 Fraction aFrac( 1, Min( Max( nDPI, sal_Int32( 75 ) ), sal_Int32( 600 ) ) );
791 aMap.SetScaleX( aFrac );
792 aMap.SetScaleY( aFrac );
794 Size aOldSize = aBitmap.GetSizePixel();
795 aBitmap.SetPrefMapMode( aMap );
796 aBitmap.SetPrefSize( Size( aOldSize.Width() * 100,
797 aOldSize.Height() * 100 ) );
799 aGraphic = Graphic( aBitmap );
801 // Groesse wird eingestellt
802 else if( nMode == 2 )
804 BitmapEx aBitmapEx( rGraphic.GetBitmapEx() );
805 aBitmapEx.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
806 aBitmapEx.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) );
807 aGraphic = Graphic( aBitmapEx );
809 else
810 aGraphic = rGraphic;
812 sal_Int32 nColors = rConfigItem.ReadInt32( String( ResId( KEY_COLORS, *pResMgr ) ), 0 ); // #92767#
813 if ( nColors ) // graphic conversion necessary ?
815 BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
816 aBmpEx.Convert( (BmpConversion)nColors ); // the entries in the xml section have the same meaning as
817 aGraphic = aBmpEx; // they have in the BmpConversion enum, so it should be
818 } // allowed to cast them
820 else
822 if( ( nMode == 1 ) || ( nMode == 2 ) )
824 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
825 ::com::sun::star::awt::Size aDefaultSize( 10000, 10000 );
826 Size aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth, nLogicalHeight ), MAP_100TH_MM, aMtf.GetPrefMapMode() ) );
828 if( aNewSize.Width() && aNewSize.Height() )
830 const Size aPreferredSize( aMtf.GetPrefSize() );
831 aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ),
832 Fraction( aNewSize.Height(), aPreferredSize.Height() ) );
834 aGraphic = Graphic( aMtf );
836 else
837 aGraphic = rGraphic;
841 else
842 aGraphic = rGraphic;
844 delete pResMgr;
846 return aGraphic;
849 static String ImpCreateFullFilterPath( const String& rPath, const String& rFilterName )
851 ::rtl::OUString aPathURL;
853 ::osl::FileBase::getFileURLFromSystemPath( rPath, aPathURL );
854 aPathURL += String( '/' );
856 ::rtl::OUString aSystemPath;
857 ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
858 aSystemPath += ::rtl::OUString( rFilterName );
860 return String( aSystemPath );
864 // --------------------------
865 // - ImpFilterLibCacheEntry -
866 // --------------------------
868 class ImpFilterLibCache;
870 struct ImpFilterLibCacheEntry
872 ImpFilterLibCacheEntry* mpNext;
873 osl::Module maLibrary;
874 String maFiltername;
875 PFilterCall mpfnImport;
876 PFilterDlgCall mpfnImportDlg;
878 ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername );
879 int operator==( const String& rFiltername ) const { return maFiltername == rFiltername; }
881 PFilterCall GetImportFunction();
882 PFilterDlgCall GetImportDlgFunction();
883 PFilterCall GetExportFunction() { return (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) ); }
884 PFilterDlgCall GetExportDlgFunction() { return (PFilterDlgCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) ); }
887 // ------------------------------------------------------------------------
889 ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername ) :
890 mpNext ( NULL ),
891 maLibrary ( rPathname ),
892 maFiltername ( rFiltername ),
893 mpfnImport ( NULL ),
894 mpfnImportDlg ( NULL )
898 // ------------------------------------------------------------------------
900 PFilterCall ImpFilterLibCacheEntry::GetImportFunction()
902 if( !mpfnImport )
903 mpfnImport = (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPORT_FUNCTION_NAME ) );
905 return mpfnImport;
908 // ------------------------------------------------------------------------
910 PFilterDlgCall ImpFilterLibCacheEntry::GetImportDlgFunction()
912 if( !mpfnImportDlg )
913 mpfnImportDlg = (PFilterDlgCall)maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPDLG_FUNCTION_NAME ) );
915 return mpfnImportDlg;
918 // ---------------------
919 // - ImpFilterLibCache -
920 // ---------------------
922 class ImpFilterLibCache
924 ImpFilterLibCacheEntry* mpFirst;
925 ImpFilterLibCacheEntry* mpLast;
927 public:
928 ImpFilterLibCache();
929 ~ImpFilterLibCache();
931 ImpFilterLibCacheEntry* GetFilter( const String& rFilterPath, const String& rFiltername );
934 // ------------------------------------------------------------------------
936 ImpFilterLibCache::ImpFilterLibCache() :
937 mpFirst ( NULL ),
938 mpLast ( NULL )
942 // ------------------------------------------------------------------------
944 ImpFilterLibCache::~ImpFilterLibCache()
946 ImpFilterLibCacheEntry* pEntry = mpFirst;
947 while( pEntry )
949 ImpFilterLibCacheEntry* pNext = pEntry->mpNext;
950 delete pEntry;
951 pEntry = pNext;
955 // ------------------------------------------------------------------------
957 ImpFilterLibCacheEntry* ImpFilterLibCache::GetFilter( const String& rFilterPath, const String& rFilterName )
959 ImpFilterLibCacheEntry* pEntry = mpFirst;
961 while( pEntry )
963 if( *pEntry == rFilterName )
964 break;
965 else
966 pEntry = pEntry->mpNext;
968 if( !pEntry )
970 String aPhysicalName( ImpCreateFullFilterPath( rFilterPath, rFilterName ) );
971 pEntry = new ImpFilterLibCacheEntry( aPhysicalName, rFilterName );
973 if ( pEntry->maLibrary.is() )
975 if( !mpFirst )
976 mpFirst = mpLast = pEntry;
977 else
978 mpLast = mpLast->mpNext = pEntry;
980 else
982 delete pEntry;
983 pEntry = NULL;
986 return pEntry;
989 // ------------------------------------------------------------------------
991 namespace { struct Cache : public rtl::Static<ImpFilterLibCache, Cache> {}; }
993 // -----------------
994 // - GraphicFilter -
995 // -----------------
997 GraphicFilter::GraphicFilter( sal_Bool bConfig ) :
998 bUseConfig ( bConfig )
1000 ImplInit();
1003 // ------------------------------------------------------------------------
1005 GraphicFilter::~GraphicFilter()
1008 ::osl::MutexGuard aGuard( getListMutex() );
1009 pFilterHdlList->Remove( (void*)this );
1010 if ( !pFilterHdlList->Count() )
1012 delete pFilterHdlList, pFilterHdlList = NULL;
1013 delete pConfig;
1018 delete pErrorEx;
1021 // ------------------------------------------------------------------------
1023 void GraphicFilter::ImplInit()
1026 ::osl::MutexGuard aGuard( getListMutex() );
1028 if ( !pFilterHdlList )
1030 pFilterHdlList = new List;
1031 pConfig = new FilterConfigCache( bUseConfig );
1033 else
1034 pConfig = ((GraphicFilter*)pFilterHdlList->First())->pConfig;
1036 pFilterHdlList->Insert( (void*)this );
1039 if( bUseConfig )
1041 #if defined WNT
1042 rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program"));
1043 #else
1044 rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program"));
1045 #endif
1046 rtl::Bootstrap::expandMacros(url); //TODO: detect failure
1047 utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath);
1050 pErrorEx = new FilterErrorEx;
1051 bAbort = sal_False;
1054 // ------------------------------------------------------------------------
1056 ULONG GraphicFilter::ImplSetError( ULONG nError, const SvStream* pStm )
1058 pErrorEx->nFilterError = nError;
1059 pErrorEx->nStreamError = pStm ? pStm->GetError() : ERRCODE_NONE;
1060 return nError;
1062 // ------------------------------------------------------------------------
1064 USHORT GraphicFilter::GetImportFormatCount()
1066 return pConfig->GetImportFormatCount();
1069 // ------------------------------------------------------------------------
1071 USHORT GraphicFilter::GetImportFormatNumber( const String& rFormatName )
1073 return pConfig->GetImportFormatNumber( rFormatName );
1076 // ------------------------------------------------------------------------
1078 USHORT GraphicFilter::GetImportFormatNumberForMediaType( const String& rMediaType )
1080 return pConfig->GetImportFormatNumberForMediaType( rMediaType );
1083 // ------------------------------------------------------------------------
1085 USHORT GraphicFilter::GetImportFormatNumberForShortName( const String& rShortName )
1087 return pConfig->GetImportFormatNumberForShortName( rShortName );
1090 // ------------------------------------------------------------------------
1092 sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( const String& rType )
1094 return pConfig->GetImportFormatNumberForTypeName( rType );
1097 // ------------------------------------------------------------------------
1099 String GraphicFilter::GetImportFormatName( USHORT nFormat )
1101 return pConfig->GetImportFormatName( nFormat );
1104 // ------------------------------------------------------------------------
1106 String GraphicFilter::GetImportFormatTypeName( USHORT nFormat )
1108 return pConfig->GetImportFilterTypeName( nFormat );
1111 // ------------------------------------------------------------------------
1113 String GraphicFilter::GetImportFormatMediaType( USHORT nFormat )
1115 return pConfig->GetImportFormatMediaType( nFormat );
1118 // ------------------------------------------------------------------------
1120 String GraphicFilter::GetImportFormatShortName( USHORT nFormat )
1122 return pConfig->GetImportFormatShortName( nFormat );
1125 // ------------------------------------------------------------------------
1127 String GraphicFilter::GetImportOSFileType( USHORT )
1129 String aOSFileType;
1130 return aOSFileType;
1133 // ------------------------------------------------------------------------
1135 String GraphicFilter::GetImportWildcard( USHORT nFormat, sal_Int32 nEntry )
1137 return pConfig->GetImportWildcard( nFormat, nEntry );
1140 // ------------------------------------------------------------------------
1142 BOOL GraphicFilter::IsImportPixelFormat( USHORT nFormat )
1144 return pConfig->IsImportPixelFormat( nFormat );
1147 // ------------------------------------------------------------------------
1149 USHORT GraphicFilter::GetExportFormatCount()
1151 return pConfig->GetExportFormatCount();
1154 // ------------------------------------------------------------------------
1156 USHORT GraphicFilter::GetExportFormatNumber( const String& rFormatName )
1158 return pConfig->GetExportFormatNumber( rFormatName );
1161 // ------------------------------------------------------------------------
1163 USHORT GraphicFilter::GetExportFormatNumberForMediaType( const String& rMediaType )
1165 return pConfig->GetExportFormatNumberForMediaType( rMediaType );
1168 // ------------------------------------------------------------------------
1170 USHORT GraphicFilter::GetExportFormatNumberForShortName( const String& rShortName )
1172 return pConfig->GetExportFormatNumberForShortName( rShortName );
1175 // ------------------------------------------------------------------------
1177 sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( const String& rType )
1179 return pConfig->GetExportFormatNumberForTypeName( rType );
1182 // ------------------------------------------------------------------------
1184 String GraphicFilter::GetExportFormatName( USHORT nFormat )
1186 return pConfig->GetExportFormatName( nFormat );
1189 // ------------------------------------------------------------------------
1191 String GraphicFilter::GetExportFormatTypeName( USHORT nFormat )
1193 return pConfig->GetExportFilterTypeName( nFormat );
1196 // ------------------------------------------------------------------------
1198 String GraphicFilter::GetExportFormatMediaType( USHORT nFormat )
1200 return pConfig->GetExportFormatMediaType( nFormat );
1203 // ------------------------------------------------------------------------
1205 String GraphicFilter::GetExportFormatShortName( USHORT nFormat )
1207 return pConfig->GetExportFormatShortName( nFormat );
1210 // ------------------------------------------------------------------------
1212 String GraphicFilter::GetExportOSFileType( USHORT )
1214 String aOSFileType;
1215 return aOSFileType;
1218 // ------------------------------------------------------------------------
1220 String GraphicFilter::GetExportWildcard( USHORT nFormat, sal_Int32 nEntry )
1222 return pConfig->GetExportWildcard( nFormat, nEntry );
1225 // ------------------------------------------------------------------------
1227 BOOL GraphicFilter::IsExportPixelFormat( USHORT nFormat )
1229 return pConfig->IsExportPixelFormat( nFormat );
1232 // ------------------------------------------------------------------------
1234 USHORT GraphicFilter::CanImportGraphic( const INetURLObject& rPath,
1235 USHORT nFormat, USHORT* pDeterminedFormat )
1237 sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
1238 DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1240 String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1241 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
1242 if ( pStream )
1244 nRetValue = CanImportGraphic( aMainUrl, *pStream, nFormat, pDeterminedFormat );
1245 delete pStream;
1247 return nRetValue;
1250 // ------------------------------------------------------------------------
1252 USHORT GraphicFilter::CanImportGraphic( const String& rMainUrl, SvStream& rIStream,
1253 USHORT nFormat, USHORT* pDeterminedFormat )
1255 ULONG nStreamPos = rIStream.Tell();
1256 sal_uInt16 nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat );
1258 rIStream.Seek(nStreamPos);
1260 if( nRes==GRFILTER_OK && pDeterminedFormat!=NULL )
1261 *pDeterminedFormat = nFormat;
1263 return (USHORT) ImplSetError( nRes, &rIStream );
1266 // ------------------------------------------------------------------------
1267 //SJ: TODO, we need to create a GraphicImporter component
1268 USHORT GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
1269 USHORT nFormat, USHORT * pDeterminedFormat, sal_uInt32 nImportFlags )
1271 sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
1272 DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1274 String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1275 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
1276 if ( pStream )
1278 nRetValue = ImportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pDeterminedFormat, nImportFlags );
1279 delete pStream;
1281 return nRetValue;
1284 USHORT GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream, USHORT nFormat, USHORT* pDeterminedFormat, sal_uInt32 nImportFlags, WMF_APMFILEHEADER *pAPMHeader )
1286 return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL, pAPMHeader );
1289 //-------------------------------------------------------------------------
1291 USHORT GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
1292 USHORT nFormat, USHORT* pDeterminedFormat, sal_uInt32 nImportFlags,
1293 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData
1294 , WMF_APMFILEHEADER *pAPMHeader)
1296 String aFilterName;
1297 ULONG nStmBegin;
1298 USHORT nStatus;
1299 GraphicReader* pContext = rGraphic.GetContext();
1300 GfxLinkType eLinkType = GFX_LINK_TYPE_NONE;
1301 BOOL bDummyContext = ( pContext == (GraphicReader*) 1 );
1302 const BOOL bLinkSet = rGraphic.IsLink();
1303 FilterConfigItem* pFilterConfigItem = NULL;
1305 Size aPreviewSizeHint( 0, 0 );
1306 sal_Bool bAllowPartialStreamRead = sal_False;
1307 sal_Bool bCreateNativeLink = sal_True;
1309 ResetLastError();
1311 if ( pFilterData )
1313 sal_Int32 i;
1314 for ( i = 0; i < pFilterData->getLength(); i++ )
1316 if ( (*pFilterData)[ i ].Name.equalsAscii( "PreviewSizeHint" ) )
1318 awt::Size aSize;
1319 if ( (*pFilterData)[ i ].Value >>= aSize )
1321 aPreviewSizeHint = Size( aSize.Width, aSize.Height );
1322 if ( aSize.Width || aSize.Height )
1323 nImportFlags |= GRFILTER_I_FLAGS_FOR_PREVIEW;
1324 else
1325 nImportFlags &=~GRFILTER_I_FLAGS_FOR_PREVIEW;
1328 else if ( (*pFilterData)[ i ].Name.equalsAscii( "AllowPartialStreamRead" ) )
1330 (*pFilterData)[ i ].Value >>= bAllowPartialStreamRead;
1331 if ( bAllowPartialStreamRead )
1332 nImportFlags |= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
1333 else
1334 nImportFlags &=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
1336 else if ( (*pFilterData)[ i ].Name.equalsAscii( "CreateNativeLink" ) )
1338 (*pFilterData)[ i ].Value >>= bCreateNativeLink;
1343 if( !pContext || bDummyContext )
1345 if( bDummyContext )
1347 rGraphic.SetContext( NULL );
1348 nStmBegin = 0;
1350 else
1351 nStmBegin = rIStream.Tell();
1353 bAbort = FALSE;
1354 nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat );
1355 // Falls Pending, geben wir GRFILTER_OK zurueck,
1356 // um mehr Bytes anzufordern
1357 if( rIStream.GetError() == ERRCODE_IO_PENDING )
1359 rGraphic.SetContext( (GraphicReader*) 1 );
1360 rIStream.ResetError();
1361 rIStream.Seek( nStmBegin );
1362 return (USHORT) ImplSetError( GRFILTER_OK );
1365 rIStream.Seek( nStmBegin );
1367 if( ( nStatus != GRFILTER_OK ) || rIStream.GetError() )
1368 return (USHORT) ImplSetError( ( nStatus != GRFILTER_OK ) ? nStatus : GRFILTER_OPENERROR, &rIStream );
1370 if( pDeterminedFormat )
1371 *pDeterminedFormat = nFormat;
1373 aFilterName = pConfig->GetImportFilterName( nFormat );
1375 else
1377 if( pContext && !bDummyContext )
1378 aFilterName = pContext->GetUpperFilterName();
1380 nStmBegin = 0;
1381 nStatus = GRFILTER_OK;
1384 // read graphic
1385 if ( pConfig->IsImportInternalFilter( nFormat ) )
1387 if( aFilterName.EqualsIgnoreCaseAscii( IMP_GIF ) )
1389 if( rGraphic.GetContext() == (GraphicReader*) 1 )
1390 rGraphic.SetContext( NULL );
1392 if( !ImportGIF( rIStream, rGraphic ) )
1393 nStatus = GRFILTER_FILTERERROR;
1394 else
1395 eLinkType = GFX_LINK_TYPE_NATIVE_GIF;
1397 else if( aFilterName.EqualsIgnoreCaseAscii( IMP_PNG ) )
1399 if ( rGraphic.GetContext() == (GraphicReader*) 1 )
1400 rGraphic.SetContext( NULL );
1402 vcl::PNGReader aPNGReader( rIStream );
1404 // ignore animation for previews and set preview size
1405 if( aPreviewSizeHint.Width() || aPreviewSizeHint.Height() )
1407 // position the stream at the end of the image if requested
1408 if( !bAllowPartialStreamRead )
1409 aPNGReader.GetChunks();
1411 else
1413 // check if this PNG contains a GIF chunk!
1414 const std::vector< vcl::PNGReader::ChunkData >& rChunkData = aPNGReader.GetChunks();
1415 std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() );
1416 std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() );
1417 while( aIter != aEnd )
1419 // Microsoft Office is storing Animated GIFs in following chunk
1420 if ( aIter->nType == PMGCHUNG_msOG )
1422 sal_uInt32 nChunkSize = aIter->aData.size();
1423 if ( nChunkSize > 11 )
1425 const std::vector< sal_uInt8 >& rData = aIter->aData;
1426 SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, STREAM_READ );
1427 ImportGIF( aIStrm, rGraphic );
1428 eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
1429 break;
1432 aIter++;
1436 if ( eLinkType == GFX_LINK_TYPE_NONE )
1438 BitmapEx aBmpEx( aPNGReader.Read( aPreviewSizeHint ) );
1439 if ( aBmpEx.IsEmpty() )
1440 nStatus = GRFILTER_FILTERERROR;
1441 else
1443 rGraphic = aBmpEx;
1444 eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
1448 else if( aFilterName.EqualsIgnoreCaseAscii( IMP_JPEG ) )
1450 if( rGraphic.GetContext() == (GraphicReader*) 1 )
1451 rGraphic.SetContext( NULL );
1453 // set LOGSIZE flag always, if not explicitly disabled
1454 // (see #90508 and #106763)
1455 if( 0 == ( nImportFlags & GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG ) )
1456 nImportFlags |= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
1458 if( !ImportJPEG( rIStream, rGraphic, NULL, nImportFlags ) )
1459 nStatus = GRFILTER_FILTERERROR;
1460 else
1461 eLinkType = GFX_LINK_TYPE_NATIVE_JPG;
1463 else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) )
1465 if( rGraphic.GetContext() == (GraphicReader*) 1 )
1466 rGraphic.SetContext( NULL );
1468 if( !ImportXBM( rIStream, rGraphic ) )
1469 nStatus = GRFILTER_FILTERERROR;
1471 else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XPM ) )
1473 if( rGraphic.GetContext() == (GraphicReader*) 1 )
1474 rGraphic.SetContext( NULL );
1476 if( !ImportXPM( rIStream, rGraphic ) )
1477 nStatus = GRFILTER_FILTERERROR;
1479 else if( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP ) ||
1480 aFilterName.EqualsIgnoreCaseAscii( IMP_SVMETAFILE ) )
1482 // SV interne Importfilter fuer Bitmaps und MetaFiles
1483 rIStream >> rGraphic;
1484 if( rIStream.GetError() )
1485 nStatus = GRFILTER_FORMATERROR;
1487 else if( aFilterName.EqualsIgnoreCaseAscii( IMP_WMF ) ||
1488 aFilterName.EqualsIgnoreCaseAscii( IMP_EMF ) )
1490 GDIMetaFile aMtf;
1491 if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL, pAPMHeader ) )
1492 nStatus = GRFILTER_FORMATERROR;
1493 else
1495 rGraphic = aMtf;
1496 eLinkType = GFX_LINK_TYPE_NATIVE_WMF;
1499 else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGF )
1500 || aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGV ) )
1502 USHORT nVersion;
1503 unsigned char nTyp = CheckSgfTyp( rIStream, nVersion );
1505 switch( nTyp )
1507 case SGF_BITIMAGE:
1509 SvMemoryStream aTempStream;
1510 if( aTempStream.GetError() )
1511 return GRFILTER_OPENERROR;
1513 if( !SgfBMapFilter( rIStream, aTempStream ) )
1514 nStatus = GRFILTER_FILTERERROR;
1515 else
1517 aTempStream.Seek( 0L );
1518 aTempStream >> rGraphic;
1520 if( aTempStream.GetError() )
1521 nStatus = GRFILTER_FILTERERROR;
1524 break;
1526 case SGF_SIMPVECT:
1528 GDIMetaFile aMtf;
1529 if( !SgfVectFilter( rIStream, aMtf ) )
1530 nStatus = GRFILTER_FILTERERROR;
1531 else
1532 rGraphic = Graphic( aMtf );
1534 break;
1536 case SGF_STARDRAW:
1538 if( nVersion != SGV_VERSION )
1539 nStatus = GRFILTER_VERSIONERROR;
1540 else
1542 GDIMetaFile aMtf;
1543 if( !SgfSDrwFilter( rIStream, aMtf,
1544 INetURLObject(aFilterPath) ) )
1546 nStatus = GRFILTER_FILTERERROR;
1548 else
1549 rGraphic = Graphic( aMtf );
1552 break;
1554 default:
1556 nStatus = GRFILTER_FORMATERROR;
1558 break;
1561 else
1562 nStatus = GRFILTER_FILTERERROR;
1564 else
1566 ImpFilterLibCacheEntry* pFilter = NULL;
1568 // find first filter in filter pathes
1569 xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
1570 ImpFilterLibCache &rCache = Cache::get();
1571 for( i = 0; ( i < nTokenCount ) && ( pFilter == NULL ); i++ )
1572 pFilter = rCache.GetFilter( aFilterPath.GetToken(i), aFilterName );
1573 if( !pFilter )
1574 nStatus = GRFILTER_FILTERERROR;
1575 else
1577 PFilterCall pFunc = pFilter->GetImportFunction();
1579 if( !pFunc )
1580 nStatus = GRFILTER_FILTERERROR;
1581 else
1583 String aShortName;
1584 if( nFormat != GRFILTER_FORMAT_DONTKNOW )
1586 aShortName = GetImportFormatShortName( nFormat ).ToUpperAscii();
1587 if ( ( pFilterConfigItem == NULL ) && aShortName.EqualsAscii( "PCD" ) )
1589 String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
1590 pFilterConfigItem = new FilterConfigItem( aFilterConfigPath );
1593 if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem, sal_False ) )
1594 nStatus = GRFILTER_FORMATERROR;
1595 else
1597 // try to set link type if format matches
1598 if( nFormat != GRFILTER_FORMAT_DONTKNOW )
1600 if( aShortName.CompareToAscii( TIF_SHORTNAME ) == COMPARE_EQUAL )
1601 eLinkType = GFX_LINK_TYPE_NATIVE_TIF;
1602 else if( aShortName.CompareToAscii( MET_SHORTNAME ) == COMPARE_EQUAL )
1603 eLinkType = GFX_LINK_TYPE_NATIVE_MET;
1604 else if( aShortName.CompareToAscii( PCT_SHORTNAME ) == COMPARE_EQUAL )
1605 eLinkType = GFX_LINK_TYPE_NATIVE_PCT;
1612 if( nStatus == GRFILTER_OK && bCreateNativeLink && ( eLinkType != GFX_LINK_TYPE_NONE ) && !rGraphic.GetContext() && !bLinkSet )
1614 const ULONG nStmEnd = rIStream.Tell();
1615 const ULONG nBufSize = nStmEnd - nStmBegin;
1617 if( nBufSize )
1619 BYTE* pBuf=0;
1622 pBuf = new BYTE[ nBufSize ];
1624 catch (std::bad_alloc)
1626 nStatus = GRFILTER_TOOBIG;
1629 if( nStatus == GRFILTER_OK )
1631 rIStream.Seek( nStmBegin );
1632 rIStream.Read( pBuf, nBufSize );
1633 rGraphic.SetLink( GfxLink( pBuf, nBufSize, eLinkType, TRUE ) );
1638 // Set error code or try to set native buffer
1639 if( nStatus != GRFILTER_OK )
1641 if( bAbort )
1642 nStatus = GRFILTER_ABORT;
1644 ImplSetError( nStatus, &rIStream );
1645 rIStream.Seek( nStmBegin );
1646 rGraphic.Clear();
1649 delete pFilterConfigItem;
1650 return nStatus;
1654 // ------------------------------------------------------------------------
1656 USHORT GraphicFilter::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
1657 sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
1659 sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
1660 DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1661 BOOL bAlreadyExists = ImplDirEntryHelper::Exists( rPath );
1663 String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1664 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_WRITE | STREAM_TRUNC );
1665 if ( pStream )
1667 nRetValue = ExportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pFilterData );
1668 delete pStream;
1670 if( ( GRFILTER_OK != nRetValue ) && !bAlreadyExists )
1671 ImplDirEntryHelper::Kill( aMainUrl );
1673 return nRetValue;
1676 // ------------------------------------------------------------------------
1678 USHORT GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& rPath,
1679 SvStream& rOStm, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
1681 USHORT nFormatCount = GetExportFormatCount();
1683 ResetLastError();
1685 if( nFormat == GRFILTER_FORMAT_DONTKNOW )
1687 INetURLObject aURL( rPath );
1688 String aExt( aURL.GetFileExtension().toAsciiUpperCase() );
1691 for( USHORT i = 0; i < nFormatCount; i++ )
1693 if ( pConfig->GetExportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
1695 nFormat=i;
1696 break;
1700 if( nFormat >= nFormatCount )
1701 return (USHORT) ImplSetError( GRFILTER_FORMATERROR );
1703 FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
1704 String aFilterName( pConfig->GetExportFilterName( nFormat ) );
1706 bAbort = FALSE;
1707 USHORT nStatus = GRFILTER_OK;
1708 GraphicType eType;
1709 Graphic aGraphic( rGraphic );
1711 aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem );
1712 eType = aGraphic.GetType();
1714 if( pConfig->IsExportPixelFormat( nFormat ) )
1716 if( eType != GRAPHIC_BITMAP )
1718 Size aSizePixel;
1719 ULONG nColorCount,nBitsPerPixel,nNeededMem,nMaxMem;
1720 VirtualDevice aVirDev;
1722 // Maximalen Speicherbedarf fuer das Bildes holen:
1723 // if( GetOptionsConfig() )
1724 // nMaxMem = (UINT32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32();
1725 // else
1726 nMaxMem = 1024;
1728 nMaxMem *= 1024; // In Bytes
1730 // Berechnen, wie gross das Bild normalerweise werden wuerde:
1731 aSizePixel=aVirDev.LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode());
1733 // Berechnen, wieviel Speicher das Bild benoetigen wuerde:
1734 nColorCount=aVirDev.GetColorCount();
1735 if (nColorCount<=2) nBitsPerPixel=1;
1736 else if (nColorCount<=4) nBitsPerPixel=2;
1737 else if (nColorCount<=16) nBitsPerPixel=4;
1738 else if (nColorCount<=256) nBitsPerPixel=8;
1739 else if (nColorCount<=65536) nBitsPerPixel=16;
1740 else nBitsPerPixel=24;
1741 nNeededMem=((ULONG)aSizePixel.Width()*(ULONG)aSizePixel.Height()*nBitsPerPixel+7)/8;
1743 // ggf. Groesse des Bildes einschraenken:
1744 if (nMaxMem<nNeededMem)
1746 double fFak=sqrt(((double)nMaxMem)/((double)nNeededMem));
1747 aSizePixel.Width()=(ULONG)(((double)aSizePixel.Width())*fFak);
1748 aSizePixel.Height()=(ULONG)(((double)aSizePixel.Height())*fFak);
1751 aVirDev.SetMapMode(MapMode(MAP_PIXEL));
1752 aVirDev.SetOutputSizePixel(aSizePixel);
1753 Graphic aGraphic2=aGraphic;
1754 aGraphic2.Draw(&aVirDev,Point(0,0),aSizePixel); // Gemein: dies aendert den MapMode
1755 aVirDev.SetMapMode(MapMode(MAP_PIXEL));
1756 aGraphic=Graphic(aVirDev.GetBitmap(Point(0,0),aSizePixel));
1759 if( rOStm.GetError() )
1760 nStatus = GRFILTER_IOERROR;
1761 if( GRFILTER_OK == nStatus )
1763 if ( pConfig->IsExportInternalFilter( nFormat ) )
1765 if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
1767 Bitmap aBmp( aGraphic.GetBitmap() );
1768 sal_Int32 nColorRes = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Colors" ) ), 0 );
1769 if ( nColorRes && ( nColorRes <= (USHORT)BMP_CONVERSION_24BIT) )
1771 if( !aBmp.Convert( (BmpConversion) nColorRes ) )
1772 aBmp = aGraphic.GetBitmap();
1774 ResMgr* pResMgr = CREATERESMGR( svt );
1775 sal_Bool bRleCoding = aConfigItem.ReadBool( String( ResId( KEY_RLE_CODING, *pResMgr ) ), sal_True );
1776 // Wollen wir RLE-Kodiert speichern?
1777 aBmp.Write( rOStm, bRleCoding );
1778 delete pResMgr;
1780 if( rOStm.GetError() )
1781 nStatus = GRFILTER_IOERROR;
1783 else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) )
1785 sal_Int32 nVersion = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), 0 ) ;
1786 if ( nVersion )
1787 rOStm.SetVersion( nVersion );
1788 GDIMetaFile aMTF;
1790 if ( eType != GRAPHIC_BITMAP )
1791 aMTF = aGraphic.GetGDIMetaFile();
1792 else
1794 VirtualDevice aVirDev;
1796 aMTF.Record( &aVirDev );
1797 aGraphic.Draw( &aVirDev, Point(), aGraphic.GetPrefSize() );
1798 aMTF.Stop();
1799 aMTF.SetPrefSize( aGraphic.GetPrefSize() );
1800 aMTF.SetPrefMapMode( aGraphic.GetPrefMapMode() );
1802 rOStm << aMTF;
1803 if( rOStm.GetError() )
1804 nStatus = GRFILTER_IOERROR;
1806 else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) )
1808 if( eType == GRAPHIC_GDIMETAFILE )
1810 if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
1811 nStatus = GRFILTER_FORMATERROR;
1813 else
1815 Bitmap aBmp( aGraphic.GetBitmap() );
1816 GDIMetaFile aMTF;
1817 VirtualDevice aVirDev;
1819 aMTF.Record( &aVirDev );
1820 aVirDev.DrawBitmap( Point(), aBmp );
1821 aMTF.Stop();
1822 aMTF.SetPrefSize( aBmp.GetSizePixel() );
1824 if( !ConvertGDIMetaFileToWMF( aMTF, rOStm, &aConfigItem ) )
1825 nStatus = GRFILTER_FORMATERROR;
1827 if( rOStm.GetError() )
1828 nStatus = GRFILTER_IOERROR;
1830 else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) )
1832 if( eType == GRAPHIC_GDIMETAFILE )
1834 if ( !ConvertGDIMetaFileToEMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
1835 nStatus = GRFILTER_FORMATERROR;
1837 else
1839 Bitmap aBmp( aGraphic.GetBitmap() );
1840 GDIMetaFile aMTF;
1841 VirtualDevice aVirDev;
1843 aMTF.Record( &aVirDev );
1844 aVirDev.DrawBitmap( Point(), aBmp );
1845 aMTF.Stop();
1846 aMTF.SetPrefSize( aBmp.GetSizePixel() );
1848 if( !ConvertGDIMetaFileToEMF( aMTF, rOStm, &aConfigItem ) )
1849 nStatus = GRFILTER_FORMATERROR;
1851 if( rOStm.GetError() )
1852 nStatus = GRFILTER_IOERROR;
1854 else if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
1856 if( !ExportJPEG( rOStm, aGraphic, pFilterData ) )
1857 nStatus = GRFILTER_FORMATERROR;
1859 if( rOStm.GetError() )
1860 nStatus = GRFILTER_IOERROR;
1862 else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
1864 vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData );
1865 if ( pFilterData )
1867 sal_Int32 k, j, i = 0;
1868 for ( i = 0; i < pFilterData->getLength(); i++ )
1870 if ( (*pFilterData)[ i ].Name.equalsAscii( "AdditionalChunks" ) )
1872 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence;
1873 if ( (*pFilterData)[ i ].Value >>= aAdditionalChunkSequence )
1875 for ( j = 0; j < aAdditionalChunkSequence.getLength(); j++ )
1877 if ( aAdditionalChunkSequence[ j ].Name.getLength() == 4 )
1879 sal_uInt32 nChunkType = 0;
1880 for ( k = 0; k < 4; k++ )
1882 nChunkType <<= 8;
1883 nChunkType |= (sal_uInt8)aAdditionalChunkSequence[ j ].Name[ k ];
1885 com::sun::star::uno::Sequence< sal_Int8 > aByteSeq;
1886 if ( aAdditionalChunkSequence[ j ].Value >>= aByteSeq )
1888 std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks();
1889 if ( rChunkData.size() )
1891 sal_uInt32 nChunkLen = aByteSeq.getLength();
1893 vcl::PNGWriter::ChunkData aChunkData;
1894 aChunkData.nType = nChunkType;
1895 if ( nChunkLen )
1897 aChunkData.aData.resize( nChunkLen );
1898 rtl_copyMemory( &aChunkData.aData[ 0 ], aByteSeq.getConstArray(), nChunkLen );
1900 std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1;
1901 rChunkData.insert( aIter, aChunkData );
1910 aPNGWriter.Write( rOStm );
1912 if( rOStm.GetError() )
1913 nStatus = GRFILTER_IOERROR;
1915 else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) )
1919 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
1921 if( xMgr.is() )
1923 ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance(
1924 ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), ::com::sun::star::uno::UNO_QUERY );
1926 ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstance(
1927 ::rtl::OUString::createFromAscii( "com.sun.star.svg.SVGWriter" ) ), ::com::sun::star::uno::UNO_QUERY );
1929 if( xSaxWriter.is() && xSVGWriter.is() )
1931 ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource(
1932 xSaxWriter, ::com::sun::star::uno::UNO_QUERY );
1934 if( xActiveDataSource.is() )
1936 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf(
1937 static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) );
1939 SvMemoryStream aMemStm( 65535, 65535 );
1941 aMemStm.SetCompressMode( COMPRESSMODE_FULL );
1942 ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm );
1944 xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >(
1945 xStmIf, ::com::sun::star::uno::UNO_QUERY ) );
1946 ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() );
1947 xSVGWriter->write( xSaxWriter, aMtfSeq );
1952 catch( ::com::sun::star::uno::Exception& )
1954 nStatus = GRFILTER_IOERROR;
1957 else
1958 nStatus = GRFILTER_FILTERERROR;
1960 else
1962 xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
1963 for ( i = 0; i < nTokenCount; i++ )
1965 String aPhysicalName( ImpCreateFullFilterPath( aFilterPath.GetToken( i ), aFilterName ) );
1966 osl::Module aLibrary( aPhysicalName );
1968 PFilterCall pFunc = (PFilterCall) aLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) );
1969 // Dialog in DLL ausfuehren
1970 if( pFunc )
1972 if ( !(*pFunc)( rOStm, aGraphic, &aConfigItem, sal_False ) )
1973 nStatus = GRFILTER_FORMATERROR;
1974 break;
1976 else
1977 nStatus = GRFILTER_FILTERERROR;
1981 if( nStatus != GRFILTER_OK )
1983 if( bAbort )
1984 nStatus = GRFILTER_ABORT;
1986 ImplSetError( nStatus, &rOStm );
1988 return nStatus;
1991 // ------------------------------------------------------------------------
1993 BOOL GraphicFilter::Setup( USHORT )
1995 return FALSE;
1998 /* ------------------------------------------------------------------------
1999 No Import filter has a dialog, so
2000 the following two methods are obsolete */
2002 BOOL GraphicFilter::HasImportDialog( USHORT )
2004 return sal_True;
2005 // return pConfig->IsImportDialog( nFormat );
2008 // ------------------------------------------------------------------------
2010 BOOL GraphicFilter::DoImportDialog( Window*, USHORT )
2012 return sal_True;
2015 // ------------------------------------------------------------------------
2017 BOOL GraphicFilter::HasExportDialog( USHORT nFormat )
2019 return pConfig->IsExportDialog( nFormat );
2022 // ------------------------------------------------------------------------
2024 BOOL GraphicFilter::DoExportDialog( Window* pWindow, USHORT nFormat )
2026 return DoExportDialog( pWindow, nFormat, FUNIT_MM );
2029 BOOL GraphicFilter::DoExportDialog( Window*, USHORT nFormat, FieldUnit )
2031 sal_Bool bRet = sal_False;
2032 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
2033 xSMgr( ::comphelper::getProcessServiceFactory() );
2035 uno::Reference< com::sun::star::uno::XInterface > xFilterOptionsDialog
2036 ( xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.svtools.SvFilterOptionsDialog" ) ),
2037 com::sun::star::uno::UNO_QUERY );
2038 if ( xFilterOptionsDialog.is() )
2040 com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XExecutableDialog > xExecutableDialog
2041 ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
2042 com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xPropertyAccess
2043 ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
2044 if ( xExecutableDialog.is() && xPropertyAccess.is() )
2046 com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aMediaDescriptor( 1 );
2047 aMediaDescriptor[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
2048 rtl::OUString aStr( pConfig->GetExportInternalFilterName( nFormat ) );
2049 aMediaDescriptor[ 0 ].Value <<= aStr;
2050 xPropertyAccess->setPropertyValues( aMediaDescriptor );
2051 bRet = xExecutableDialog->execute() == com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
2054 return bRet;
2057 // ------------------------------------------------------------------------
2059 const FilterErrorEx& GraphicFilter::GetLastError() const
2061 return *pErrorEx;
2064 // ------------------------------------------------------------------------
2066 void GraphicFilter::ResetLastError()
2068 pErrorEx->nFilterError = pErrorEx->nStreamError = 0UL;
2071 // ------------------------------------------------------------------------
2073 const Link GraphicFilter::GetFilterCallback() const
2075 const Link aLink( LINK( this, GraphicFilter, FilterCallback ) );
2076 return aLink;
2079 // ------------------------------------------------------------------------
2081 IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData )
2083 long nRet = 0L;
2085 if( pData )
2087 USHORT nFormat = GRFILTER_FORMAT_DONTKNOW;
2088 ByteString aShortName;
2089 switch( pData->mnFormat )
2091 case( CVT_BMP ): aShortName = BMP_SHORTNAME; break;
2092 case( CVT_GIF ): aShortName = GIF_SHORTNAME; break;
2093 case( CVT_JPG ): aShortName = JPG_SHORTNAME; break;
2094 case( CVT_MET ): aShortName = MET_SHORTNAME; break;
2095 case( CVT_PCT ): aShortName = PCT_SHORTNAME; break;
2096 case( CVT_PNG ): aShortName = PNG_SHORTNAME; break;
2097 case( CVT_SVM ): aShortName = SVM_SHORTNAME; break;
2098 case( CVT_TIF ): aShortName = TIF_SHORTNAME; break;
2099 case( CVT_WMF ): aShortName = WMF_SHORTNAME; break;
2100 case( CVT_EMF ): aShortName = EMF_SHORTNAME; break;
2102 default:
2103 break;
2105 if( GRAPHIC_NONE == pData->maGraphic.GetType() || pData->maGraphic.GetContext() ) // Import
2107 // Import
2108 nFormat = GetImportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
2109 nRet = ImportGraphic( pData->maGraphic, String(), pData->mrStm ) == 0;
2111 else if( aShortName.Len() )
2113 // Export
2114 nFormat = GetExportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
2115 nRet = ExportGraphic( pData->maGraphic, String(), pData->mrStm, nFormat ) == 0;
2118 return nRet;
2121 // ------------------------------------------------------------------------
2123 GraphicFilter* GraphicFilter::GetGraphicFilter()
2125 if( !pGraphicFilter )
2127 pGraphicFilter = new GraphicFilter;
2128 pGraphicFilter->GetImportFormatCount();
2130 return pGraphicFilter;