xref: /AOO41X/main/svtools/source/filter/filter.cxx (revision 22d2383be6847618b3ce48ca671b022e44cc0d9f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #if defined UNX && defined ALPHA
28 #include <fstream.hxx>
29 #endif
30 #include <vos/mutex.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <ucbhelper/content.hxx>
33 #include <cppuhelper/implbase1.hxx>
34 #include <tools/urlobj.hxx>
35 #include <vcl/salctype.hxx>
36 #include <vcl/pngread.hxx>
37 #include <vcl/pngwrite.hxx>
38 #include <vcl/svgdata.hxx>
39 #include <vcl/virdev.hxx>
40 #include <vcl/svapp.hxx>
41 #include <osl/file.hxx>
42 #include <svtools/filter.hxx>
43 #include "FilterConfigCache.hxx"
44 #include <svtools/FilterConfigItem.hxx>
45 #include <svtools/fltcall.hxx>
46 #include <svtools/wmf.hxx>
47 #include "gifread.hxx"
48 #include "jpeg.hxx"
49 #include "xbmread.hxx"
50 #include "xpmread.hxx"
51 #include <svl/solar.hrc>
52 #include <svtools/svtools.hrc>
53 #include "sgffilt.hxx"
54 #include "osl/module.hxx"
55 #include <com/sun/star/uno/Reference.h>
56 #include <com/sun/star/awt/Size.hpp>
57 #include <com/sun/star/uno/XInterface.hpp>
58 #include <com/sun/star/uno/XWeak.hpp>
59 #include <com/sun/star/uno/XAggregation.hpp>
60 #ifndef _COM_SUN_STAR_UNO_XTYPEPROVIDER_HPP_
61 #include <com/sun/star/lang/XTypeProvider.hpp>
62 #endif
63 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
64 #include <com/sun/star/io/XActiveDataSource.hpp>
65 #include <com/sun/star/io/XOutputStream.hpp>
66 #include <com/sun/star/svg/XSVGWriter.hpp>
67 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
68 #include <com/sun/star/ucb/CommandAbortedException.hpp>
69 #include <unotools/ucbstreamhelper.hxx>
70 #include <unotools/localfilehelper.hxx>
71 #include <comphelper/processfactory.hxx>
72 #include <rtl/bootstrap.hxx>
73 #include <rtl/instance.hxx>
74 #include <vcl/metaact.hxx>
75 #include <vcl/dibtools.hxx>
76 
77 #include "SvFilterOptionsDialog.hxx"
78 
79 #define PMGCHUNG_msOG       0x6d734f47      // Microsoft Office Animated GIF
80 
81 #if (defined OS2 && !defined ICC)
82 
83 #define IMPORT_FUNCTION_NAME    "_GraphicImport"
84 #define EXPORT_FUNCTION_NAME    "_GraphicExport"
85 #define IMPDLG_FUNCTION_NAME    "_DoImportDialog"
86 #define EXPDLG_FUNCTION_NAME    "_DoExportDialog"
87 
88 #else
89 
90 #define IMPORT_FUNCTION_NAME    "GraphicImport"
91 #define EXPORT_FUNCTION_NAME    "GraphicExport"
92 #define IMPDLG_FUNCTION_NAME    "DoImportDialog"
93 #define EXPDLG_FUNCTION_NAME    "DoExportDialog"
94 
95 #endif
96 
97 
98 // -----------
99 // - statics -
100 // -----------
101 
102 using namespace ::rtl;
103 using namespace ::com::sun::star;
104 
105 static List*        pFilterHdlList = NULL;
106 
getListMutex()107 static ::osl::Mutex& getListMutex()
108 {
109     static ::osl::Mutex s_aListProtection;
110     return s_aListProtection;
111 }
112 
113 static GraphicFilter* pGraphicFilter=0;
114 
115 // -------------------------
116 // - ImpFilterOutputStream -
117 // -------------------------
118 
119 class ImpFilterOutputStream : public ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream >
120 {
121 protected:
122 
123     SvStream&                           mrStm;
124 
writeBytes(const::com::sun::star::uno::Sequence<sal_Int8> & rData)125     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() ); }
flush()126     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(); }
closeOutput()127     virtual void SAL_CALL               closeOutput() throw() {}
128 
129 public:
130 
ImpFilterOutputStream(SvStream & rStm)131                                         ImpFilterOutputStream( SvStream& rStm ) : mrStm( rStm ) {}
~ImpFilterOutputStream()132                                         ~ImpFilterOutputStream() {}
133 };
134 
Exists(const INetURLObject & rObj)135 sal_Bool ImplDirEntryHelper::Exists( const INetURLObject& rObj )
136 {
137     sal_Bool bExists = sal_False;
138 
139     try
140     {
141         ::rtl::OUString aTitle;
142         ::ucbhelper::Content    aCnt( rObj.GetMainURL( INetURLObject::NO_DECODE ),
143                               ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
144 
145         bExists = aCnt.isDocument();
146     }
147     catch( ::com::sun::star::ucb::CommandAbortedException& )
148     {
149         DBG_ERRORFILE( "CommandAbortedException" );
150     }
151     catch( ::com::sun::star::ucb::ContentCreationException& )
152     {
153         DBG_ERRORFILE( "ContentCreationException" );
154     }
155     catch( ... )
156     {
157 //      DBG_ERRORFILE( "Any other exception" );
158     }
159     return bExists;
160 }
161 
162 // -----------------------------------------------------------------------------
163 
Kill(const String & rMainUrl)164 void ImplDirEntryHelper::Kill( const String& rMainUrl )
165 {
166     try
167     {
168         ::ucbhelper::Content aCnt( rMainUrl,
169                              ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
170 
171         aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
172                              ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
173     }
174     catch( ::com::sun::star::ucb::CommandAbortedException& )
175     {
176         DBG_ERRORFILE( "CommandAbortedException" );
177     }
178     catch( ... )
179     {
180         DBG_ERRORFILE( "Any other exception" );
181     }
182 }
183 
184 // --------------------
185 // - Helper functions -
186 // --------------------
187 
188 //--------------------------------------------------------------------------
189 
ImplSearchEntry(sal_uInt8 * pSource,sal_uInt8 * pDest,sal_uLong nComp,sal_uLong nSize)190 sal_uInt8* ImplSearchEntry( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nComp, sal_uLong nSize )
191 {
192     while ( nComp-- >= nSize )
193     {
194         sal_uLong i;
195         for ( i = 0; i < nSize; i++ )
196         {
197             if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
198                 break;
199         }
200         if ( i == nSize )
201             return pSource;
202         pSource++;
203     }
204     return NULL;
205 }
206 
207 //--------------------------------------------------------------------------
208 
ImpGetExtension(const String & rPath)209 inline String ImpGetExtension( const String &rPath )
210 {
211     String          aExt;
212     INetURLObject   aURL( rPath );
213     aExt = aURL.GetFileExtension().toAsciiUpperCase();
214     return aExt;
215 }
216 
217 /*************************************************************************
218 |*
219 |*    ImpPeekGraphicFormat()
220 |*
221 |*    Beschreibung:
222 |*        Diese Funktion kann zweierlei:
223 |*        1.) Datei anlesen, Dateiformat ermitteln
224 |*            Eingabe-prarameter:
225 |*              rPath            - Dateipfad
226 |*              rFormatExtension - Inhalt egal
227 |*              bTest            - setze sal_False
228 |*            Ausgabe-parameter:
229 |*              Funkionswert     - sal_True wenn Erfolg
230 |*              rFormatExtension - Bei Erfolg: uebliche Dateiendung
231 |*                                 des Formats (Grossbuchstaben)
232 |*        2.) Datei anlesen, Dateiformat ueberpruefen
233 |*            Eingabe-prarameter:
234 |*              rPath            - Dateipfad
235 |*              rFormatExtension - uebliche Dateiendung des Formats
236 |*                                 (Grossbuchstaben)
237 |*              bTest            - setze sal_True
238 |*            Ausgabe-parameter:
239 |*              Funkionswert     - sal_False, wenn die Datei bestimmt nicht
240 |*                                 vom uebgebenen Format ist.
241 |*                                 sal_True, wenn die Datei WAHRSCHEINLICH von
242 |*                                 dem Format ist, ODER WENN DAS FORMAT
243 |*                                 DIESER FUNKTION NICHT BEKANNT IST!
244 |*
245 |*    Ersterstellung    OH 26.05.95
246 |*    Letzte Aenderung  OH 07.08.95
247 |*
248 *************************************************************************/
249 
ImpPeekGraphicFormat(SvStream & rStream,String & rFormatExtension,sal_Bool bTest)250 static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtension, sal_Bool bTest )
251 {
252     sal_uInt16  i;
253     sal_uInt8    sFirstBytes[ 256 ];
254     sal_uLong   nFirstLong,nSecondLong;
255     sal_uLong   nStreamPos = rStream.Tell();
256 
257     rStream.Seek( STREAM_SEEK_TO_END );
258     sal_uLong nStreamLen = rStream.Tell() - nStreamPos;
259     rStream.Seek( nStreamPos );
260 
261     if ( !nStreamLen )
262     {
263         SvLockBytes* pLockBytes = rStream.GetLockBytes();
264         if ( pLockBytes  )
265             pLockBytes->SetSynchronMode( sal_True );
266 
267         rStream.Seek( STREAM_SEEK_TO_END );
268         nStreamLen = rStream.Tell() - nStreamPos;
269         rStream.Seek( nStreamPos );
270     }
271     // Die ersten 256 Bytes in einen Buffer laden:
272     if( nStreamLen >= 256 )
273         rStream.Read( sFirstBytes, 256 );
274     else
275     {
276         rStream.Read( sFirstBytes, nStreamLen );
277 
278         for( i = (sal_uInt16) nStreamLen; i < 256; i++ )
279             sFirstBytes[ i ]=0;
280     }
281 
282     if( rStream.GetError() )
283         return sal_False;
284 
285     // Die ersten 8 Bytes in nFirstLong, nSecondLong unterbringen,
286     // Big-Endian:
287     for( i = 0, nFirstLong = 0L, nSecondLong = 0L; i < 4; i++ )
288     {
289         nFirstLong=(nFirstLong<<8)|(sal_uLong)sFirstBytes[i];
290         nSecondLong=(nSecondLong<<8)|(sal_uLong)sFirstBytes[i+4];
291     }
292 
293     // Folgende Variable ist nur bei bTest==sal_True interessant. Sie
294     // bleibt sal_False, wenn das Format (rFormatExtension) hier noch nicht
295     // einprogrammiert wurde.
296     sal_Bool bSomethingTested = sal_False;
297 
298     // Nun werden die verschieden Formate ueberprueft. Dabei ist die
299     // Reihenfolge nicht egal. Z.b. koennte eine MET-Datei auch durch
300     // den BMP-Test gehen, umgekehrt kann eine BMP-Datei kaum durch den
301     // MET-Test gehen. Also sollte MET vor BMP getestet werden.
302     // Theoretisch waere aber vielleicht auch eine BMP-Datei denkbar,
303     // die durch den MET-Test geht.
304     // Diese Probleme gibt es natuerlich nicht nur bei MET und BMP.
305     // Deshalb wird im Falle der Uberpruefung eines Formats (bTest==sal_True)
306     // nur genau dieses eine Format getestet. Alles andere koennte fatale
307     // Folgen haben, z.B. wenn der Benutzer sagt, es sei BMP-Datei (und es
308     // ist BMP-Datei), und hier wuerde die Datei durch den MET-Test gehen...
309 
310     //--------------------------- MET ------------------------------------
311     if( !bTest || ( rFormatExtension.CompareToAscii( "MET", 3 ) == COMPARE_EQUAL ) )
312     {
313         bSomethingTested=sal_True;
314         if( sFirstBytes[2] == 0xd3 )
315         {
316             rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
317             rStream.Seek( nStreamPos );
318             sal_uInt16 nFieldSize;
319             sal_uInt8 nMagic;
320             sal_Bool bOK=sal_True;
321             rStream >> nFieldSize >> nMagic;
322             for (i=0; i<3; i++) {
323                 if (nFieldSize<6) { bOK=sal_False; break; }
324                 if (nStreamLen < rStream.Tell() + nFieldSize ) { bOK=sal_False; break; }
325                 rStream.SeekRel(nFieldSize-3);
326                 rStream >> nFieldSize >> nMagic;
327                 if (nMagic!=0xd3) { bOK=sal_False; break; }
328             }
329             rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
330             if (bOK && !rStream.GetError()) {
331                 rFormatExtension= UniString::CreateFromAscii( "MET", 3 );
332                 return sal_True;
333             }
334         }
335     }
336 
337     //--------------------------- BMP ------------------------------------
338     if( !bTest || ( rFormatExtension.CompareToAscii( "BMP", 3 ) == COMPARE_EQUAL ) )
339     {
340         sal_uInt8 nOffs;
341 
342         bSomethingTested=sal_True;
343 
344         // OS/2-Bitmaparray ('BA') koennen wir evtl. auch lesen,
345         // dementspr. muessen wir den Offset anpassen,
346         // um auf die erste Bitmap im Array zu stossen
347         if ( sFirstBytes[0] == 0x42 && sFirstBytes[1] == 0x41 )
348             nOffs = 14;
349         else
350             nOffs = 0;
351 
352         // Jetzt testen wir zunaechst auf 'BM'
353         if ( sFirstBytes[0+nOffs]==0x42 && sFirstBytes[1+nOffs]==0x4d )
354         {
355             // unter OS/2 koennen die Reserved-Flags != 0 sein
356             // (was sie eigentlich nicht duerften);
357             // in diesem Fall testen wir die Groesse des BmpInfoHeaders
358             if ( ( sFirstBytes[6+nOffs]==0x00 &&
359                    sFirstBytes[7+nOffs]==0x00 &&
360                    sFirstBytes[8+nOffs]==0x00 &&
361                    sFirstBytes[9+nOffs]==0x00 ) ||
362                    sFirstBytes[14+nOffs] == 0x28 ||
363                    sFirstBytes[14+nOffs] == 0x0c )
364             {
365                 rFormatExtension = UniString::CreateFromAscii( "BMP", 3 );
366                 return sal_True;
367             }
368         }
369     }
370 
371     //--------------------------- WMF/EMF ------------------------------------
372 
373     if( !bTest ||
374         ( rFormatExtension.CompareToAscii( "WMF", 3 ) == COMPARE_EQUAL ) ||
375             ( rFormatExtension.CompareToAscii( "EMF", 3 ) == COMPARE_EQUAL ) )
376     {
377         bSomethingTested = sal_True;
378 
379         if ( nFirstLong==0xd7cdc69a || nFirstLong==0x01000900 )
380         {
381             rFormatExtension = UniString::CreateFromAscii( "WMF", 3 );
382             return sal_True;
383         }
384         else if( nFirstLong == 0x01000000 && sFirstBytes[ 40 ] == 0x20 && sFirstBytes[ 41 ] == 0x45 &&
385             sFirstBytes[ 42 ] == 0x4d && sFirstBytes[ 43 ] == 0x46 )
386         {
387             rFormatExtension = UniString::CreateFromAscii( "EMF", 3 );
388             return sal_True;
389         }
390     }
391 
392     //--------------------------- PCX ------------------------------------
393     if( !bTest || ( rFormatExtension.CompareToAscii( "PCX", 3 ) == COMPARE_EQUAL ) )
394     {
395         bSomethingTested=sal_True;
396         if (sFirstBytes[0]==0x0a)
397         {
398             sal_uInt8 nVersion=sFirstBytes[1];
399             sal_uInt8 nEncoding=sFirstBytes[2];
400             if( ( nVersion==0 || nVersion==2 || nVersion==3 || nVersion==5 ) && nEncoding<=1 )
401             {
402                 rFormatExtension = UniString::CreateFromAscii( "PCX", 3 );
403                 return sal_True;
404             }
405         }
406     }
407 
408     //--------------------------- TIF ------------------------------------
409     if( !bTest || ( rFormatExtension.CompareToAscii( "TIF", 3 ) == COMPARE_EQUAL ) )
410     {
411         bSomethingTested=sal_True;
412         if ( nFirstLong==0x49492a00 || nFirstLong==0x4d4d002a )
413         {
414             rFormatExtension=UniString::CreateFromAscii( "TIF", 3 );
415             return sal_True;
416         }
417     }
418 
419     //--------------------------- GIF ------------------------------------
420     if( !bTest || ( rFormatExtension.CompareToAscii( "GIF", 3 ) == COMPARE_EQUAL ) )
421     {
422         bSomethingTested=sal_True;
423         if ( nFirstLong==0x47494638 && (sFirstBytes[4]==0x37 || sFirstBytes[4]==0x39) && sFirstBytes[5]==0x61 )
424         {
425             rFormatExtension = UniString::CreateFromAscii( "GIF", 3 );
426             return sal_True;
427         }
428     }
429 
430     //--------------------------- PNG ------------------------------------
431     if( !bTest || ( rFormatExtension.CompareToAscii( "PNG", 3 ) == COMPARE_EQUAL ) )
432     {
433         bSomethingTested=sal_True;
434         if (nFirstLong==0x89504e47 && nSecondLong==0x0d0a1a0a)
435         {
436             rFormatExtension = UniString::CreateFromAscii( "PNG", 3 );
437             return sal_True;
438         }
439     }
440 
441     //--------------------------- JPG ------------------------------------
442     if( !bTest || ( rFormatExtension.CompareToAscii( "JPG", 3 ) == COMPARE_EQUAL ) )
443     {
444         bSomethingTested=sal_True;
445         if ( ( nFirstLong==0xffd8ffe0 && sFirstBytes[6]==0x4a && sFirstBytes[7]==0x46 && sFirstBytes[8]==0x49 && sFirstBytes[9]==0x46 ) ||
446              ( nFirstLong==0xffd8fffe ) || ( 0xffd8ff00 == ( nFirstLong & 0xffffff00 ) ) )
447         {
448             rFormatExtension = UniString::CreateFromAscii( "JPG", 3 );
449             return sal_True;
450         }
451     }
452 
453     //--------------------------- SVM ------------------------------------
454     if( !bTest || ( rFormatExtension.CompareToAscii( "SVM", 3 ) == COMPARE_EQUAL ) )
455     {
456         bSomethingTested=sal_True;
457         if( nFirstLong==0x53564744 && sFirstBytes[4]==0x49 )
458         {
459             rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
460             return sal_True;
461         }
462         else if( sFirstBytes[0]==0x56 && sFirstBytes[1]==0x43 && sFirstBytes[2]==0x4C &&
463                  sFirstBytes[3]==0x4D && sFirstBytes[4]==0x54 && sFirstBytes[5]==0x46 )
464         {
465             rFormatExtension = UniString::CreateFromAscii( "SVM", 3 );
466             return sal_True;
467         }
468     }
469 
470     //--------------------------- PCD ------------------------------------
471     if( !bTest || ( rFormatExtension.CompareToAscii( "PCD", 3 ) == COMPARE_EQUAL ) )
472     {
473         bSomethingTested = sal_True;
474         if( nStreamLen >= 2055 )
475         {
476             char sBuf[8];
477             rStream.Seek( nStreamPos + 2048 );
478             rStream.Read( sBuf, 7 );
479 
480             if( strncmp( sBuf, "PCD_IPI", 7 ) ==  0 )
481             {
482                 rFormatExtension = UniString::CreateFromAscii( "PCD", 3 );
483                 return sal_True;
484             }
485         }
486     }
487 
488     //--------------------------- PSD ------------------------------------
489     if( !bTest || ( rFormatExtension.CompareToAscii( "PSD", 3 ) == COMPARE_EQUAL ) )
490     {
491         bSomethingTested = sal_True;
492         if ( ( nFirstLong == 0x38425053 ) && ( (nSecondLong >> 16 ) == 1 ) )
493         {
494             rFormatExtension = UniString::CreateFromAscii( "PSD", 3 );
495             return sal_True;
496         }
497     }
498 
499     //--------------------------- EPS ------------------------------------
500     if( !bTest || ( rFormatExtension.CompareToAscii( "EPS", 3 ) == COMPARE_EQUAL ) )
501     {
502         bSomethingTested = sal_True;
503         if ( ( nFirstLong == 0xC5D0D3C6 ) || ( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 ) &&
504              ImplSearchEntry( &sFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) )
505         {
506             rFormatExtension = UniString::CreateFromAscii( "EPS", 3 );
507             return sal_True;
508         }
509     }
510 
511     //--------------------------- DXF ------------------------------------
512     if( !bTest || ( rFormatExtension.CompareToAscii( "DXF", 3 ) == COMPARE_EQUAL ) )
513     {
514         bSomethingTested=sal_True;
515 
516         i=0;
517         while (i<256 && sFirstBytes[i]<=32)
518             i++;
519 
520         if (i<256)
521         {
522             if( sFirstBytes[i]=='0' )
523                 i++;
524             else
525                 i=256;
526         }
527         while( i<256 && sFirstBytes[i]<=32 )
528             i++;
529 
530         if (i+7<256)
531         {
532             if (strncmp((char*)(sFirstBytes+i),"SECTION",7)==0)
533             {
534                 rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
535                 return sal_True;
536             }
537         }
538 
539         if( strncmp( (char*) sFirstBytes, "AutoCAD Binary DXF", 18 ) == 0 )
540         {
541             rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
542             return sal_True;
543         }
544     }
545 
546     //--------------------------- PCT ------------------------------------
547     if( !bTest || ( rFormatExtension.CompareToAscii( "PCT", 3 ) == COMPARE_EQUAL ) )
548     {
549         bSomethingTested = sal_True;
550         sal_uInt8 sBuf[3];
551         // store number format
552         sal_uInt16 oldNumberFormat = rStream.GetNumberFormatInt();
553         sal_uInt32 nOffset; // in ms documents the pict format is used without the first 512 bytes
554         for ( nOffset = 0; ( nOffset <= 512 ) && ( ( nStreamPos + nOffset + 14 ) <= nStreamLen ); nOffset += 512 )
555         {
556             short y1,x1,y2,x2;
557             sal_Bool bdBoxOk = sal_True;
558 
559             rStream.Seek( nStreamPos + nOffset);
560             // size of the pict in version 1 pict ( 2bytes) : ignored
561             rStream.SeekRel(2);
562             // bounding box (bytes 2 -> 9)
563             rStream.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
564             rStream >> y1 >> x1 >> y2 >> x2;
565             rStream.SetNumberFormatInt(oldNumberFormat); // reset format
566 
567             if (x1 > x2 || y1 > y2 || // bad bdbox
568                 (x1 == x2 && y1 == y2) || // 1 pixel picture
569                 x2-x1 > 2048 || y2-y1 > 2048 ) // picture anormaly big
570               bdBoxOk = sal_False;
571 
572             // read version op
573             rStream.Read( sBuf,3 );
574             // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
575             // normal version 2 - page A23 and A24
576             if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x02)
577             {
578               rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
579               return sal_True;
580             }
581             // normal version 1 - page A25
582             else if (sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 && bdBoxOk) {
583               rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
584               return sal_True;
585             }
586             // previous code kept in order to do not break any compatibility
587             // probably eroneous
588             else if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x01 && bdBoxOk)
589             {
590               rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
591               return sal_True;
592             }
593         }
594     }
595 
596     //------------------------- PBM + PGM + PPM ---------------------------
597     if( !bTest ||
598         ( rFormatExtension.CompareToAscii( "PBM", 3 ) == COMPARE_EQUAL ) ||
599             ( rFormatExtension.CompareToAscii( "PGM", 3 ) == COMPARE_EQUAL ) ||
600                 ( rFormatExtension.CompareToAscii( "PPM", 3 ) == COMPARE_EQUAL ) )
601     {
602         bSomethingTested=sal_True;
603         if ( sFirstBytes[ 0 ] == 'P' )
604         {
605             switch( sFirstBytes[ 1 ] )
606             {
607                 case '1' :
608                 case '4' :
609                     rFormatExtension = UniString::CreateFromAscii( "PBM", 3 );
610                 return sal_True;
611 
612                 case '2' :
613                 case '5' :
614                     rFormatExtension = UniString::CreateFromAscii( "PGM", 3 );
615                 return sal_True;
616 
617                 case '3' :
618                 case '6' :
619                     rFormatExtension = UniString::CreateFromAscii( "PPM", 3 );
620                 return sal_True;
621             }
622         }
623     }
624 
625     //--------------------------- RAS( SUN RasterFile )------------------
626     if( !bTest || ( rFormatExtension.CompareToAscii( "RAS", 3 ) == COMPARE_EQUAL ) )
627     {
628         bSomethingTested=sal_True;
629         if( nFirstLong == 0x59a66a95 )
630         {
631             rFormatExtension = UniString::CreateFromAscii( "RAS", 3 );
632             return sal_True;
633         }
634     }
635 
636     //--------------------------- XPM ------------------------------------
637     if( !bTest )
638     {
639         bSomethingTested = sal_True;
640         if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"/* XPM */", 256, 9 ) )
641         {
642             rFormatExtension = UniString::CreateFromAscii( "XPM", 3 );
643             return sal_True;
644         }
645     }
646     else if( rFormatExtension.CompareToAscii( "XPM", 3 ) == COMPARE_EQUAL )
647     {
648         bSomethingTested = sal_True;
649         return sal_True;
650     }
651 
652     //--------------------------- XBM ------------------------------------
653     if( !bTest )
654     {
655         sal_uLong nSize = ( nStreamLen > 2048 ) ? 2048 : nStreamLen;
656         sal_uInt8* pBuf = new sal_uInt8 [ nSize ];
657 
658         rStream.Seek( nStreamPos );
659         rStream.Read( pBuf, nSize );
660         sal_uInt8* pPtr = ImplSearchEntry( pBuf, (sal_uInt8*)"#define", nSize, 7 );
661 
662         if( pPtr )
663         {
664             if( ImplSearchEntry( pPtr, (sal_uInt8*)"_width", pBuf + nSize - pPtr, 6 ) )
665             {
666                 rFormatExtension = UniString::CreateFromAscii( "XBM", 3 );
667                 delete[] pBuf;
668                 return sal_True;
669             }
670         }
671         delete[] pBuf;
672     }
673     else if( rFormatExtension.CompareToAscii( "XBM", 3 ) == COMPARE_EQUAL )
674     {
675         bSomethingTested = sal_True;
676         return sal_True;
677     }
678 
679     //--------------------------- SVG ------------------------------------
680     if( !bTest )
681     {
682         // check for Xml
683         if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<?xml", 256, 5 ) // is it xml
684             && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"version", 256, 7 )) // does it have a version (required for xml)
685         {
686             bool bIsSvg(false);
687 
688             // check for DOCTYPE svg combination
689             if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"DOCTYPE", 256, 7 ) // 'DOCTYPE' is there
690                 && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"svg", 256, 3 )) // 'svg' is there
691             {
692                 bIsSvg = true;
693             }
694 
695             // check for svg element in 1st 256 bytes
696             if(!bIsSvg && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg'
697             {
698                 bIsSvg = true;
699             }
700 
701             if(!bIsSvg)
702             {
703                 // it's a xml, look for '<svg' in full file. Should not happen too
704                 // often since the tests above will handle most cases, but can happen
705                 // with Svg files containing big comment headers or Svg as the host
706                 // language
707                 const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen);
708                 sal_uInt8* pBuf = new sal_uInt8[nSize];
709 
710                 rStream.Seek(nStreamPos);
711                 rStream.Read(pBuf, nSize);
712 
713                 if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg'
714                 {
715                     bIsSvg = true;
716                 }
717 
718                 delete[] pBuf;
719             }
720 
721             if(bIsSvg)
722             {
723                 rFormatExtension = UniString::CreateFromAscii( "SVG", 3 );
724                 return sal_True;
725             }
726         }
727         else
728         {
729             // #119176# Svg files which have no xml header at all have shown up,
730             // detect those, too
731             bool bIsSvg(false);
732 
733             // check for svg element in 1st 256 bytes
734             if(ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg'
735             {
736                 bIsSvg = true;
737             }
738 
739             if(!bIsSvg)
740             {
741                 // look for '<svg' in full file. Should not happen too
742                 // often since the tests above will handle most cases, but can happen
743                 // with Svg files containing big comment headers or Svg as the host
744                 // language
745                 const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen);
746                 sal_uInt8* pBuf = new sal_uInt8[nSize];
747 
748                 rStream.Seek(nStreamPos);
749                 rStream.Read(pBuf, nSize);
750 
751                 if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg'
752                 {
753                     bIsSvg = true;
754                 }
755 
756                 delete[] pBuf;
757             }
758 
759             if(bIsSvg)
760             {
761                 rFormatExtension = UniString::CreateFromAscii( "SVG", 3 );
762                 return sal_True;
763             }
764         }
765     }
766     else if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL )
767     {
768         bSomethingTested = sal_True;
769         return sal_True;
770     }
771 
772     //--------------------------- TGA ------------------------------------
773     if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) )
774     {
775         bSomethingTested = sal_True;
776 
777         // just a simple test for the extension
778         if( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL )
779             return sal_True;
780     }
781 
782     //--------------------------- SGV ------------------------------------
783     if( !bTest || ( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) )
784     {
785         bSomethingTested = sal_True;
786 
787         // just a simple test for the extension
788         if( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL )
789             return sal_True;
790     }
791 
792     //--------------------------- SGF ------------------------------------
793     if( !bTest || ( rFormatExtension.CompareToAscii( "SGF", 3 ) == COMPARE_EQUAL ) )
794     {
795         bSomethingTested=sal_True;
796         if( sFirstBytes[ 0 ] == 'J' && sFirstBytes[ 1 ] == 'J' )
797         {
798             rFormatExtension = UniString::CreateFromAscii( "SGF", 3 );
799             return sal_True;
800         }
801     }
802 
803     return bTest && !bSomethingTested;
804 }
805 
806 //--------------------------------------------------------------------------
807 
ImpTestOrFindFormat(const String & rPath,SvStream & rStream,sal_uInt16 & rFormat)808 sal_uInt16 GraphicFilter::ImpTestOrFindFormat( const String& rPath, SvStream& rStream, sal_uInt16& rFormat )
809 {
810     sal_uInt16 n = pConfig->GetImportFormatCount();
811 
812     // ggf. Filter bzw. Format durch anlesen ermitteln,
813     // oder durch anlesen zusichern, dass das Format stimmt:
814     if( rFormat == GRFILTER_FORMAT_DONTKNOW )
815     {
816         String aFormatExt;
817         if( ImpPeekGraphicFormat( rStream, aFormatExt, sal_False ) )
818         {
819             for( sal_uInt16 i = 0; i < n; i++ )
820             {
821                 if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aFormatExt ) )
822                 {
823                     rFormat = i;
824                     return GRFILTER_OK;
825                 }
826             }
827         }
828         // ggf. Filter anhand der Datei-Endung raussuchen:
829         if( rPath.Len() )
830         {
831             String aExt( ImpGetExtension( rPath ) );
832             for( sal_uInt16 i = 0; i < n; i++ )
833             {
834                 if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
835                 {
836                     rFormat = i;
837                     return GRFILTER_OK;
838                 }
839             }
840         }
841         return GRFILTER_FORMATERROR;
842     }
843     else
844     {
845         String aTmpStr( pConfig->GetImportFormatExtension( rFormat ) );
846         if( !ImpPeekGraphicFormat( rStream, aTmpStr, sal_True ) )
847             return GRFILTER_FORMATERROR;
848         if ( pConfig->GetImportFormatExtension( rFormat ).EqualsIgnoreCaseAscii( "pcd" ) )
849         {
850             sal_Int32 nBase = 2;    // default Base0
851             if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base4" ) )
852                 nBase = 1;
853             else if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base16" ) )
854                 nBase = 0;
855             String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
856             FilterConfigItem aFilterConfigItem( aFilterConfigPath );
857             aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
858         }
859     }
860 
861     return GRFILTER_OK;
862 }
863 
864 //--------------------------------------------------------------------------
865 
ImpGetScaledGraphic(const Graphic & rGraphic,FilterConfigItem & rConfigItem)866 static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem )
867 {
868     Graphic     aGraphic;
869     ByteString  aResMgrName( "svt", 3 );
870     ResMgr*     pResMgr;
871 
872     pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
873 
874     sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) ), 0 );
875     sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) ), 0 );
876 
877     if ( rGraphic.GetType() != GRAPHIC_NONE )
878     {
879         sal_Int32 nMode = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "ExportMode" ) ), -1 );
880 
881         if ( nMode == -1 )  // the property is not there, this is possible, if the graphic filter
882         {                   // is called via UnoGraphicExporter and not from a graphic export Dialog
883             nMode = 0;      // then we are defaulting this mode to 0
884             if ( nLogicalWidth || nLogicalHeight )
885                 nMode = 2;
886         }
887 
888 
889         Size aOriginalSize;
890         Size aPrefSize( rGraphic.GetPrefSize() );
891         MapMode aPrefMapMode( rGraphic.GetPrefMapMode() );
892         if ( aPrefMapMode == MAP_PIXEL )
893             aOriginalSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
894         else
895             aOriginalSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
896         if ( !nLogicalWidth )
897             nLogicalWidth = aOriginalSize.Width();
898         if ( !nLogicalHeight )
899             nLogicalHeight = aOriginalSize.Height();
900         if( rGraphic.GetType() == GRAPHIC_BITMAP )
901         {
902 
903             // Aufloesung wird eingestellt
904             if( nMode == 1 )
905             {
906                 Bitmap      aBitmap( rGraphic.GetBitmap() );
907                 MapMode     aMap( MAP_100TH_INCH );
908 
909                 sal_Int32   nDPI = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), 75 );
910                 Fraction    aFrac( 1, Min( Max( nDPI, sal_Int32( 75 ) ), sal_Int32( 600 ) ) );
911 
912                 aMap.SetScaleX( aFrac );
913                 aMap.SetScaleY( aFrac );
914 
915                 Size aOldSize = aBitmap.GetSizePixel();
916                 aGraphic = rGraphic;
917                 aGraphic.SetPrefMapMode( aMap );
918                 aGraphic.SetPrefSize( Size( aOldSize.Width() * 100,
919                                            aOldSize.Height() * 100 ) );
920             }
921             // Groesse wird eingestellt
922             else if( nMode == 2 )
923             {
924                 aGraphic = rGraphic;
925                 aGraphic.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
926                 aGraphic.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) );
927             }
928             else
929                 aGraphic = rGraphic;
930 
931             sal_Int32 nColors = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Color" ) ), 0 ); // #92767#
932             if ( nColors )  // graphic conversion necessary ?
933             {
934                 BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
935                 aBmpEx.Convert( (BmpConversion)nColors );   // the entries in the xml section have the same meaning as
936                 aGraphic = aBmpEx;                          // they have in the BmpConversion enum, so it should be
937             }                                               // allowed to cast them
938         }
939         else
940         {
941             if( ( nMode == 1 ) || ( nMode == 2 ) )
942             {
943                 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
944                 ::com::sun::star::awt::Size aDefaultSize( 10000, 10000 );
945                 Size aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth, nLogicalHeight ), MAP_100TH_MM, aMtf.GetPrefMapMode() ) );
946 
947                 if( aNewSize.Width() && aNewSize.Height() )
948                 {
949                     const Size aPreferredSize( aMtf.GetPrefSize() );
950                     aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ),
951                                 Fraction( aNewSize.Height(), aPreferredSize.Height() ) );
952                 }
953                 aGraphic = Graphic( aMtf );
954             }
955             else
956                 aGraphic = rGraphic;
957         }
958 
959     }
960     else
961         aGraphic = rGraphic;
962 
963     delete pResMgr;
964 
965     return aGraphic;
966 }
967 
ImpCreateFullFilterPath(const String & rPath,const String & rFilterName)968 static String ImpCreateFullFilterPath( const String& rPath, const String& rFilterName )
969 {
970     ::rtl::OUString aPathURL;
971 
972     ::osl::FileBase::getFileURLFromSystemPath( rPath, aPathURL );
973     aPathURL += String( '/' );
974 
975     ::rtl::OUString aSystemPath;
976     ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
977     aSystemPath += ::rtl::OUString( rFilterName );
978 
979     return String( aSystemPath );
980 }
981 
982 
983 // --------------------------
984 // - ImpFilterLibCacheEntry -
985 // --------------------------
986 
987 class ImpFilterLibCache;
988 
989 struct ImpFilterLibCacheEntry
990 {
991     ImpFilterLibCacheEntry* mpNext;
992     osl::Module             maLibrary;
993     String                  maFiltername;
994     PFilterCall             mpfnImport;
995     PFilterDlgCall          mpfnImportDlg;
996 
997                             ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername );
operator ==ImpFilterLibCacheEntry998     int                     operator==( const String& rFiltername ) const { return maFiltername == rFiltername; }
999 
1000     PFilterCall             GetImportFunction();
1001     PFilterDlgCall          GetImportDlgFunction();
GetExportFunctionImpFilterLibCacheEntry1002     PFilterCall             GetExportFunction() { return (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) ); }
GetExportDlgFunctionImpFilterLibCacheEntry1003     PFilterDlgCall          GetExportDlgFunction() { return (PFilterDlgCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) ); }
1004 };
1005 
1006 // ------------------------------------------------------------------------
1007 
ImpFilterLibCacheEntry(const String & rPathname,const String & rFiltername)1008 ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername ) :
1009         mpNext          ( NULL ),
1010         maLibrary       ( rPathname ),
1011         maFiltername    ( rFiltername ),
1012         mpfnImport      ( NULL ),
1013         mpfnImportDlg   ( NULL )
1014 {
1015 }
1016 
1017 // ------------------------------------------------------------------------
1018 
GetImportFunction()1019 PFilterCall ImpFilterLibCacheEntry::GetImportFunction()
1020 {
1021     if( !mpfnImport )
1022         mpfnImport = (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPORT_FUNCTION_NAME ) );
1023 
1024     return mpfnImport;
1025 }
1026 
1027 // ------------------------------------------------------------------------
1028 
GetImportDlgFunction()1029 PFilterDlgCall ImpFilterLibCacheEntry::GetImportDlgFunction()
1030 {
1031     if( !mpfnImportDlg )
1032         mpfnImportDlg = (PFilterDlgCall)maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPDLG_FUNCTION_NAME ) );
1033 
1034     return mpfnImportDlg;
1035 }
1036 
1037 // ---------------------
1038 // - ImpFilterLibCache -
1039 // ---------------------
1040 
1041 class ImpFilterLibCache
1042 {
1043     ImpFilterLibCacheEntry* mpFirst;
1044     ImpFilterLibCacheEntry* mpLast;
1045 
1046 public:
1047                             ImpFilterLibCache();
1048                             ~ImpFilterLibCache();
1049 
1050     ImpFilterLibCacheEntry* GetFilter( const String& rFilterPath, const String& rFiltername );
1051 };
1052 
1053 // ------------------------------------------------------------------------
1054 
ImpFilterLibCache()1055 ImpFilterLibCache::ImpFilterLibCache() :
1056     mpFirst     ( NULL ),
1057     mpLast      ( NULL )
1058 {
1059 }
1060 
1061 // ------------------------------------------------------------------------
1062 
~ImpFilterLibCache()1063 ImpFilterLibCache::~ImpFilterLibCache()
1064 {
1065     ImpFilterLibCacheEntry* pEntry = mpFirst;
1066     while( pEntry )
1067     {
1068         ImpFilterLibCacheEntry* pNext = pEntry->mpNext;
1069         delete pEntry;
1070         pEntry = pNext;
1071     }
1072 }
1073 
1074 // ------------------------------------------------------------------------
1075 
GetFilter(const String & rFilterPath,const String & rFilterName)1076 ImpFilterLibCacheEntry* ImpFilterLibCache::GetFilter( const String& rFilterPath, const String& rFilterName )
1077 {
1078     ImpFilterLibCacheEntry* pEntry = mpFirst;
1079 
1080     while( pEntry )
1081     {
1082         if( *pEntry == rFilterName )
1083             break;
1084         else
1085             pEntry = pEntry->mpNext;
1086     }
1087     if( !pEntry )
1088     {
1089         String aPhysicalName( ImpCreateFullFilterPath( rFilterPath, rFilterName ) );
1090         pEntry = new ImpFilterLibCacheEntry( aPhysicalName, rFilterName );
1091 
1092         if ( pEntry->maLibrary.is() )
1093         {
1094             if( !mpFirst )
1095                 mpFirst = mpLast = pEntry;
1096             else
1097                 mpLast = mpLast->mpNext = pEntry;
1098         }
1099         else
1100         {
1101             delete pEntry;
1102             pEntry = NULL;
1103         }
1104     }
1105     return pEntry;
1106 };
1107 
1108 // ------------------------------------------------------------------------
1109 
1110 namespace { struct Cache : public rtl::Static<ImpFilterLibCache, Cache> {}; }
1111 
1112 // -----------------
1113 // - GraphicFilter -
1114 // -----------------
1115 
GraphicFilter(sal_Bool bConfig)1116 GraphicFilter::GraphicFilter( sal_Bool bConfig ) :
1117     bUseConfig        ( bConfig ),
1118     nExpGraphHint     ( 0 )
1119 {
1120     ImplInit();
1121 }
1122 
1123 // ------------------------------------------------------------------------
1124 
~GraphicFilter()1125 GraphicFilter::~GraphicFilter()
1126 {
1127     {
1128         ::osl::MutexGuard aGuard( getListMutex() );
1129         pFilterHdlList->Remove( (void*)this );
1130         if ( !pFilterHdlList->Count() )
1131         {
1132             delete pFilterHdlList, pFilterHdlList = NULL;
1133             delete pConfig;
1134         }
1135     }
1136 
1137 
1138     delete pErrorEx;
1139 }
1140 
1141 // ------------------------------------------------------------------------
1142 
ImplInit()1143 void GraphicFilter::ImplInit()
1144 {
1145     {
1146         ::osl::MutexGuard aGuard( getListMutex() );
1147 
1148         if ( !pFilterHdlList )
1149         {
1150             pFilterHdlList = new List;
1151             pConfig = new FilterConfigCache( bUseConfig );
1152         }
1153         else
1154             pConfig = ((GraphicFilter*)pFilterHdlList->First())->pConfig;
1155 
1156         pFilterHdlList->Insert( (void*)this );
1157     }
1158 
1159     if( bUseConfig )
1160     {
1161         rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program"));
1162         rtl::Bootstrap::expandMacros(url); //TODO: detect failure
1163         utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath);
1164     }
1165 
1166     pErrorEx = new FilterErrorEx;
1167     bAbort = sal_False;
1168 }
1169 
1170 // ------------------------------------------------------------------------
1171 
ImplSetError(sal_uLong nError,const SvStream * pStm)1172 sal_uLong GraphicFilter::ImplSetError( sal_uLong nError, const SvStream* pStm )
1173 {
1174     pErrorEx->nFilterError = nError;
1175     pErrorEx->nStreamError = pStm ? pStm->GetError() : ERRCODE_NONE;
1176     return nError;
1177 }
1178 // ------------------------------------------------------------------------
1179 
GetImportFormatCount()1180 sal_uInt16 GraphicFilter::GetImportFormatCount()
1181 {
1182     return pConfig->GetImportFormatCount();
1183 }
1184 
1185 // ------------------------------------------------------------------------
1186 
GetImportFormatNumber(const String & rFormatName)1187 sal_uInt16 GraphicFilter::GetImportFormatNumber( const String& rFormatName )
1188 {
1189     return pConfig->GetImportFormatNumber( rFormatName );
1190 }
1191 
1192 // ------------------------------------------------------------------------
1193 
GetImportFormatNumberForMediaType(const String & rMediaType)1194 sal_uInt16 GraphicFilter::GetImportFormatNumberForMediaType( const String& rMediaType )
1195 {
1196     return pConfig->GetImportFormatNumberForMediaType( rMediaType );
1197 }
1198 
1199 // ------------------------------------------------------------------------
1200 
GetImportFormatNumberForShortName(const String & rShortName)1201 sal_uInt16 GraphicFilter::GetImportFormatNumberForShortName( const String& rShortName )
1202 {
1203     return pConfig->GetImportFormatNumberForShortName( rShortName );
1204 }
1205 
1206 // ------------------------------------------------------------------------
1207 
GetImportFormatNumberForTypeName(const String & rType)1208 sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( const String& rType )
1209 {
1210     return pConfig->GetImportFormatNumberForTypeName( rType );
1211 }
1212 
1213 // ------------------------------------------------------------------------
1214 
GetImportFormatName(sal_uInt16 nFormat)1215 String GraphicFilter::GetImportFormatName( sal_uInt16 nFormat )
1216 {
1217     return pConfig->GetImportFormatName( nFormat );
1218 }
1219 
1220 // ------------------------------------------------------------------------
1221 
GetImportFormatTypeName(sal_uInt16 nFormat)1222 String GraphicFilter::GetImportFormatTypeName( sal_uInt16 nFormat )
1223 {
1224     return pConfig->GetImportFilterTypeName( nFormat );
1225 }
1226 
1227 // ------------------------------------------------------------------------
1228 
GetImportFormatMediaType(sal_uInt16 nFormat)1229 String GraphicFilter::GetImportFormatMediaType( sal_uInt16 nFormat )
1230 {
1231     return pConfig->GetImportFormatMediaType( nFormat );
1232 }
1233 
1234 // ------------------------------------------------------------------------
1235 
GetImportFormatShortName(sal_uInt16 nFormat)1236 String GraphicFilter::GetImportFormatShortName( sal_uInt16 nFormat )
1237 {
1238     return pConfig->GetImportFormatShortName( nFormat );
1239 }
1240 
1241 // ------------------------------------------------------------------------
1242 
GetImportOSFileType(sal_uInt16)1243 String GraphicFilter::GetImportOSFileType( sal_uInt16 )
1244 {
1245     String aOSFileType;
1246     return aOSFileType;
1247 }
1248 
1249 // ------------------------------------------------------------------------
1250 
GetImportWildcard(sal_uInt16 nFormat,sal_Int32 nEntry)1251 String GraphicFilter::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
1252 {
1253     return pConfig->GetImportWildcard( nFormat, nEntry );
1254 }
1255 
1256 // ------------------------------------------------------------------------
1257 
IsImportPixelFormat(sal_uInt16 nFormat)1258 sal_Bool GraphicFilter::IsImportPixelFormat( sal_uInt16 nFormat )
1259 {
1260     return pConfig->IsImportPixelFormat( nFormat );
1261 }
1262 
1263 // ------------------------------------------------------------------------
1264 
GetExportFormatCount()1265 sal_uInt16 GraphicFilter::GetExportFormatCount()
1266 {
1267     return pConfig->GetExportFormatCount();
1268 }
1269 
1270 // ------------------------------------------------------------------------
1271 
GetExportFormatNumber(const String & rFormatName)1272 sal_uInt16 GraphicFilter::GetExportFormatNumber( const String& rFormatName )
1273 {
1274     return pConfig->GetExportFormatNumber( rFormatName );
1275 }
1276 
1277 // ------------------------------------------------------------------------
1278 
GetExportFormatNumberForMediaType(const String & rMediaType)1279 sal_uInt16 GraphicFilter::GetExportFormatNumberForMediaType( const String& rMediaType )
1280 {
1281     return pConfig->GetExportFormatNumberForMediaType( rMediaType );
1282 }
1283 
1284 // ------------------------------------------------------------------------
1285 
GetExportFormatNumberForShortName(const String & rShortName)1286 sal_uInt16 GraphicFilter::GetExportFormatNumberForShortName( const String& rShortName )
1287 {
1288     return pConfig->GetExportFormatNumberForShortName( rShortName );
1289 }
1290 
1291 // ------------------------------------------------------------------------
1292 
GetExportFormatNumberForTypeName(const String & rType)1293 sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( const String& rType )
1294 {
1295     return pConfig->GetExportFormatNumberForTypeName( rType );
1296 }
1297 
1298 // ------------------------------------------------------------------------
1299 
GetExportFormatName(sal_uInt16 nFormat)1300 String GraphicFilter::GetExportFormatName( sal_uInt16 nFormat )
1301 {
1302     return pConfig->GetExportFormatName( nFormat );
1303 }
1304 
1305 // ------------------------------------------------------------------------
1306 
GetExportFormatTypeName(sal_uInt16 nFormat)1307 String GraphicFilter::GetExportFormatTypeName( sal_uInt16 nFormat )
1308 {
1309     return pConfig->GetExportFilterTypeName( nFormat );
1310 }
1311 
1312 // ------------------------------------------------------------------------
1313 
GetExportFormatMediaType(sal_uInt16 nFormat)1314 String GraphicFilter::GetExportFormatMediaType( sal_uInt16 nFormat )
1315 {
1316     return pConfig->GetExportFormatMediaType( nFormat );
1317 }
1318 
1319 // ------------------------------------------------------------------------
1320 
GetExportFormatShortName(sal_uInt16 nFormat)1321 String GraphicFilter::GetExportFormatShortName( sal_uInt16 nFormat )
1322 {
1323     return pConfig->GetExportFormatShortName( nFormat );
1324 }
1325 
1326 // ------------------------------------------------------------------------
1327 
GetExportOSFileType(sal_uInt16)1328 String GraphicFilter::GetExportOSFileType( sal_uInt16 )
1329 {
1330     String aOSFileType;
1331     return aOSFileType;
1332 }
1333 
1334 // ------------------------------------------------------------------------
1335 
GetExportWildcard(sal_uInt16 nFormat,sal_Int32 nEntry)1336 String GraphicFilter::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
1337 {
1338     return pConfig->GetExportWildcard( nFormat, nEntry );
1339 }
1340 
1341 // ------------------------------------------------------------------------
1342 
IsExportPixelFormat(sal_uInt16 nFormat)1343 sal_Bool GraphicFilter::IsExportPixelFormat( sal_uInt16 nFormat )
1344 {
1345     return pConfig->IsExportPixelFormat( nFormat );
1346 }
1347 
1348 // ------------------------------------------------------------------------
1349 
CanImportGraphic(const INetURLObject & rPath,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat)1350 sal_uInt16 GraphicFilter::CanImportGraphic( const INetURLObject& rPath,
1351                                         sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
1352 {
1353     sal_uInt16  nRetValue = GRFILTER_FORMATERROR;
1354     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1355 
1356     String      aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1357     SvStream*   pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
1358     if ( pStream )
1359     {
1360         nRetValue = CanImportGraphic( aMainUrl, *pStream, nFormat, pDeterminedFormat );
1361         delete pStream;
1362     }
1363     return nRetValue;
1364 }
1365 
1366 // ------------------------------------------------------------------------
1367 
CanImportGraphic(const String & rMainUrl,SvStream & rIStream,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat)1368 sal_uInt16 GraphicFilter::CanImportGraphic( const String& rMainUrl, SvStream& rIStream,
1369                                         sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
1370 {
1371     sal_uLong nStreamPos = rIStream.Tell();
1372     sal_uInt16 nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat );
1373 
1374     rIStream.Seek(nStreamPos);
1375 
1376     if( nRes==GRFILTER_OK && pDeterminedFormat!=NULL )
1377         *pDeterminedFormat = nFormat;
1378 
1379     return (sal_uInt16) ImplSetError( nRes, &rIStream );
1380 }
1381 
1382 // ------------------------------------------------------------------------
1383 //SJ: TODO, we need to create a GraphicImporter component
ImportGraphic(Graphic & rGraphic,const INetURLObject & rPath,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat,sal_uInt32 nImportFlags)1384 sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
1385                                      sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, sal_uInt32 nImportFlags )
1386 {
1387     sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
1388     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1389 
1390     String      aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1391     SvStream*   pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
1392     if ( pStream )
1393     {
1394         nRetValue = ImportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pDeterminedFormat, nImportFlags );
1395         delete pStream;
1396     }
1397     return nRetValue;
1398 }
1399 
ImportGraphic(Graphic & rGraphic,const String & rPath,SvStream & rIStream,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat,sal_uInt32 nImportFlags)1400 sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
1401                                      sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags )
1402 {
1403     return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL );
1404 }
1405 
1406 //-------------------------------------------------------------------------
1407 
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)1408 sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
1409                                      sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags,
1410                                      com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData )
1411 {
1412     String                  aFilterName;
1413     sal_uLong                   nStmBegin;
1414     sal_uInt16                  nStatus;
1415     GraphicReader*          pContext = rGraphic.GetContext();
1416     GfxLinkType             eLinkType = GFX_LINK_TYPE_NONE;
1417     sal_Bool                    bDummyContext = ( pContext == (GraphicReader*) 1 );
1418     const sal_Bool              bLinkSet = rGraphic.IsLink();
1419     FilterConfigItem*       pFilterConfigItem = NULL;
1420 
1421     Size                    aPreviewSizeHint( 0, 0 );
1422     sal_Bool                bAllowPartialStreamRead = sal_False;
1423     sal_Bool                bCreateNativeLink = sal_True;
1424 
1425     ResetLastError();
1426 
1427     if ( pFilterData )
1428     {
1429         sal_Int32 i;
1430         for ( i = 0; i < pFilterData->getLength(); i++ )
1431         {
1432             if ( (*pFilterData)[ i ].Name.equalsAscii( "PreviewSizeHint" ) )
1433             {
1434                 awt::Size aSize;
1435                 if ( (*pFilterData)[ i ].Value >>= aSize )
1436                 {
1437                     aPreviewSizeHint = Size( aSize.Width, aSize.Height );
1438                     if ( aSize.Width || aSize.Height )
1439                         nImportFlags |= GRFILTER_I_FLAGS_FOR_PREVIEW;
1440                     else
1441                         nImportFlags &=~GRFILTER_I_FLAGS_FOR_PREVIEW;
1442                 }
1443             }
1444             else if ( (*pFilterData)[ i ].Name.equalsAscii( "AllowPartialStreamRead" ) )
1445             {
1446                 (*pFilterData)[ i ].Value >>= bAllowPartialStreamRead;
1447                 if ( bAllowPartialStreamRead )
1448                     nImportFlags |= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
1449                 else
1450                     nImportFlags &=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
1451             }
1452             else if ( (*pFilterData)[ i ].Name.equalsAscii( "CreateNativeLink" ) )
1453             {
1454                 (*pFilterData)[ i ].Value >>= bCreateNativeLink;
1455             }
1456         }
1457     }
1458 
1459     if( !pContext || bDummyContext )
1460     {
1461         if( bDummyContext )
1462         {
1463             rGraphic.SetContext( NULL );
1464             nStmBegin = 0;
1465         }
1466         else
1467             nStmBegin = rIStream.Tell();
1468 
1469         bAbort = sal_False;
1470         nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat );
1471         // Falls Pending, geben wir GRFILTER_OK zurueck,
1472         // um mehr Bytes anzufordern
1473         if( rIStream.GetError() == ERRCODE_IO_PENDING )
1474         {
1475             rGraphic.SetContext( (GraphicReader*) 1 );
1476             rIStream.ResetError();
1477             rIStream.Seek( nStmBegin );
1478             return (sal_uInt16) ImplSetError( GRFILTER_OK );
1479         }
1480 
1481         rIStream.Seek( nStmBegin );
1482 
1483         if( ( nStatus != GRFILTER_OK ) || rIStream.GetError() )
1484             return (sal_uInt16) ImplSetError( ( nStatus != GRFILTER_OK ) ? nStatus : GRFILTER_OPENERROR, &rIStream );
1485 
1486         if( pDeterminedFormat )
1487             *pDeterminedFormat = nFormat;
1488 
1489         aFilterName = pConfig->GetImportFilterName( nFormat );
1490     }
1491     else
1492     {
1493         if( pContext && !bDummyContext )
1494             aFilterName = pContext->GetUpperFilterName();
1495 
1496         nStmBegin = 0;
1497         nStatus = GRFILTER_OK;
1498     }
1499 
1500     // read graphic
1501     if ( pConfig->IsImportInternalFilter( nFormat ) )
1502     {
1503         if( aFilterName.EqualsIgnoreCaseAscii( IMP_GIF )  )
1504         {
1505             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1506                 rGraphic.SetContext( NULL );
1507 
1508             if( !ImportGIF( rIStream, rGraphic ) )
1509                 nStatus = GRFILTER_FILTERERROR;
1510             else
1511                 eLinkType = GFX_LINK_TYPE_NATIVE_GIF;
1512         }
1513         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_PNG ) )
1514         {
1515             if ( rGraphic.GetContext() == (GraphicReader*) 1 )
1516                 rGraphic.SetContext( NULL );
1517 
1518             vcl::PNGReader aPNGReader( rIStream );
1519 
1520             // ignore animation for previews and set preview size
1521             if( aPreviewSizeHint.Width() || aPreviewSizeHint.Height() )
1522             {
1523                 // position the stream at the end of the image if requested
1524                 if( !bAllowPartialStreamRead )
1525                     aPNGReader.GetChunks();
1526             }
1527             else
1528             {
1529                 // check if this PNG contains a GIF chunk!
1530                 const std::vector< vcl::PNGReader::ChunkData >&    rChunkData = aPNGReader.GetChunks();
1531                 std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() );
1532                 std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() );
1533                 while( aIter != aEnd )
1534                 {
1535                     // Microsoft Office is storing Animated GIFs in following chunk
1536                     if ( aIter->nType == PMGCHUNG_msOG )
1537                     {
1538                         sal_uInt32 nChunkSize = aIter->aData.size();
1539                         if ( nChunkSize > 11 )
1540                         {
1541                             const std::vector< sal_uInt8 >& rData = aIter->aData;
1542                             SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, STREAM_READ );
1543                             ImportGIF( aIStrm, rGraphic );
1544                             eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
1545                             break;
1546                         }
1547                     }
1548                     aIter++;
1549                 }
1550             }
1551 
1552             if ( eLinkType == GFX_LINK_TYPE_NONE )
1553             {
1554                 BitmapEx aBmpEx( aPNGReader.Read( aPreviewSizeHint ) );
1555                 if ( aBmpEx.IsEmpty() )
1556                     nStatus = GRFILTER_FILTERERROR;
1557                 else
1558                 {
1559                     rGraphic = aBmpEx;
1560                     eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
1561                 }
1562             }
1563         }
1564         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_JPEG ) )
1565         {
1566             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1567                 rGraphic.SetContext( NULL );
1568 
1569             // set LOGSIZE flag always, if not explicitly disabled
1570             // (see #90508 and #106763)
1571             if( 0 == ( nImportFlags & GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG ) )
1572                 nImportFlags |= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
1573 
1574             if( !ImportJPEG( rIStream, rGraphic, NULL, nImportFlags ) )
1575                 nStatus = GRFILTER_FILTERERROR;
1576             else
1577                 eLinkType = GFX_LINK_TYPE_NATIVE_JPG;
1578         }
1579         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVG ) )
1580         {
1581             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1582                 rGraphic.SetContext( NULL );
1583 
1584             const sal_uInt32 nStmPos(rIStream.Tell());
1585             const sal_uInt32 nStmLen(rIStream.Seek(STREAM_SEEK_TO_END) - nStmPos);
1586             bool bOkay(false);
1587 
1588             if(nStmLen)
1589             {
1590                 SvgDataArray aNewData(new sal_uInt8[nStmLen]);
1591 
1592                 rIStream.Seek(nStmPos);
1593                 rIStream.Read(aNewData.get(), nStmLen);
1594 
1595                 if(!rIStream.GetError())
1596                 {
1597                     SvgDataPtr aSvgDataPtr(
1598                         new SvgData(
1599                             aNewData,
1600                             nStmLen,
1601                             rPath));
1602 
1603                     rGraphic = Graphic(aSvgDataPtr);
1604                     bOkay = true;
1605                 }
1606             }
1607 
1608             if(bOkay)
1609             {
1610                 eLinkType = GFX_LINK_TYPE_NATIVE_SVG;
1611             }
1612             else
1613             {
1614                 nStatus = GRFILTER_FILTERERROR;
1615             }
1616         }
1617         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) )
1618         {
1619             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1620                 rGraphic.SetContext( NULL );
1621 
1622             if( !ImportXBM( rIStream, rGraphic ) )
1623                 nStatus = GRFILTER_FILTERERROR;
1624         }
1625         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XPM ) )
1626         {
1627             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1628                 rGraphic.SetContext( NULL );
1629 
1630             if( !ImportXPM( rIStream, rGraphic ) )
1631                 nStatus = GRFILTER_FILTERERROR;
1632         }
1633         else if ( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP )
1634                   || aFilterName.EqualsIgnoreCaseAscii( IMP_SVMETAFILE ) )
1635         {
1636             // SV interne Importfilter fuer Bitmaps und MetaFiles
1637             rIStream >> rGraphic;
1638 
1639             if( rIStream.GetError() )
1640             {
1641                 nStatus = GRFILTER_FORMATERROR;
1642             }
1643             else
1644             {
1645                 if ( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP ) )
1646                 {
1647                     // #15508# added BMP type (checked, works)
1648                     eLinkType = GFX_LINK_TYPE_NATIVE_BMP;
1649                 }
1650             }
1651         }
1652         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_WMF ) ||
1653                 aFilterName.EqualsIgnoreCaseAscii( IMP_EMF ) )
1654         {
1655             GDIMetaFile aMtf;
1656             if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL ) )
1657                 nStatus = GRFILTER_FORMATERROR;
1658             else
1659             {
1660                 rGraphic = aMtf;
1661                 eLinkType = GFX_LINK_TYPE_NATIVE_WMF;
1662             }
1663         }
1664         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGF )
1665                 || aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGV ) )
1666         {
1667             sal_uInt16          nVersion;
1668             unsigned char   nTyp = CheckSgfTyp( rIStream, nVersion );
1669 
1670             switch( nTyp )
1671             {
1672                 case SGF_BITIMAGE:
1673                 {
1674                     SvMemoryStream aTempStream;
1675                     if( aTempStream.GetError() )
1676                         return GRFILTER_OPENERROR;
1677 
1678                     if( !SgfBMapFilter( rIStream, aTempStream ) )
1679                         nStatus = GRFILTER_FILTERERROR;
1680                     else
1681                     {
1682                         aTempStream.Seek( 0L );
1683                         aTempStream >> rGraphic;
1684 
1685                         if( aTempStream.GetError() )
1686                             nStatus = GRFILTER_FILTERERROR;
1687                     }
1688                 }
1689                 break;
1690 
1691                 case SGF_SIMPVECT:
1692                 {
1693                     GDIMetaFile aMtf;
1694                     if( !SgfVectFilter( rIStream, aMtf ) )
1695                         nStatus = GRFILTER_FILTERERROR;
1696                     else
1697                         rGraphic = Graphic( aMtf );
1698                 }
1699                 break;
1700 
1701                 case SGF_STARDRAW:
1702                 {
1703                     if( nVersion != SGV_VERSION )
1704                         nStatus = GRFILTER_VERSIONERROR;
1705                     else
1706                     {
1707                         GDIMetaFile aMtf;
1708                         if( !SgfSDrwFilter( rIStream, aMtf,
1709                                 INetURLObject(aFilterPath) ) )
1710                         {
1711                             nStatus = GRFILTER_FILTERERROR;
1712                         }
1713                         else
1714                             rGraphic = Graphic( aMtf );
1715                     }
1716                 }
1717                 break;
1718 
1719                 default:
1720                 {
1721                     nStatus = GRFILTER_FORMATERROR;
1722                 }
1723                 break;
1724             }
1725         }
1726         else
1727             nStatus = GRFILTER_FILTERERROR;
1728     }
1729     else
1730     {
1731         ImpFilterLibCacheEntry* pFilter = NULL;
1732 
1733         // find first filter in filter pathes
1734         xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
1735         ImpFilterLibCache &rCache = Cache::get();
1736         for( i = 0; ( i < nTokenCount ) && ( pFilter == NULL ); i++ )
1737             pFilter = rCache.GetFilter( aFilterPath.GetToken(i), aFilterName );
1738         if( !pFilter )
1739             nStatus = GRFILTER_FILTERERROR;
1740         else
1741         {
1742             PFilterCall pFunc = pFilter->GetImportFunction();
1743 
1744             if( !pFunc )
1745                 nStatus = GRFILTER_FILTERERROR;
1746             else
1747             {
1748                 String aShortName;
1749                 if( nFormat != GRFILTER_FORMAT_DONTKNOW )
1750                 {
1751                     aShortName = GetImportFormatShortName( nFormat ).ToUpperAscii();
1752                     if ( ( pFilterConfigItem == NULL ) && aShortName.EqualsAscii( "PCD" ) )
1753                     {
1754                         String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
1755                         pFilterConfigItem = new FilterConfigItem( aFilterConfigPath );
1756                     }
1757                 }
1758                 if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem, sal_False ) )
1759                     nStatus = GRFILTER_FORMATERROR;
1760                 else
1761                 {
1762                     // try to set link type if format matches
1763                     if( nFormat != GRFILTER_FORMAT_DONTKNOW )
1764                     {
1765                         if( aShortName.CompareToAscii( TIF_SHORTNAME ) == COMPARE_EQUAL )
1766                             eLinkType = GFX_LINK_TYPE_NATIVE_TIF;
1767                         else if( aShortName.CompareToAscii( MET_SHORTNAME ) == COMPARE_EQUAL )
1768                             eLinkType = GFX_LINK_TYPE_NATIVE_MET;
1769                         else if( aShortName.CompareToAscii( PCT_SHORTNAME ) == COMPARE_EQUAL )
1770                             eLinkType = GFX_LINK_TYPE_NATIVE_PCT;
1771                     }
1772                 }
1773             }
1774         }
1775     }
1776 
1777     if( nStatus == GRFILTER_OK && bCreateNativeLink && ( eLinkType != GFX_LINK_TYPE_NONE ) && !rGraphic.GetContext() && !bLinkSet )
1778     {
1779         const sal_uLong nStmEnd = rIStream.Tell();
1780         const sal_uLong nBufSize = nStmEnd - nStmBegin;
1781 
1782         if( nBufSize )
1783         {
1784             sal_uInt8*  pBuf=0;
1785             try
1786             {
1787                 pBuf = new sal_uInt8[ nBufSize ];
1788             }
1789                 catch (std::bad_alloc)
1790             {
1791                 nStatus = GRFILTER_TOOBIG;
1792             }
1793 
1794             if( nStatus == GRFILTER_OK )
1795             {
1796                 rIStream.Seek( nStmBegin );
1797                 rIStream.Read( pBuf, nBufSize );
1798                 rGraphic.SetLink( GfxLink( pBuf, nBufSize, eLinkType, sal_True ) );
1799             }
1800         }
1801     }
1802 
1803     // Set error code or try to set native buffer
1804     if( nStatus != GRFILTER_OK )
1805     {
1806         if( bAbort )
1807             nStatus = GRFILTER_ABORT;
1808 
1809         ImplSetError( nStatus, &rIStream );
1810         rIStream.Seek( nStmBegin );
1811         rGraphic.Clear();
1812     }
1813 
1814     delete pFilterConfigItem;
1815     return nStatus;
1816 }
1817 
1818 
1819 // ------------------------------------------------------------------------
1820 
ExportGraphic(const Graphic & rGraphic,const INetURLObject & rPath,sal_uInt16 nFormat,const uno::Sequence<beans::PropertyValue> * pFilterData)1821 sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
1822     sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
1823 {
1824     sal_uInt16  nRetValue = GRFILTER_FORMATERROR;
1825     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1826     sal_Bool        bAlreadyExists = ImplDirEntryHelper::Exists( rPath );
1827 
1828     String      aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1829     SvStream*   pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_WRITE | STREAM_TRUNC );
1830     if ( pStream )
1831     {
1832         nRetValue = ExportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pFilterData );
1833         delete pStream;
1834 
1835         if( ( GRFILTER_OK != nRetValue ) && !bAlreadyExists )
1836             ImplDirEntryHelper::Kill( aMainUrl );
1837     }
1838     return nRetValue;
1839 }
1840 
1841 // ------------------------------------------------------------------------
1842 
ExportGraphic(const Graphic & rGraphic,const String & rPath,SvStream & rOStm,sal_uInt16 nFormat,const uno::Sequence<beans::PropertyValue> * pFilterData)1843 sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& rPath,
1844     SvStream& rOStm, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
1845 {
1846     sal_uInt16 nFormatCount = GetExportFormatCount();
1847 
1848     ResetLastError();
1849     nExpGraphHint = 0;
1850 
1851     if( nFormat == GRFILTER_FORMAT_DONTKNOW )
1852     {
1853         INetURLObject aURL( rPath );
1854         String aExt( aURL.GetFileExtension().toAsciiUpperCase() );
1855 
1856 
1857         for( sal_uInt16 i = 0; i < nFormatCount; i++ )
1858         {
1859             if ( pConfig->GetExportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
1860             {
1861                 nFormat=i;
1862                 break;
1863             }
1864         }
1865     }
1866     if( nFormat >= nFormatCount )
1867         return (sal_uInt16) ImplSetError( GRFILTER_FORMATERROR );
1868 
1869     FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
1870     String aFilterName( pConfig->GetExportFilterName( nFormat ) );
1871 
1872     bAbort              = sal_False;
1873     sal_uInt16      nStatus = GRFILTER_OK;
1874     GraphicType eType;
1875     Graphic     aGraphic( rGraphic );
1876 
1877     aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem );
1878     eType = aGraphic.GetType();
1879 
1880     if( pConfig->IsExportPixelFormat( nFormat ) )
1881     {
1882         if( eType != GRAPHIC_BITMAP )
1883         {
1884             Size aSizePixel;
1885             sal_uLong nColorCount,nBitsPerPixel,nNeededMem,nMaxMem;
1886             VirtualDevice aVirDev;
1887 
1888             // Maximalen Speicherbedarf fuer das Bildes holen:
1889 //          if( GetOptionsConfig() )
1890 //              nMaxMem = (UINT32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32();
1891 //          else
1892                 nMaxMem = 1024;
1893 
1894             nMaxMem *= 1024; // In Bytes
1895 
1896             // Berechnen, wie gross das Bild normalerweise werden wuerde:
1897             aSizePixel=aVirDev.LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode());
1898 
1899             // Berechnen, wieviel Speicher das Bild benoetigen wuerde:
1900             nColorCount=aVirDev.GetColorCount();
1901             if      (nColorCount<=2)     nBitsPerPixel=1;
1902             else if (nColorCount<=4)     nBitsPerPixel=2;
1903             else if (nColorCount<=16)    nBitsPerPixel=4;
1904             else if (nColorCount<=256)   nBitsPerPixel=8;
1905             else if (nColorCount<=65536) nBitsPerPixel=16;
1906             else                         nBitsPerPixel=24;
1907             nNeededMem=((sal_uLong)aSizePixel.Width()*(sal_uLong)aSizePixel.Height()*nBitsPerPixel+7)/8;
1908 
1909             // ggf. Groesse des Bildes einschraenken:
1910             if (nMaxMem<nNeededMem)
1911             {
1912                 double fFak=sqrt(((double)nMaxMem)/((double)nNeededMem));
1913                 aSizePixel.Width()=(sal_uLong)(((double)aSizePixel.Width())*fFak);
1914                 aSizePixel.Height()=(sal_uLong)(((double)aSizePixel.Height())*fFak);
1915             }
1916 
1917             aVirDev.SetMapMode(MapMode(MAP_PIXEL));
1918             aVirDev.SetOutputSizePixel(aSizePixel);
1919             Graphic aGraphic2=aGraphic;
1920             aGraphic2.Draw(&aVirDev,Point(0,0),aSizePixel); // Gemein: dies aendert den MapMode
1921             aVirDev.SetMapMode(MapMode(MAP_PIXEL));
1922             aGraphic=Graphic(aVirDev.GetBitmap(Point(0,0),aSizePixel));
1923         }
1924     }
1925     if( rOStm.GetError() )
1926         nStatus = GRFILTER_IOERROR;
1927     if( GRFILTER_OK == nStatus )
1928     {
1929         if ( pConfig->IsExportInternalFilter( nFormat ) )
1930         {
1931             if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
1932             {
1933                 Bitmap aBmp( aGraphic.GetBitmap() );
1934                 sal_Int32 nColorRes = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Colors" ) ), 0 );
1935                 if ( nColorRes && ( nColorRes <= (sal_uInt16)BMP_CONVERSION_24BIT) )
1936                 {
1937                     if( !aBmp.Convert( (BmpConversion) nColorRes ) )
1938                         aBmp = aGraphic.GetBitmap();
1939                 }
1940                 ResMgr*     pResMgr = CREATERESMGR( svt );
1941                 sal_Bool    bRleCoding = aConfigItem.ReadBool( String( RTL_CONSTASCII_USTRINGPARAM( "RLE_Coding" ) ), sal_True );
1942                 // Wollen wir RLE-Kodiert speichern?
1943                 WriteDIB(aBmp, rOStm, bRleCoding, true);
1944                 delete pResMgr;
1945 
1946                 if( rOStm.GetError() )
1947                     nStatus = GRFILTER_IOERROR;
1948             }
1949             else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) )
1950             {
1951                 sal_Int32 nVersion = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), 0 ) ;
1952                 if ( nVersion )
1953                     rOStm.SetVersion( nVersion );
1954 
1955                 // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1956                 GDIMetaFile aMTF(aGraphic.GetGDIMetaFile());
1957 
1958                 aMTF.Write( rOStm );
1959 
1960                 if( rOStm.GetError() )
1961                     nStatus = GRFILTER_IOERROR;
1962             }
1963             else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) )
1964             {
1965                 // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1966                 if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
1967                     nStatus = GRFILTER_FORMATERROR;
1968 
1969                 if( rOStm.GetError() )
1970                     nStatus = GRFILTER_IOERROR;
1971             }
1972             else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) )
1973             {
1974                 // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1975                 if ( !ConvertGDIMetaFileToEMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
1976                     nStatus = GRFILTER_FORMATERROR;
1977 
1978                 if( rOStm.GetError() )
1979                     nStatus = GRFILTER_IOERROR;
1980             }
1981             else if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
1982             {
1983                 bool bExportedGrayJPEG = false;
1984                 if( !ExportJPEG( rOStm, aGraphic, pFilterData, &bExportedGrayJPEG ) )
1985                     nStatus = GRFILTER_FORMATERROR;
1986                 nExpGraphHint = bExportedGrayJPEG ? GRFILTER_OUTHINT_GREY : 0;
1987 
1988                 if( rOStm.GetError() )
1989                     nStatus = GRFILTER_IOERROR;
1990             }
1991             else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
1992             {
1993                 vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData );
1994                 if ( pFilterData )
1995                 {
1996                     sal_Int32 k, j, i = 0;
1997                     for ( i = 0; i < pFilterData->getLength(); i++ )
1998                     {
1999                         if ( (*pFilterData)[ i ].Name.equalsAscii( "AdditionalChunks" ) )
2000                         {
2001                             com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence;
2002                             if ( (*pFilterData)[ i ].Value >>= aAdditionalChunkSequence )
2003                             {
2004                                 for ( j = 0; j < aAdditionalChunkSequence.getLength(); j++ )
2005                                 {
2006                                     if ( aAdditionalChunkSequence[ j ].Name.getLength() == 4 )
2007                                     {
2008                                         sal_uInt32 nChunkType = 0;
2009                                         for ( k = 0; k < 4; k++ )
2010                                         {
2011                                             nChunkType <<= 8;
2012                                             nChunkType |= (sal_uInt8)aAdditionalChunkSequence[ j ].Name[ k ];
2013                                         }
2014                                         com::sun::star::uno::Sequence< sal_Int8 > aByteSeq;
2015                                         if ( aAdditionalChunkSequence[ j ].Value >>= aByteSeq )
2016                                         {
2017                                             std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks();
2018                                             if ( rChunkData.size() )
2019                                             {
2020                                                 sal_uInt32 nChunkLen = aByteSeq.getLength();
2021 
2022                                                 vcl::PNGWriter::ChunkData aChunkData;
2023                                                 aChunkData.nType = nChunkType;
2024                                                 if ( nChunkLen )
2025                                                 {
2026                                                     aChunkData.aData.resize( nChunkLen );
2027                                                     rtl_copyMemory( &aChunkData.aData[ 0 ], aByteSeq.getConstArray(), nChunkLen );
2028                                                 }
2029                                                 std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1;
2030                                                 rChunkData.insert( aIter, aChunkData );
2031                                             }
2032                                         }
2033                                     }
2034                                 }
2035                             }
2036                         }
2037                     }
2038                 }
2039                 aPNGWriter.Write( rOStm );
2040 
2041                 if( rOStm.GetError() )
2042                     nStatus = GRFILTER_IOERROR;
2043             }
2044             else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) )
2045             {
2046                 bool bDone(false);
2047 
2048                 // do we have a native SVG RenderGraphic, whose data can be written directly?
2049                 const SvgDataPtr aSvgDataPtr(rGraphic.getSvgData());
2050 
2051                 if(aSvgDataPtr.get() && aSvgDataPtr->getSvgDataArrayLength())
2052                 {
2053                     rOStm.Write(aSvgDataPtr->getSvgDataArray().get(), aSvgDataPtr->getSvgDataArrayLength());
2054 
2055                     if( rOStm.GetError() )
2056                     {
2057                         nStatus = GRFILTER_IOERROR;
2058                     }
2059                     else
2060                     {
2061                         bDone = true;
2062                     }
2063                 }
2064 
2065                 if( !bDone )
2066                 {
2067                     // do the normal GDIMetaFile export instead
2068                     try
2069                     {
2070                         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2071 
2072                         if( xMgr.is() )
2073                         {
2074                             ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance(
2075                                 ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), ::com::sun::star::uno::UNO_QUERY );
2076 
2077                             com::sun::star::uno::Sequence< com::sun::star::uno::Any > aArguments( 1 );
2078                             aArguments[ 0 ] <<= aConfigItem.GetFilterData();
2079                             ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstanceWithArguments(
2080                                 ::rtl::OUString::createFromAscii( "com.sun.star.svg.SVGWriter" ), aArguments ), ::com::sun::star::uno::UNO_QUERY );
2081 
2082                             if( xSaxWriter.is() && xSVGWriter.is() )
2083                             {
2084                                 ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource(
2085                                     xSaxWriter, ::com::sun::star::uno::UNO_QUERY );
2086 
2087                                 if( xActiveDataSource.is() )
2088                                 {
2089                                     const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf(
2090                                         static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) );
2091 
2092                                     SvMemoryStream aMemStm( 65535, 65535 );
2093 
2094                                     aMemStm.SetCompressMode( COMPRESSMODE_FULL );
2095 
2096                                     // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
2097                                     ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm );
2098 
2099                                     xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >(
2100                                         xStmIf, ::com::sun::star::uno::UNO_QUERY ) );
2101                                     ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() );
2102                                     xSVGWriter->write( xSaxWriter, aMtfSeq );
2103                                 }
2104                             }
2105                         }
2106                     }
2107                     catch( ::com::sun::star::uno::Exception& )
2108                     {
2109                         nStatus = GRFILTER_IOERROR;
2110                     }
2111                 }
2112             }
2113             else
2114                 nStatus = GRFILTER_FILTERERROR;
2115         }
2116         else
2117         {
2118             xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
2119             for ( i = 0; i < nTokenCount; i++ )
2120             {
2121                 String aPhysicalName( ImpCreateFullFilterPath( aFilterPath.GetToken( i ), aFilterName ) );
2122                 osl::Module aLibrary( aPhysicalName );
2123 
2124                 PFilterCall pFunc = (PFilterCall) aLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) );
2125                 // Dialog in DLL ausfuehren
2126                 if( pFunc )
2127                 {
2128                     if ( !(*pFunc)( rOStm, aGraphic, &aConfigItem, sal_False ) )
2129                         nStatus = GRFILTER_FORMATERROR;
2130                     break;
2131                 }
2132                 else
2133                     nStatus = GRFILTER_FILTERERROR;
2134             }
2135         }
2136     }
2137     if( nStatus != GRFILTER_OK )
2138     {
2139         if( bAbort )
2140             nStatus = GRFILTER_ABORT;
2141 
2142         ImplSetError( nStatus, &rOStm );
2143     }
2144     return nStatus;
2145 }
2146 
2147 // ------------------------------------------------------------------------
2148 
Setup(sal_uInt16)2149 sal_Bool GraphicFilter::Setup( sal_uInt16 )
2150 {
2151     return sal_False;
2152 }
2153 
2154 /* ------------------------------------------------------------------------
2155     No Import filter has a dialog, so
2156    the following two methods are obsolete */
2157 
HasImportDialog(sal_uInt16)2158 sal_Bool GraphicFilter::HasImportDialog( sal_uInt16 )
2159 {
2160     return sal_True;
2161 //  return pConfig->IsImportDialog( nFormat );
2162 }
2163 
2164 // ------------------------------------------------------------------------
2165 
DoImportDialog(Window *,sal_uInt16)2166 sal_Bool GraphicFilter::DoImportDialog( Window*, sal_uInt16 )
2167 {
2168     return sal_True;
2169 }
2170 
2171 // ------------------------------------------------------------------------
2172 
HasExportDialog(sal_uInt16 nFormat)2173 sal_Bool GraphicFilter::HasExportDialog( sal_uInt16 nFormat )
2174 {
2175     return pConfig->IsExportDialog( nFormat );
2176 }
2177 
2178 // ------------------------------------------------------------------------
2179 
DoExportDialog(Window * pWindow,sal_uInt16 nFormat)2180 sal_Bool GraphicFilter::DoExportDialog( Window* pWindow, sal_uInt16 nFormat )
2181 {
2182     return DoExportDialog( pWindow, nFormat, FUNIT_MM );
2183 }
2184 
DoExportDialog(Window *,sal_uInt16 nFormat,FieldUnit)2185 sal_Bool GraphicFilter::DoExportDialog( Window*, sal_uInt16 nFormat, FieldUnit )
2186 {
2187     sal_Bool bRet = sal_False;
2188     com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
2189         xSMgr( ::comphelper::getProcessServiceFactory() );
2190 
2191     uno::Reference< com::sun::star::uno::XInterface > xFilterOptionsDialog
2192         ( xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.svtools.SvFilterOptionsDialog" ) ),
2193             com::sun::star::uno::UNO_QUERY );
2194     if ( xFilterOptionsDialog.is() )
2195     {
2196         com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XExecutableDialog > xExecutableDialog
2197             ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
2198         com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xPropertyAccess
2199             ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
2200         if ( xExecutableDialog.is() && xPropertyAccess.is() )
2201         {
2202             com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aMediaDescriptor( 1 );
2203             aMediaDescriptor[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
2204             rtl::OUString aStr( pConfig->GetExportInternalFilterName( nFormat ) );
2205             aMediaDescriptor[ 0 ].Value <<= aStr;
2206             xPropertyAccess->setPropertyValues( aMediaDescriptor );
2207             bRet = xExecutableDialog->execute() == com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
2208         }
2209     }
2210     return bRet;
2211 }
2212 
2213 // ------------------------------------------------------------------------
2214 
GetLastError() const2215 const FilterErrorEx& GraphicFilter::GetLastError() const
2216 {
2217     return *pErrorEx;
2218 }
2219 
2220 // ------------------------------------------------------------------------
2221 
ResetLastError()2222 void GraphicFilter::ResetLastError()
2223 {
2224     pErrorEx->nFilterError = pErrorEx->nStreamError = 0UL;
2225 }
2226 
2227 // ------------------------------------------------------------------------
2228 
GetFilterCallback() const2229 const Link GraphicFilter::GetFilterCallback() const
2230 {
2231     const Link aLink( LINK( this, GraphicFilter, FilterCallback ) );
2232     return aLink;
2233 }
2234 
2235 // ------------------------------------------------------------------------
2236 
IMPL_LINK(GraphicFilter,FilterCallback,ConvertData *,pData)2237 IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData )
2238 {
2239     long nRet = 0L;
2240 
2241     if( pData )
2242     {
2243         sal_uInt16      nFormat = GRFILTER_FORMAT_DONTKNOW;
2244         ByteString  aShortName;
2245         switch( pData->mnFormat )
2246         {
2247             case( CVT_BMP ): aShortName = BMP_SHORTNAME; break;
2248             case( CVT_GIF ): aShortName = GIF_SHORTNAME; break;
2249             case( CVT_JPG ): aShortName = JPG_SHORTNAME; break;
2250             case( CVT_MET ): aShortName = MET_SHORTNAME; break;
2251             case( CVT_PCT ): aShortName = PCT_SHORTNAME; break;
2252             case( CVT_PNG ): aShortName = PNG_SHORTNAME; break;
2253             case( CVT_SVM ): aShortName = SVM_SHORTNAME; break;
2254             case( CVT_TIF ): aShortName = TIF_SHORTNAME; break;
2255             case( CVT_WMF ): aShortName = WMF_SHORTNAME; break;
2256             case( CVT_EMF ): aShortName = EMF_SHORTNAME; break;
2257             case( CVT_SVG ): aShortName = SVG_SHORTNAME; break;
2258 
2259             default:
2260             break;
2261         }
2262         if( GRAPHIC_NONE == pData->maGraphic.GetType() || pData->maGraphic.GetContext() ) // Import
2263         {
2264             // Import
2265             nFormat = GetImportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
2266             nRet = ImportGraphic( pData->maGraphic, String(), pData->mrStm ) == 0;
2267         }
2268         else if( aShortName.Len() )
2269         {
2270             // Export
2271             nFormat = GetExportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
2272             nRet = ExportGraphic( pData->maGraphic, String(), pData->mrStm, nFormat ) == 0;
2273         }
2274     }
2275     return nRet;
2276 }
2277 
2278 // ------------------------------------------------------------------------
2279 
GetGraphicFilter()2280 GraphicFilter* GraphicFilter::GetGraphicFilter()
2281 {
2282     if( !pGraphicFilter )
2283     {
2284         pGraphicFilter = new GraphicFilter;
2285         pGraphicFilter->GetImportFormatCount();
2286     }
2287     return pGraphicFilter;
2288 }
2289 
LoadGraphic(const String & rPath,const String & rFilterName,Graphic & rGraphic,GraphicFilter * pFilter,sal_uInt16 * pDeterminedFormat)2290 int GraphicFilter::LoadGraphic( const String &rPath, const String &rFilterName,
2291                  Graphic& rGraphic, GraphicFilter* pFilter,
2292                  sal_uInt16* pDeterminedFormat )
2293 {
2294     if ( !pFilter )
2295         pFilter = GetGraphicFilter();
2296 
2297     const sal_uInt16 nFilter = rFilterName.Len() && pFilter->GetImportFormatCount()
2298                     ? pFilter->GetImportFormatNumber( rFilterName )
2299                     : GRFILTER_FORMAT_DONTKNOW;
2300 
2301     SvStream* pStream = NULL;
2302     INetURLObject aURL( rPath );
2303 
2304     if ( aURL.HasError() || INET_PROT_NOT_VALID == aURL.GetProtocol() )
2305     {
2306         aURL.SetSmartProtocol( INET_PROT_FILE );
2307         aURL.SetSmartURL( rPath );
2308     }
2309     else if ( INET_PROT_FILE != aURL.GetProtocol() )
2310     {
2311         pStream = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
2312     }
2313 
2314     int nRes = GRFILTER_OK;
2315     if ( !pStream )
2316         nRes = pFilter->ImportGraphic( rGraphic, aURL, nFilter, pDeterminedFormat );
2317     else
2318         nRes = pFilter->ImportGraphic( rGraphic, rPath, *pStream, nFilter, pDeterminedFormat );
2319 
2320 #ifdef DBG_UTIL
2321     if( nRes )
2322         DBG_WARNING2( "GrafikFehler [%d] - [%s]", nRes, rPath.GetBuffer() );
2323 #endif
2324 
2325     return nRes;
2326 }
2327