xref: /AOO41X/main/svtools/source/filter/filter.cxx (revision 3c5a7184f8642cf65c823667fcf4481e80301540)
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 
518         // A DXF file may begin with one or more 999 comment groups (each is a
519         // "999" code line followed by a comment value line), e.g. files written
520         // by Pro/ENGINEER. Skip them before looking for the first real group,
521         // otherwise such valid DXF files are rejected as an unknown format
522         // (issue 122565).
523         for (;;)
524         {
525             while (i<256 && sFirstBytes[i]<=32)
526                 i++;
527             if ( i+3<256 && sFirstBytes[i]=='9' && sFirstBytes[i+1]=='9' &&
528                  sFirstBytes[i+2]=='9' && sFirstBytes[i+3]<=32 )
529             {
530                 // skip the "999" code line and the comment value line after it
531                 int nLine;
532                 for ( nLine=0; nLine<2 && i<256; nLine++ )
533                 {
534                     while (i<256 && sFirstBytes[i]!='\n' && sFirstBytes[i]!='\r')
535                         i++;
536                     while (i<256 && (sFirstBytes[i]=='\n' || sFirstBytes[i]=='\r'))
537                         i++;
538                 }
539                 continue;
540             }
541             break;
542         }
543 
544         if (i<256)
545         {
546             if( sFirstBytes[i]=='0' )
547                 i++;
548             else
549                 i=256;
550         }
551         while( i<256 && sFirstBytes[i]<=32 )
552             i++;
553 
554         if (i+7<256)
555         {
556             if (strncmp((char*)(sFirstBytes+i),"SECTION",7)==0)
557             {
558                 rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
559                 return sal_True;
560             }
561         }
562 
563         if( strncmp( (char*) sFirstBytes, "AutoCAD Binary DXF", 18 ) == 0 )
564         {
565             rFormatExtension = UniString::CreateFromAscii( "DXF", 3 );
566             return sal_True;
567         }
568     }
569 
570     //--------------------------- PCT ------------------------------------
571     if( !bTest || ( rFormatExtension.CompareToAscii( "PCT", 3 ) == COMPARE_EQUAL ) )
572     {
573         bSomethingTested = sal_True;
574         sal_uInt8 sBuf[3];
575         // store number format
576         sal_uInt16 oldNumberFormat = rStream.GetNumberFormatInt();
577         sal_uInt32 nOffset; // in ms documents the pict format is used without the first 512 bytes
578         for ( nOffset = 0; ( nOffset <= 512 ) && ( ( nStreamPos + nOffset + 14 ) <= nStreamLen ); nOffset += 512 )
579         {
580             short y1,x1,y2,x2;
581             sal_Bool bdBoxOk = sal_True;
582 
583             rStream.Seek( nStreamPos + nOffset);
584             // size of the pict in version 1 pict ( 2bytes) : ignored
585             rStream.SeekRel(2);
586             // bounding box (bytes 2 -> 9)
587             rStream.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
588             rStream >> y1 >> x1 >> y2 >> x2;
589             rStream.SetNumberFormatInt(oldNumberFormat); // reset format
590 
591             if (x1 > x2 || y1 > y2 || // bad bdbox
592                 (x1 == x2 && y1 == y2) || // 1 pixel picture
593                 x2-x1 > 2048 || y2-y1 > 2048 ) // picture anormaly big
594               bdBoxOk = sal_False;
595 
596             // read version op
597             rStream.Read( sBuf,3 );
598             // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
599             // normal version 2 - page A23 and A24
600             if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x02)
601             {
602               rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
603               return sal_True;
604             }
605             // normal version 1 - page A25
606             else if (sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 && bdBoxOk) {
607               rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
608               return sal_True;
609             }
610             // previous code kept in order to do not break any compatibility
611             // probably eroneous
612             else if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x01 && bdBoxOk)
613             {
614               rFormatExtension = UniString::CreateFromAscii( "PCT", 3 );
615               return sal_True;
616             }
617         }
618     }
619 
620     //------------------------- PBM + PGM + PPM ---------------------------
621     if( !bTest ||
622         ( rFormatExtension.CompareToAscii( "PBM", 3 ) == COMPARE_EQUAL ) ||
623             ( rFormatExtension.CompareToAscii( "PGM", 3 ) == COMPARE_EQUAL ) ||
624                 ( rFormatExtension.CompareToAscii( "PPM", 3 ) == COMPARE_EQUAL ) )
625     {
626         bSomethingTested=sal_True;
627         if ( sFirstBytes[ 0 ] == 'P' )
628         {
629             switch( sFirstBytes[ 1 ] )
630             {
631                 case '1' :
632                 case '4' :
633                     rFormatExtension = UniString::CreateFromAscii( "PBM", 3 );
634                 return sal_True;
635 
636                 case '2' :
637                 case '5' :
638                     rFormatExtension = UniString::CreateFromAscii( "PGM", 3 );
639                 return sal_True;
640 
641                 case '3' :
642                 case '6' :
643                     rFormatExtension = UniString::CreateFromAscii( "PPM", 3 );
644                 return sal_True;
645             }
646         }
647     }
648 
649     //--------------------------- RAS( SUN RasterFile )------------------
650     if( !bTest || ( rFormatExtension.CompareToAscii( "RAS", 3 ) == COMPARE_EQUAL ) )
651     {
652         bSomethingTested=sal_True;
653         if( nFirstLong == 0x59a66a95 )
654         {
655             rFormatExtension = UniString::CreateFromAscii( "RAS", 3 );
656             return sal_True;
657         }
658     }
659 
660     //--------------------------- XPM ------------------------------------
661     if( !bTest )
662     {
663         bSomethingTested = sal_True;
664         if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"/* XPM */", 256, 9 ) )
665         {
666             rFormatExtension = UniString::CreateFromAscii( "XPM", 3 );
667             return sal_True;
668         }
669     }
670     else if( rFormatExtension.CompareToAscii( "XPM", 3 ) == COMPARE_EQUAL )
671     {
672         bSomethingTested = sal_True;
673         return sal_True;
674     }
675 
676     //--------------------------- XBM ------------------------------------
677     if( !bTest )
678     {
679         sal_uLong nSize = ( nStreamLen > 2048 ) ? 2048 : nStreamLen;
680         sal_uInt8* pBuf = new sal_uInt8 [ nSize ];
681 
682         rStream.Seek( nStreamPos );
683         rStream.Read( pBuf, nSize );
684         sal_uInt8* pPtr = ImplSearchEntry( pBuf, (sal_uInt8*)"#define", nSize, 7 );
685 
686         if( pPtr )
687         {
688             if( ImplSearchEntry( pPtr, (sal_uInt8*)"_width", pBuf + nSize - pPtr, 6 ) )
689             {
690                 rFormatExtension = UniString::CreateFromAscii( "XBM", 3 );
691                 delete[] pBuf;
692                 return sal_True;
693             }
694         }
695         delete[] pBuf;
696     }
697     else if( rFormatExtension.CompareToAscii( "XBM", 3 ) == COMPARE_EQUAL )
698     {
699         bSomethingTested = sal_True;
700         return sal_True;
701     }
702 
703     //--------------------------- SVG ------------------------------------
704     if( !bTest )
705     {
706         // check for Xml
707         if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<?xml", 256, 5 ) // is it xml
708             && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"version", 256, 7 )) // does it have a version (required for xml)
709         {
710             bool bIsSvg(false);
711 
712             // check for DOCTYPE svg combination
713             if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"DOCTYPE", 256, 7 ) // 'DOCTYPE' is there
714                 && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"svg", 256, 3 )) // 'svg' is there
715             {
716                 bIsSvg = true;
717             }
718 
719             // check for svg element in 1st 256 bytes
720             if(!bIsSvg && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg'
721             {
722                 bIsSvg = true;
723             }
724 
725             if(!bIsSvg)
726             {
727                 // it's a xml, look for '<svg' in full file. Should not happen too
728                 // often since the tests above will handle most cases, but can happen
729                 // with Svg files containing big comment headers or Svg as the host
730                 // language
731                 const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen);
732                 sal_uInt8* pBuf = new sal_uInt8[nSize];
733 
734                 rStream.Seek(nStreamPos);
735                 rStream.Read(pBuf, nSize);
736 
737                 if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg'
738                 {
739                     bIsSvg = true;
740                 }
741 
742                 delete[] pBuf;
743             }
744 
745             if(bIsSvg)
746             {
747                 rFormatExtension = UniString::CreateFromAscii( "SVG", 3 );
748                 return sal_True;
749             }
750         }
751         else
752         {
753             // #119176# Svg files which have no xml header at all have shown up,
754             // detect those, too
755             bool bIsSvg(false);
756 
757             // check for svg element in 1st 256 bytes
758             if(ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg'
759             {
760                 bIsSvg = true;
761             }
762 
763             if(!bIsSvg)
764             {
765                 // look for '<svg' in full file. Should not happen too
766                 // often since the tests above will handle most cases, but can happen
767                 // with Svg files containing big comment headers or Svg as the host
768                 // language
769                 const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen);
770                 sal_uInt8* pBuf = new sal_uInt8[nSize];
771 
772                 rStream.Seek(nStreamPos);
773                 rStream.Read(pBuf, nSize);
774 
775                 if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg'
776                 {
777                     bIsSvg = true;
778                 }
779 
780                 delete[] pBuf;
781             }
782 
783             if(bIsSvg)
784             {
785                 rFormatExtension = UniString::CreateFromAscii( "SVG", 3 );
786                 return sal_True;
787             }
788         }
789     }
790     else if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL )
791     {
792         bSomethingTested = sal_True;
793         return sal_True;
794     }
795 
796     //--------------------------- TGA ------------------------------------
797     if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) )
798     {
799         bSomethingTested = sal_True;
800 
801         // just a simple test for the extension
802         if( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL )
803             return sal_True;
804     }
805 
806     //--------------------------- SGV ------------------------------------
807     if( !bTest || ( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) )
808     {
809         bSomethingTested = sal_True;
810 
811         // just a simple test for the extension
812         if( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL )
813             return sal_True;
814     }
815 
816     //--------------------------- SGF ------------------------------------
817     if( !bTest || ( rFormatExtension.CompareToAscii( "SGF", 3 ) == COMPARE_EQUAL ) )
818     {
819         bSomethingTested=sal_True;
820         if( sFirstBytes[ 0 ] == 'J' && sFirstBytes[ 1 ] == 'J' )
821         {
822             rFormatExtension = UniString::CreateFromAscii( "SGF", 3 );
823             return sal_True;
824         }
825     }
826 
827     return bTest && !bSomethingTested;
828 }
829 
830 //--------------------------------------------------------------------------
831 
ImpTestOrFindFormat(const String & rPath,SvStream & rStream,sal_uInt16 & rFormat)832 sal_uInt16 GraphicFilter::ImpTestOrFindFormat( const String& rPath, SvStream& rStream, sal_uInt16& rFormat )
833 {
834     sal_uInt16 n = pConfig->GetImportFormatCount();
835 
836     // ggf. Filter bzw. Format durch anlesen ermitteln,
837     // oder durch anlesen zusichern, dass das Format stimmt:
838     if( rFormat == GRFILTER_FORMAT_DONTKNOW )
839     {
840         String aFormatExt;
841         if( ImpPeekGraphicFormat( rStream, aFormatExt, sal_False ) )
842         {
843             for( sal_uInt16 i = 0; i < n; i++ )
844             {
845                 if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aFormatExt ) )
846                 {
847                     rFormat = i;
848                     return GRFILTER_OK;
849                 }
850             }
851         }
852         // ggf. Filter anhand der Datei-Endung raussuchen:
853         if( rPath.Len() )
854         {
855             String aExt( ImpGetExtension( rPath ) );
856             for( sal_uInt16 i = 0; i < n; i++ )
857             {
858                 if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
859                 {
860                     rFormat = i;
861                     return GRFILTER_OK;
862                 }
863             }
864         }
865         return GRFILTER_FORMATERROR;
866     }
867     else
868     {
869         String aTmpStr( pConfig->GetImportFormatExtension( rFormat ) );
870         if( !ImpPeekGraphicFormat( rStream, aTmpStr, sal_True ) )
871             return GRFILTER_FORMATERROR;
872         if ( pConfig->GetImportFormatExtension( rFormat ).EqualsIgnoreCaseAscii( "pcd" ) )
873         {
874             sal_Int32 nBase = 2;    // default Base0
875             if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base4" ) )
876                 nBase = 1;
877             else if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base16" ) )
878                 nBase = 0;
879             String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
880             FilterConfigItem aFilterConfigItem( aFilterConfigPath );
881             aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
882         }
883     }
884 
885     return GRFILTER_OK;
886 }
887 
888 //--------------------------------------------------------------------------
889 
ImpGetScaledGraphic(const Graphic & rGraphic,FilterConfigItem & rConfigItem)890 static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem )
891 {
892     Graphic     aGraphic;
893     ByteString  aResMgrName( "svt", 3 );
894     ResMgr*     pResMgr;
895 
896     pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
897 
898     sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) ), 0 );
899     sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) ), 0 );
900 
901     if ( rGraphic.GetType() != GRAPHIC_NONE )
902     {
903         sal_Int32 nMode = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "ExportMode" ) ), -1 );
904 
905         if ( nMode == -1 )  // the property is not there, this is possible, if the graphic filter
906         {                   // is called via UnoGraphicExporter and not from a graphic export Dialog
907             nMode = 0;      // then we are defaulting this mode to 0
908             if ( nLogicalWidth || nLogicalHeight )
909                 nMode = 2;
910         }
911 
912 
913         Size aOriginalSize;
914         Size aPrefSize( rGraphic.GetPrefSize() );
915         MapMode aPrefMapMode( rGraphic.GetPrefMapMode() );
916         if ( aPrefMapMode == MAP_PIXEL )
917             aOriginalSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
918         else
919             aOriginalSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
920         if ( !nLogicalWidth )
921             nLogicalWidth = aOriginalSize.Width();
922         if ( !nLogicalHeight )
923             nLogicalHeight = aOriginalSize.Height();
924         if( rGraphic.GetType() == GRAPHIC_BITMAP )
925         {
926 
927             // Aufloesung wird eingestellt
928             if( nMode == 1 )
929             {
930                 Bitmap      aBitmap( rGraphic.GetBitmap() );
931                 MapMode     aMap( MAP_100TH_INCH );
932 
933                 sal_Int32   nDPI = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), 75 );
934                 Fraction    aFrac( 1, Min( Max( nDPI, sal_Int32( 75 ) ), sal_Int32( 600 ) ) );
935 
936                 aMap.SetScaleX( aFrac );
937                 aMap.SetScaleY( aFrac );
938 
939                 Size aOldSize = aBitmap.GetSizePixel();
940                 aGraphic = rGraphic;
941                 aGraphic.SetPrefMapMode( aMap );
942                 aGraphic.SetPrefSize( Size( aOldSize.Width() * 100,
943                                            aOldSize.Height() * 100 ) );
944             }
945             // Groesse wird eingestellt
946             else if( nMode == 2 )
947             {
948                 aGraphic = rGraphic;
949                 aGraphic.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
950                 aGraphic.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) );
951             }
952             else
953                 aGraphic = rGraphic;
954 
955             sal_Int32 nColors = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Color" ) ), 0 ); // #92767#
956             if ( nColors )  // graphic conversion necessary ?
957             {
958                 BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
959                 aBmpEx.Convert( (BmpConversion)nColors );   // the entries in the xml section have the same meaning as
960                 aGraphic = aBmpEx;                          // they have in the BmpConversion enum, so it should be
961             }                                               // allowed to cast them
962         }
963         else
964         {
965             if( ( nMode == 1 ) || ( nMode == 2 ) )
966             {
967                 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
968                 ::com::sun::star::awt::Size aDefaultSize( 10000, 10000 );
969                 Size aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth, nLogicalHeight ), MAP_100TH_MM, aMtf.GetPrefMapMode() ) );
970 
971                 if( aNewSize.Width() && aNewSize.Height() )
972                 {
973                     const Size aPreferredSize( aMtf.GetPrefSize() );
974                     aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ),
975                                 Fraction( aNewSize.Height(), aPreferredSize.Height() ) );
976                 }
977                 aGraphic = Graphic( aMtf );
978             }
979             else
980                 aGraphic = rGraphic;
981         }
982 
983     }
984     else
985         aGraphic = rGraphic;
986 
987     delete pResMgr;
988 
989     return aGraphic;
990 }
991 
ImpCreateFullFilterPath(const String & rPath,const String & rFilterName)992 static String ImpCreateFullFilterPath( const String& rPath, const String& rFilterName )
993 {
994     ::rtl::OUString aPathURL;
995 
996     ::osl::FileBase::getFileURLFromSystemPath( rPath, aPathURL );
997     aPathURL += String( '/' );
998 
999     ::rtl::OUString aSystemPath;
1000     ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
1001     aSystemPath += ::rtl::OUString( rFilterName );
1002 
1003     return String( aSystemPath );
1004 }
1005 
1006 
1007 // --------------------------
1008 // - ImpFilterLibCacheEntry -
1009 // --------------------------
1010 
1011 class ImpFilterLibCache;
1012 
1013 struct ImpFilterLibCacheEntry
1014 {
1015     ImpFilterLibCacheEntry* mpNext;
1016     osl::Module             maLibrary;
1017     String                  maFiltername;
1018     PFilterCall             mpfnImport;
1019     PFilterDlgCall          mpfnImportDlg;
1020 
1021                             ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername );
operator ==ImpFilterLibCacheEntry1022     int                     operator==( const String& rFiltername ) const { return maFiltername == rFiltername; }
1023 
1024     PFilterCall             GetImportFunction();
1025     PFilterDlgCall          GetImportDlgFunction();
GetExportFunctionImpFilterLibCacheEntry1026     PFilterCall             GetExportFunction() { return (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) ); }
GetExportDlgFunctionImpFilterLibCacheEntry1027     PFilterDlgCall          GetExportDlgFunction() { return (PFilterDlgCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) ); }
1028 };
1029 
1030 // ------------------------------------------------------------------------
1031 
ImpFilterLibCacheEntry(const String & rPathname,const String & rFiltername)1032 ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername ) :
1033         mpNext          ( NULL ),
1034         maLibrary       ( rPathname ),
1035         maFiltername    ( rFiltername ),
1036         mpfnImport      ( NULL ),
1037         mpfnImportDlg   ( NULL )
1038 {
1039 }
1040 
1041 // ------------------------------------------------------------------------
1042 
GetImportFunction()1043 PFilterCall ImpFilterLibCacheEntry::GetImportFunction()
1044 {
1045     if( !mpfnImport )
1046         mpfnImport = (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPORT_FUNCTION_NAME ) );
1047 
1048     return mpfnImport;
1049 }
1050 
1051 // ------------------------------------------------------------------------
1052 
GetImportDlgFunction()1053 PFilterDlgCall ImpFilterLibCacheEntry::GetImportDlgFunction()
1054 {
1055     if( !mpfnImportDlg )
1056         mpfnImportDlg = (PFilterDlgCall)maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPDLG_FUNCTION_NAME ) );
1057 
1058     return mpfnImportDlg;
1059 }
1060 
1061 // ---------------------
1062 // - ImpFilterLibCache -
1063 // ---------------------
1064 
1065 class ImpFilterLibCache
1066 {
1067     ImpFilterLibCacheEntry* mpFirst;
1068     ImpFilterLibCacheEntry* mpLast;
1069 
1070 public:
1071                             ImpFilterLibCache();
1072                             ~ImpFilterLibCache();
1073 
1074     ImpFilterLibCacheEntry* GetFilter( const String& rFilterPath, const String& rFiltername );
1075 };
1076 
1077 // ------------------------------------------------------------------------
1078 
ImpFilterLibCache()1079 ImpFilterLibCache::ImpFilterLibCache() :
1080     mpFirst     ( NULL ),
1081     mpLast      ( NULL )
1082 {
1083 }
1084 
1085 // ------------------------------------------------------------------------
1086 
~ImpFilterLibCache()1087 ImpFilterLibCache::~ImpFilterLibCache()
1088 {
1089     ImpFilterLibCacheEntry* pEntry = mpFirst;
1090     while( pEntry )
1091     {
1092         ImpFilterLibCacheEntry* pNext = pEntry->mpNext;
1093         delete pEntry;
1094         pEntry = pNext;
1095     }
1096 }
1097 
1098 // ------------------------------------------------------------------------
1099 
GetFilter(const String & rFilterPath,const String & rFilterName)1100 ImpFilterLibCacheEntry* ImpFilterLibCache::GetFilter( const String& rFilterPath, const String& rFilterName )
1101 {
1102     ImpFilterLibCacheEntry* pEntry = mpFirst;
1103 
1104     while( pEntry )
1105     {
1106         if( *pEntry == rFilterName )
1107             break;
1108         else
1109             pEntry = pEntry->mpNext;
1110     }
1111     if( !pEntry )
1112     {
1113         String aPhysicalName( ImpCreateFullFilterPath( rFilterPath, rFilterName ) );
1114         pEntry = new ImpFilterLibCacheEntry( aPhysicalName, rFilterName );
1115 
1116         if ( pEntry->maLibrary.is() )
1117         {
1118             if( !mpFirst )
1119                 mpFirst = mpLast = pEntry;
1120             else
1121                 mpLast = mpLast->mpNext = pEntry;
1122         }
1123         else
1124         {
1125             delete pEntry;
1126             pEntry = NULL;
1127         }
1128     }
1129     return pEntry;
1130 };
1131 
1132 // ------------------------------------------------------------------------
1133 
1134 namespace { struct Cache : public rtl::Static<ImpFilterLibCache, Cache> {}; }
1135 
1136 // -----------------
1137 // - GraphicFilter -
1138 // -----------------
1139 
GraphicFilter(sal_Bool bConfig)1140 GraphicFilter::GraphicFilter( sal_Bool bConfig ) :
1141     bUseConfig        ( bConfig ),
1142     nExpGraphHint     ( 0 )
1143 {
1144     ImplInit();
1145 }
1146 
1147 // ------------------------------------------------------------------------
1148 
~GraphicFilter()1149 GraphicFilter::~GraphicFilter()
1150 {
1151     {
1152         ::osl::MutexGuard aGuard( getListMutex() );
1153         pFilterHdlList->Remove( (void*)this );
1154         if ( !pFilterHdlList->Count() )
1155         {
1156             delete pFilterHdlList, pFilterHdlList = NULL;
1157             delete pConfig;
1158         }
1159     }
1160 
1161 
1162     delete pErrorEx;
1163 }
1164 
1165 // ------------------------------------------------------------------------
1166 
ImplInit()1167 void GraphicFilter::ImplInit()
1168 {
1169     {
1170         ::osl::MutexGuard aGuard( getListMutex() );
1171 
1172         if ( !pFilterHdlList )
1173         {
1174             pFilterHdlList = new List;
1175             pConfig = new FilterConfigCache( bUseConfig );
1176         }
1177         else
1178             pConfig = ((GraphicFilter*)pFilterHdlList->First())->pConfig;
1179 
1180         pFilterHdlList->Insert( (void*)this );
1181     }
1182 
1183     if( bUseConfig )
1184     {
1185         rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program"));
1186         rtl::Bootstrap::expandMacros(url); //TODO: detect failure
1187         utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath);
1188     }
1189 
1190     pErrorEx = new FilterErrorEx;
1191     bAbort = sal_False;
1192 }
1193 
1194 // ------------------------------------------------------------------------
1195 
ImplSetError(sal_uLong nError,const SvStream * pStm)1196 sal_uLong GraphicFilter::ImplSetError( sal_uLong nError, const SvStream* pStm )
1197 {
1198     pErrorEx->nFilterError = nError;
1199     pErrorEx->nStreamError = pStm ? pStm->GetError() : ERRCODE_NONE;
1200     return nError;
1201 }
1202 // ------------------------------------------------------------------------
1203 
GetImportFormatCount()1204 sal_uInt16 GraphicFilter::GetImportFormatCount()
1205 {
1206     return pConfig->GetImportFormatCount();
1207 }
1208 
1209 // ------------------------------------------------------------------------
1210 
GetImportFormatNumber(const String & rFormatName)1211 sal_uInt16 GraphicFilter::GetImportFormatNumber( const String& rFormatName )
1212 {
1213     return pConfig->GetImportFormatNumber( rFormatName );
1214 }
1215 
1216 // ------------------------------------------------------------------------
1217 
GetImportFormatNumberForMediaType(const String & rMediaType)1218 sal_uInt16 GraphicFilter::GetImportFormatNumberForMediaType( const String& rMediaType )
1219 {
1220     return pConfig->GetImportFormatNumberForMediaType( rMediaType );
1221 }
1222 
1223 // ------------------------------------------------------------------------
1224 
GetImportFormatNumberForShortName(const String & rShortName)1225 sal_uInt16 GraphicFilter::GetImportFormatNumberForShortName( const String& rShortName )
1226 {
1227     return pConfig->GetImportFormatNumberForShortName( rShortName );
1228 }
1229 
1230 // ------------------------------------------------------------------------
1231 
GetImportFormatNumberForTypeName(const String & rType)1232 sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( const String& rType )
1233 {
1234     return pConfig->GetImportFormatNumberForTypeName( rType );
1235 }
1236 
1237 // ------------------------------------------------------------------------
1238 
GetImportFormatName(sal_uInt16 nFormat)1239 String GraphicFilter::GetImportFormatName( sal_uInt16 nFormat )
1240 {
1241     return pConfig->GetImportFormatName( nFormat );
1242 }
1243 
1244 // ------------------------------------------------------------------------
1245 
GetImportFormatTypeName(sal_uInt16 nFormat)1246 String GraphicFilter::GetImportFormatTypeName( sal_uInt16 nFormat )
1247 {
1248     return pConfig->GetImportFilterTypeName( nFormat );
1249 }
1250 
1251 // ------------------------------------------------------------------------
1252 
GetImportFormatMediaType(sal_uInt16 nFormat)1253 String GraphicFilter::GetImportFormatMediaType( sal_uInt16 nFormat )
1254 {
1255     return pConfig->GetImportFormatMediaType( nFormat );
1256 }
1257 
1258 // ------------------------------------------------------------------------
1259 
GetImportFormatShortName(sal_uInt16 nFormat)1260 String GraphicFilter::GetImportFormatShortName( sal_uInt16 nFormat )
1261 {
1262     return pConfig->GetImportFormatShortName( nFormat );
1263 }
1264 
1265 // ------------------------------------------------------------------------
1266 
GetImportOSFileType(sal_uInt16)1267 String GraphicFilter::GetImportOSFileType( sal_uInt16 )
1268 {
1269     String aOSFileType;
1270     return aOSFileType;
1271 }
1272 
1273 // ------------------------------------------------------------------------
1274 
GetImportWildcard(sal_uInt16 nFormat,sal_Int32 nEntry)1275 String GraphicFilter::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
1276 {
1277     return pConfig->GetImportWildcard( nFormat, nEntry );
1278 }
1279 
1280 // ------------------------------------------------------------------------
1281 
IsImportPixelFormat(sal_uInt16 nFormat)1282 sal_Bool GraphicFilter::IsImportPixelFormat( sal_uInt16 nFormat )
1283 {
1284     return pConfig->IsImportPixelFormat( nFormat );
1285 }
1286 
1287 // ------------------------------------------------------------------------
1288 
GetExportFormatCount()1289 sal_uInt16 GraphicFilter::GetExportFormatCount()
1290 {
1291     return pConfig->GetExportFormatCount();
1292 }
1293 
1294 // ------------------------------------------------------------------------
1295 
GetExportFormatNumber(const String & rFormatName)1296 sal_uInt16 GraphicFilter::GetExportFormatNumber( const String& rFormatName )
1297 {
1298     return pConfig->GetExportFormatNumber( rFormatName );
1299 }
1300 
1301 // ------------------------------------------------------------------------
1302 
GetExportFormatNumberForMediaType(const String & rMediaType)1303 sal_uInt16 GraphicFilter::GetExportFormatNumberForMediaType( const String& rMediaType )
1304 {
1305     return pConfig->GetExportFormatNumberForMediaType( rMediaType );
1306 }
1307 
1308 // ------------------------------------------------------------------------
1309 
GetExportFormatNumberForShortName(const String & rShortName)1310 sal_uInt16 GraphicFilter::GetExportFormatNumberForShortName( const String& rShortName )
1311 {
1312     return pConfig->GetExportFormatNumberForShortName( rShortName );
1313 }
1314 
1315 // ------------------------------------------------------------------------
1316 
GetExportFormatNumberForTypeName(const String & rType)1317 sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( const String& rType )
1318 {
1319     return pConfig->GetExportFormatNumberForTypeName( rType );
1320 }
1321 
1322 // ------------------------------------------------------------------------
1323 
GetExportFormatName(sal_uInt16 nFormat)1324 String GraphicFilter::GetExportFormatName( sal_uInt16 nFormat )
1325 {
1326     return pConfig->GetExportFormatName( nFormat );
1327 }
1328 
1329 // ------------------------------------------------------------------------
1330 
GetExportFormatTypeName(sal_uInt16 nFormat)1331 String GraphicFilter::GetExportFormatTypeName( sal_uInt16 nFormat )
1332 {
1333     return pConfig->GetExportFilterTypeName( nFormat );
1334 }
1335 
1336 // ------------------------------------------------------------------------
1337 
GetExportFormatMediaType(sal_uInt16 nFormat)1338 String GraphicFilter::GetExportFormatMediaType( sal_uInt16 nFormat )
1339 {
1340     return pConfig->GetExportFormatMediaType( nFormat );
1341 }
1342 
1343 // ------------------------------------------------------------------------
1344 
GetExportFormatShortName(sal_uInt16 nFormat)1345 String GraphicFilter::GetExportFormatShortName( sal_uInt16 nFormat )
1346 {
1347     return pConfig->GetExportFormatShortName( nFormat );
1348 }
1349 
1350 // ------------------------------------------------------------------------
1351 
GetExportOSFileType(sal_uInt16)1352 String GraphicFilter::GetExportOSFileType( sal_uInt16 )
1353 {
1354     String aOSFileType;
1355     return aOSFileType;
1356 }
1357 
1358 // ------------------------------------------------------------------------
1359 
GetExportWildcard(sal_uInt16 nFormat,sal_Int32 nEntry)1360 String GraphicFilter::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
1361 {
1362     return pConfig->GetExportWildcard( nFormat, nEntry );
1363 }
1364 
1365 // ------------------------------------------------------------------------
1366 
IsExportPixelFormat(sal_uInt16 nFormat)1367 sal_Bool GraphicFilter::IsExportPixelFormat( sal_uInt16 nFormat )
1368 {
1369     return pConfig->IsExportPixelFormat( nFormat );
1370 }
1371 
1372 // ------------------------------------------------------------------------
1373 
CanImportGraphic(const INetURLObject & rPath,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat)1374 sal_uInt16 GraphicFilter::CanImportGraphic( const INetURLObject& rPath,
1375                                         sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
1376 {
1377     sal_uInt16  nRetValue = GRFILTER_FORMATERROR;
1378     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1379 
1380     String      aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1381     SvStream*   pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
1382     if ( pStream )
1383     {
1384         nRetValue = CanImportGraphic( aMainUrl, *pStream, nFormat, pDeterminedFormat );
1385         delete pStream;
1386     }
1387     return nRetValue;
1388 }
1389 
1390 // ------------------------------------------------------------------------
1391 
CanImportGraphic(const String & rMainUrl,SvStream & rIStream,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat)1392 sal_uInt16 GraphicFilter::CanImportGraphic( const String& rMainUrl, SvStream& rIStream,
1393                                         sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
1394 {
1395     sal_uLong nStreamPos = rIStream.Tell();
1396     sal_uInt16 nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat );
1397 
1398     rIStream.Seek(nStreamPos);
1399 
1400     if( nRes==GRFILTER_OK && pDeterminedFormat!=NULL )
1401         *pDeterminedFormat = nFormat;
1402 
1403     return (sal_uInt16) ImplSetError( nRes, &rIStream );
1404 }
1405 
1406 // ------------------------------------------------------------------------
1407 //SJ: TODO, we need to create a GraphicImporter component
ImportGraphic(Graphic & rGraphic,const INetURLObject & rPath,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat,sal_uInt32 nImportFlags)1408 sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
1409                                      sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, sal_uInt32 nImportFlags )
1410 {
1411     sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
1412     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1413 
1414     String      aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1415     SvStream*   pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE );
1416     if ( pStream )
1417     {
1418         nRetValue = ImportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pDeterminedFormat, nImportFlags );
1419         delete pStream;
1420     }
1421     return nRetValue;
1422 }
1423 
ImportGraphic(Graphic & rGraphic,const String & rPath,SvStream & rIStream,sal_uInt16 nFormat,sal_uInt16 * pDeterminedFormat,sal_uInt32 nImportFlags)1424 sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
1425                                      sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags )
1426 {
1427     return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL );
1428 }
1429 
1430 //-------------------------------------------------------------------------
1431 
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)1432 sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream,
1433                                      sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags,
1434                                      com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData )
1435 {
1436     String                  aFilterName;
1437     sal_uLong                   nStmBegin;
1438     sal_uInt16                  nStatus;
1439     GraphicReader*          pContext = rGraphic.GetContext();
1440     GfxLinkType             eLinkType = GFX_LINK_TYPE_NONE;
1441     sal_Bool                    bDummyContext = ( pContext == (GraphicReader*) 1 );
1442     const sal_Bool              bLinkSet = rGraphic.IsLink();
1443     FilterConfigItem*       pFilterConfigItem = NULL;
1444 
1445     Size                    aPreviewSizeHint( 0, 0 );
1446     sal_Bool                bAllowPartialStreamRead = sal_False;
1447     sal_Bool                bCreateNativeLink = sal_True;
1448 
1449     ResetLastError();
1450 
1451     if ( pFilterData )
1452     {
1453         sal_Int32 i;
1454         for ( i = 0; i < pFilterData->getLength(); i++ )
1455         {
1456             if ( (*pFilterData)[ i ].Name.equalsAscii( "PreviewSizeHint" ) )
1457             {
1458                 awt::Size aSize;
1459                 if ( (*pFilterData)[ i ].Value >>= aSize )
1460                 {
1461                     aPreviewSizeHint = Size( aSize.Width, aSize.Height );
1462                     if ( aSize.Width || aSize.Height )
1463                         nImportFlags |= GRFILTER_I_FLAGS_FOR_PREVIEW;
1464                     else
1465                         nImportFlags &=~GRFILTER_I_FLAGS_FOR_PREVIEW;
1466                 }
1467             }
1468             else if ( (*pFilterData)[ i ].Name.equalsAscii( "AllowPartialStreamRead" ) )
1469             {
1470                 (*pFilterData)[ i ].Value >>= bAllowPartialStreamRead;
1471                 if ( bAllowPartialStreamRead )
1472                     nImportFlags |= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
1473                 else
1474                     nImportFlags &=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
1475             }
1476             else if ( (*pFilterData)[ i ].Name.equalsAscii( "CreateNativeLink" ) )
1477             {
1478                 (*pFilterData)[ i ].Value >>= bCreateNativeLink;
1479             }
1480         }
1481     }
1482 
1483     if( !pContext || bDummyContext )
1484     {
1485         if( bDummyContext )
1486         {
1487             rGraphic.SetContext( NULL );
1488             nStmBegin = 0;
1489         }
1490         else
1491             nStmBegin = rIStream.Tell();
1492 
1493         bAbort = sal_False;
1494         nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat );
1495         // Falls Pending, geben wir GRFILTER_OK zurueck,
1496         // um mehr Bytes anzufordern
1497         if( rIStream.GetError() == ERRCODE_IO_PENDING )
1498         {
1499             rGraphic.SetContext( (GraphicReader*) 1 );
1500             rIStream.ResetError();
1501             rIStream.Seek( nStmBegin );
1502             return (sal_uInt16) ImplSetError( GRFILTER_OK );
1503         }
1504 
1505         rIStream.Seek( nStmBegin );
1506 
1507         if( ( nStatus != GRFILTER_OK ) || rIStream.GetError() )
1508             return (sal_uInt16) ImplSetError( ( nStatus != GRFILTER_OK ) ? nStatus : GRFILTER_OPENERROR, &rIStream );
1509 
1510         if( pDeterminedFormat )
1511             *pDeterminedFormat = nFormat;
1512 
1513         aFilterName = pConfig->GetImportFilterName( nFormat );
1514     }
1515     else
1516     {
1517         if( pContext && !bDummyContext )
1518             aFilterName = pContext->GetUpperFilterName();
1519 
1520         nStmBegin = 0;
1521         nStatus = GRFILTER_OK;
1522     }
1523 
1524     // read graphic
1525     if ( pConfig->IsImportInternalFilter( nFormat ) )
1526     {
1527         if( aFilterName.EqualsIgnoreCaseAscii( IMP_GIF )  )
1528         {
1529             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1530                 rGraphic.SetContext( NULL );
1531 
1532             if( !ImportGIF( rIStream, rGraphic ) )
1533                 nStatus = GRFILTER_FILTERERROR;
1534             else
1535                 eLinkType = GFX_LINK_TYPE_NATIVE_GIF;
1536         }
1537         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_PNG ) )
1538         {
1539             if ( rGraphic.GetContext() == (GraphicReader*) 1 )
1540                 rGraphic.SetContext( NULL );
1541 
1542             vcl::PNGReader aPNGReader( rIStream );
1543 
1544             // ignore animation for previews and set preview size
1545             if( aPreviewSizeHint.Width() || aPreviewSizeHint.Height() )
1546             {
1547                 // position the stream at the end of the image if requested
1548                 if( !bAllowPartialStreamRead )
1549                     aPNGReader.GetChunks();
1550             }
1551             else
1552             {
1553                 // check if this PNG contains a GIF chunk!
1554                 const std::vector< vcl::PNGReader::ChunkData >&    rChunkData = aPNGReader.GetChunks();
1555                 std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() );
1556                 std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() );
1557                 while( aIter != aEnd )
1558                 {
1559                     // Microsoft Office is storing Animated GIFs in following chunk
1560                     if ( aIter->nType == PMGCHUNG_msOG )
1561                     {
1562                         sal_uInt32 nChunkSize = aIter->aData.size();
1563                         if ( nChunkSize > 11 )
1564                         {
1565                             const std::vector< sal_uInt8 >& rData = aIter->aData;
1566                             SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, STREAM_READ );
1567                             ImportGIF( aIStrm, rGraphic );
1568                             eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
1569                             break;
1570                         }
1571                     }
1572                     aIter++;
1573                 }
1574             }
1575 
1576             if ( eLinkType == GFX_LINK_TYPE_NONE )
1577             {
1578                 BitmapEx aBmpEx( aPNGReader.Read( aPreviewSizeHint ) );
1579                 if ( aBmpEx.IsEmpty() )
1580                     nStatus = GRFILTER_FILTERERROR;
1581                 else
1582                 {
1583                     rGraphic = aBmpEx;
1584                     eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
1585                 }
1586             }
1587         }
1588         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_JPEG ) )
1589         {
1590             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1591                 rGraphic.SetContext( NULL );
1592 
1593             // set LOGSIZE flag always, if not explicitly disabled
1594             // (see #90508 and #106763)
1595             if( 0 == ( nImportFlags & GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG ) )
1596                 nImportFlags |= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
1597 
1598             if( !ImportJPEG( rIStream, rGraphic, NULL, nImportFlags ) )
1599                 nStatus = GRFILTER_FILTERERROR;
1600             else
1601                 eLinkType = GFX_LINK_TYPE_NATIVE_JPG;
1602         }
1603         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVG ) )
1604         {
1605             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1606                 rGraphic.SetContext( NULL );
1607 
1608             const sal_uInt32 nStmPos(rIStream.Tell());
1609             const sal_uInt32 nStmLen(rIStream.Seek(STREAM_SEEK_TO_END) - nStmPos);
1610             bool bOkay(false);
1611 
1612             if(nStmLen)
1613             {
1614                 SvgDataArray aNewData(new sal_uInt8[nStmLen]);
1615 
1616                 rIStream.Seek(nStmPos);
1617                 rIStream.Read(aNewData.get(), nStmLen);
1618 
1619                 if(!rIStream.GetError())
1620                 {
1621                     SvgDataPtr aSvgDataPtr(
1622                         new SvgData(
1623                             aNewData,
1624                             nStmLen,
1625                             rPath));
1626 
1627                     rGraphic = Graphic(aSvgDataPtr);
1628                     bOkay = true;
1629                 }
1630             }
1631 
1632             if(bOkay)
1633             {
1634                 eLinkType = GFX_LINK_TYPE_NATIVE_SVG;
1635             }
1636             else
1637             {
1638                 nStatus = GRFILTER_FILTERERROR;
1639             }
1640         }
1641         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) )
1642         {
1643             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1644                 rGraphic.SetContext( NULL );
1645 
1646             if( !ImportXBM( rIStream, rGraphic ) )
1647                 nStatus = GRFILTER_FILTERERROR;
1648         }
1649         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XPM ) )
1650         {
1651             if( rGraphic.GetContext() == (GraphicReader*) 1 )
1652                 rGraphic.SetContext( NULL );
1653 
1654             if( !ImportXPM( rIStream, rGraphic ) )
1655                 nStatus = GRFILTER_FILTERERROR;
1656         }
1657         else if ( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP )
1658                   || aFilterName.EqualsIgnoreCaseAscii( IMP_SVMETAFILE ) )
1659         {
1660             // SV interne Importfilter fuer Bitmaps und MetaFiles
1661             rIStream >> rGraphic;
1662 
1663             if( rIStream.GetError() )
1664             {
1665                 nStatus = GRFILTER_FORMATERROR;
1666             }
1667             else
1668             {
1669                 if ( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP ) )
1670                 {
1671                     // #15508# added BMP type (checked, works)
1672                     eLinkType = GFX_LINK_TYPE_NATIVE_BMP;
1673                 }
1674             }
1675         }
1676         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_WMF ) ||
1677                 aFilterName.EqualsIgnoreCaseAscii( IMP_EMF ) )
1678         {
1679             GDIMetaFile aMtf;
1680             if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL ) )
1681                 nStatus = GRFILTER_FORMATERROR;
1682             else
1683             {
1684                 rGraphic = aMtf;
1685                 eLinkType = GFX_LINK_TYPE_NATIVE_WMF;
1686             }
1687         }
1688         else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGF )
1689                 || aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGV ) )
1690         {
1691             sal_uInt16          nVersion;
1692             unsigned char   nTyp = CheckSgfTyp( rIStream, nVersion );
1693 
1694             switch( nTyp )
1695             {
1696                 case SGF_BITIMAGE:
1697                 {
1698                     SvMemoryStream aTempStream;
1699                     if( aTempStream.GetError() )
1700                         return GRFILTER_OPENERROR;
1701 
1702                     if( !SgfBMapFilter( rIStream, aTempStream ) )
1703                         nStatus = GRFILTER_FILTERERROR;
1704                     else
1705                     {
1706                         aTempStream.Seek( 0L );
1707                         aTempStream >> rGraphic;
1708 
1709                         if( aTempStream.GetError() )
1710                             nStatus = GRFILTER_FILTERERROR;
1711                     }
1712                 }
1713                 break;
1714 
1715                 case SGF_SIMPVECT:
1716                 {
1717                     GDIMetaFile aMtf;
1718                     if( !SgfVectFilter( rIStream, aMtf ) )
1719                         nStatus = GRFILTER_FILTERERROR;
1720                     else
1721                         rGraphic = Graphic( aMtf );
1722                 }
1723                 break;
1724 
1725                 case SGF_STARDRAW:
1726                 {
1727                     if( nVersion != SGV_VERSION )
1728                         nStatus = GRFILTER_VERSIONERROR;
1729                     else
1730                     {
1731                         GDIMetaFile aMtf;
1732                         if( !SgfSDrwFilter( rIStream, aMtf,
1733                                 INetURLObject(aFilterPath) ) )
1734                         {
1735                             nStatus = GRFILTER_FILTERERROR;
1736                         }
1737                         else
1738                             rGraphic = Graphic( aMtf );
1739                     }
1740                 }
1741                 break;
1742 
1743                 default:
1744                 {
1745                     nStatus = GRFILTER_FORMATERROR;
1746                 }
1747                 break;
1748             }
1749         }
1750         else
1751             nStatus = GRFILTER_FILTERERROR;
1752     }
1753     else
1754     {
1755         ImpFilterLibCacheEntry* pFilter = NULL;
1756 
1757         // find first filter in filter pathes
1758         xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
1759         ImpFilterLibCache &rCache = Cache::get();
1760         for( i = 0; ( i < nTokenCount ) && ( pFilter == NULL ); i++ )
1761             pFilter = rCache.GetFilter( aFilterPath.GetToken(i), aFilterName );
1762         if( !pFilter )
1763             nStatus = GRFILTER_FILTERERROR;
1764         else
1765         {
1766             PFilterCall pFunc = pFilter->GetImportFunction();
1767 
1768             if( !pFunc )
1769                 nStatus = GRFILTER_FILTERERROR;
1770             else
1771             {
1772                 String aShortName;
1773                 if( nFormat != GRFILTER_FORMAT_DONTKNOW )
1774                 {
1775                     aShortName = GetImportFormatShortName( nFormat ).ToUpperAscii();
1776                     if ( ( pFilterConfigItem == NULL ) && aShortName.EqualsAscii( "PCD" ) )
1777                     {
1778                         String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
1779                         pFilterConfigItem = new FilterConfigItem( aFilterConfigPath );
1780                     }
1781                 }
1782                 if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem, sal_False ) )
1783                     nStatus = GRFILTER_FORMATERROR;
1784                 else
1785                 {
1786                     // try to set link type if format matches
1787                     if( nFormat != GRFILTER_FORMAT_DONTKNOW )
1788                     {
1789                         if( aShortName.CompareToAscii( TIF_SHORTNAME ) == COMPARE_EQUAL )
1790                             eLinkType = GFX_LINK_TYPE_NATIVE_TIF;
1791                         else if( aShortName.CompareToAscii( MET_SHORTNAME ) == COMPARE_EQUAL )
1792                             eLinkType = GFX_LINK_TYPE_NATIVE_MET;
1793                         else if( aShortName.CompareToAscii( PCT_SHORTNAME ) == COMPARE_EQUAL )
1794                             eLinkType = GFX_LINK_TYPE_NATIVE_PCT;
1795                     }
1796                 }
1797             }
1798         }
1799     }
1800 
1801     if( nStatus == GRFILTER_OK && bCreateNativeLink && ( eLinkType != GFX_LINK_TYPE_NONE ) && !rGraphic.GetContext() && !bLinkSet )
1802     {
1803         const sal_uLong nStmEnd = rIStream.Tell();
1804         const sal_uLong nBufSize = nStmEnd - nStmBegin;
1805 
1806         if( nBufSize )
1807         {
1808             sal_uInt8*  pBuf=0;
1809             try
1810             {
1811                 pBuf = new sal_uInt8[ nBufSize ];
1812             }
1813                 catch (std::bad_alloc)
1814             {
1815                 nStatus = GRFILTER_TOOBIG;
1816             }
1817 
1818             if( nStatus == GRFILTER_OK )
1819             {
1820                 rIStream.Seek( nStmBegin );
1821                 rIStream.Read( pBuf, nBufSize );
1822                 rGraphic.SetLink( GfxLink( pBuf, nBufSize, eLinkType, sal_True ) );
1823             }
1824         }
1825     }
1826 
1827     // Set error code or try to set native buffer
1828     if( nStatus != GRFILTER_OK )
1829     {
1830         if( bAbort )
1831             nStatus = GRFILTER_ABORT;
1832 
1833         ImplSetError( nStatus, &rIStream );
1834         rIStream.Seek( nStmBegin );
1835         rGraphic.Clear();
1836     }
1837 
1838     delete pFilterConfigItem;
1839     return nStatus;
1840 }
1841 
1842 
1843 // ------------------------------------------------------------------------
1844 
ExportGraphic(const Graphic & rGraphic,const INetURLObject & rPath,sal_uInt16 nFormat,const uno::Sequence<beans::PropertyValue> * pFilterData)1845 sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
1846     sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
1847 {
1848     sal_uInt16  nRetValue = GRFILTER_FORMATERROR;
1849     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1850     sal_Bool        bAlreadyExists = ImplDirEntryHelper::Exists( rPath );
1851 
1852     String      aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
1853     SvStream*   pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_WRITE | STREAM_TRUNC );
1854     if ( pStream )
1855     {
1856         nRetValue = ExportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pFilterData );
1857         delete pStream;
1858 
1859         if( ( GRFILTER_OK != nRetValue ) && !bAlreadyExists )
1860             ImplDirEntryHelper::Kill( aMainUrl );
1861     }
1862     return nRetValue;
1863 }
1864 
1865 // ------------------------------------------------------------------------
1866 
ExportGraphic(const Graphic & rGraphic,const String & rPath,SvStream & rOStm,sal_uInt16 nFormat,const uno::Sequence<beans::PropertyValue> * pFilterData)1867 sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& rPath,
1868     SvStream& rOStm, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
1869 {
1870     sal_uInt16 nFormatCount = GetExportFormatCount();
1871 
1872     ResetLastError();
1873     nExpGraphHint = 0;
1874 
1875     if( nFormat == GRFILTER_FORMAT_DONTKNOW )
1876     {
1877         INetURLObject aURL( rPath );
1878         String aExt( aURL.GetFileExtension().toAsciiUpperCase() );
1879 
1880 
1881         for( sal_uInt16 i = 0; i < nFormatCount; i++ )
1882         {
1883             if ( pConfig->GetExportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) )
1884             {
1885                 nFormat=i;
1886                 break;
1887             }
1888         }
1889     }
1890     if( nFormat >= nFormatCount )
1891         return (sal_uInt16) ImplSetError( GRFILTER_FORMATERROR );
1892 
1893     FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
1894     String aFilterName( pConfig->GetExportFilterName( nFormat ) );
1895 
1896     bAbort              = sal_False;
1897     sal_uInt16      nStatus = GRFILTER_OK;
1898     GraphicType eType;
1899     Graphic     aGraphic( rGraphic );
1900 
1901     aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem );
1902     eType = aGraphic.GetType();
1903 
1904     if( pConfig->IsExportPixelFormat( nFormat ) )
1905     {
1906         if( eType != GRAPHIC_BITMAP )
1907         {
1908             Size aSizePixel;
1909             sal_uLong nColorCount,nBitsPerPixel,nNeededMem,nMaxMem;
1910             VirtualDevice aVirDev;
1911 
1912             // Maximalen Speicherbedarf fuer das Bildes holen:
1913 //          if( GetOptionsConfig() )
1914 //              nMaxMem = (UINT32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32();
1915 //          else
1916                 nMaxMem = 1024;
1917 
1918             nMaxMem *= 1024; // In Bytes
1919 
1920             // Berechnen, wie gross das Bild normalerweise werden wuerde:
1921             aSizePixel=aVirDev.LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode());
1922 
1923             // Berechnen, wieviel Speicher das Bild benoetigen wuerde:
1924             nColorCount=aVirDev.GetColorCount();
1925             if      (nColorCount<=2)     nBitsPerPixel=1;
1926             else if (nColorCount<=4)     nBitsPerPixel=2;
1927             else if (nColorCount<=16)    nBitsPerPixel=4;
1928             else if (nColorCount<=256)   nBitsPerPixel=8;
1929             else if (nColorCount<=65536) nBitsPerPixel=16;
1930             else                         nBitsPerPixel=24;
1931             nNeededMem=((sal_uLong)aSizePixel.Width()*(sal_uLong)aSizePixel.Height()*nBitsPerPixel+7)/8;
1932 
1933             // ggf. Groesse des Bildes einschraenken:
1934             if (nMaxMem<nNeededMem)
1935             {
1936                 double fFak=sqrt(((double)nMaxMem)/((double)nNeededMem));
1937                 aSizePixel.Width()=(sal_uLong)(((double)aSizePixel.Width())*fFak);
1938                 aSizePixel.Height()=(sal_uLong)(((double)aSizePixel.Height())*fFak);
1939             }
1940 
1941             aVirDev.SetMapMode(MapMode(MAP_PIXEL));
1942             aVirDev.SetOutputSizePixel(aSizePixel);
1943             Graphic aGraphic2=aGraphic;
1944             aGraphic2.Draw(&aVirDev,Point(0,0),aSizePixel); // Gemein: dies aendert den MapMode
1945             aVirDev.SetMapMode(MapMode(MAP_PIXEL));
1946             aGraphic=Graphic(aVirDev.GetBitmap(Point(0,0),aSizePixel));
1947         }
1948     }
1949     if( rOStm.GetError() )
1950         nStatus = GRFILTER_IOERROR;
1951     if( GRFILTER_OK == nStatus )
1952     {
1953         if ( pConfig->IsExportInternalFilter( nFormat ) )
1954         {
1955             if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
1956             {
1957                 Bitmap aBmp( aGraphic.GetBitmap() );
1958                 sal_Int32 nColorRes = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Colors" ) ), 0 );
1959                 if ( nColorRes && ( nColorRes <= (sal_uInt16)BMP_CONVERSION_24BIT) )
1960                 {
1961                     if( !aBmp.Convert( (BmpConversion) nColorRes ) )
1962                         aBmp = aGraphic.GetBitmap();
1963                 }
1964                 ResMgr*     pResMgr = CREATERESMGR( svt );
1965                 sal_Bool    bRleCoding = aConfigItem.ReadBool( String( RTL_CONSTASCII_USTRINGPARAM( "RLE_Coding" ) ), sal_True );
1966                 // Wollen wir RLE-Kodiert speichern?
1967                 WriteDIB(aBmp, rOStm, bRleCoding, true);
1968                 delete pResMgr;
1969 
1970                 if( rOStm.GetError() )
1971                     nStatus = GRFILTER_IOERROR;
1972             }
1973             else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) )
1974             {
1975                 sal_Int32 nVersion = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), 0 ) ;
1976                 if ( nVersion )
1977                     rOStm.SetVersion( nVersion );
1978 
1979                 // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1980                 GDIMetaFile aMTF(aGraphic.GetGDIMetaFile());
1981 
1982                 aMTF.Write( rOStm );
1983 
1984                 if( rOStm.GetError() )
1985                     nStatus = GRFILTER_IOERROR;
1986             }
1987             else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) )
1988             {
1989                 // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1990                 if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
1991                     nStatus = GRFILTER_FORMATERROR;
1992 
1993                 if( rOStm.GetError() )
1994                     nStatus = GRFILTER_IOERROR;
1995             }
1996             else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) )
1997             {
1998                 // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1999                 if ( !ConvertGDIMetaFileToEMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
2000                     nStatus = GRFILTER_FORMATERROR;
2001 
2002                 if( rOStm.GetError() )
2003                     nStatus = GRFILTER_IOERROR;
2004             }
2005             else if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
2006             {
2007                 bool bExportedGrayJPEG = false;
2008                 if( !ExportJPEG( rOStm, aGraphic, pFilterData, &bExportedGrayJPEG ) )
2009                     nStatus = GRFILTER_FORMATERROR;
2010                 nExpGraphHint = bExportedGrayJPEG ? GRFILTER_OUTHINT_GREY : 0;
2011 
2012                 if( rOStm.GetError() )
2013                     nStatus = GRFILTER_IOERROR;
2014             }
2015             else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
2016             {
2017                 vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData );
2018                 if ( pFilterData )
2019                 {
2020                     sal_Int32 k, j, i = 0;
2021                     for ( i = 0; i < pFilterData->getLength(); i++ )
2022                     {
2023                         if ( (*pFilterData)[ i ].Name.equalsAscii( "AdditionalChunks" ) )
2024                         {
2025                             com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence;
2026                             if ( (*pFilterData)[ i ].Value >>= aAdditionalChunkSequence )
2027                             {
2028                                 for ( j = 0; j < aAdditionalChunkSequence.getLength(); j++ )
2029                                 {
2030                                     if ( aAdditionalChunkSequence[ j ].Name.getLength() == 4 )
2031                                     {
2032                                         sal_uInt32 nChunkType = 0;
2033                                         for ( k = 0; k < 4; k++ )
2034                                         {
2035                                             nChunkType <<= 8;
2036                                             nChunkType |= (sal_uInt8)aAdditionalChunkSequence[ j ].Name[ k ];
2037                                         }
2038                                         com::sun::star::uno::Sequence< sal_Int8 > aByteSeq;
2039                                         if ( aAdditionalChunkSequence[ j ].Value >>= aByteSeq )
2040                                         {
2041                                             std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks();
2042                                             if ( rChunkData.size() )
2043                                             {
2044                                                 sal_uInt32 nChunkLen = aByteSeq.getLength();
2045 
2046                                                 vcl::PNGWriter::ChunkData aChunkData;
2047                                                 aChunkData.nType = nChunkType;
2048                                                 if ( nChunkLen )
2049                                                 {
2050                                                     aChunkData.aData.resize( nChunkLen );
2051                                                     rtl_copyMemory( &aChunkData.aData[ 0 ], aByteSeq.getConstArray(), nChunkLen );
2052                                                 }
2053                                                 std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1;
2054                                                 rChunkData.insert( aIter, aChunkData );
2055                                             }
2056                                         }
2057                                     }
2058                                 }
2059                             }
2060                         }
2061                     }
2062                 }
2063                 aPNGWriter.Write( rOStm );
2064 
2065                 if( rOStm.GetError() )
2066                     nStatus = GRFILTER_IOERROR;
2067             }
2068             else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) )
2069             {
2070                 bool bDone(false);
2071 
2072                 // do we have a native SVG RenderGraphic, whose data can be written directly?
2073                 const SvgDataPtr aSvgDataPtr(rGraphic.getSvgData());
2074 
2075                 if(aSvgDataPtr.get() && aSvgDataPtr->getSvgDataArrayLength())
2076                 {
2077                     rOStm.Write(aSvgDataPtr->getSvgDataArray().get(), aSvgDataPtr->getSvgDataArrayLength());
2078 
2079                     if( rOStm.GetError() )
2080                     {
2081                         nStatus = GRFILTER_IOERROR;
2082                     }
2083                     else
2084                     {
2085                         bDone = true;
2086                     }
2087                 }
2088 
2089                 if( !bDone )
2090                 {
2091                     // do the normal GDIMetaFile export instead
2092                     try
2093                     {
2094                         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
2095 
2096                         if( xMgr.is() )
2097                         {
2098                             ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance(
2099                                 ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), ::com::sun::star::uno::UNO_QUERY );
2100 
2101                             com::sun::star::uno::Sequence< com::sun::star::uno::Any > aArguments( 1 );
2102                             aArguments[ 0 ] <<= aConfigItem.GetFilterData();
2103                             ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstanceWithArguments(
2104                                 ::rtl::OUString::createFromAscii( "com.sun.star.svg.SVGWriter" ), aArguments ), ::com::sun::star::uno::UNO_QUERY );
2105 
2106                             if( xSaxWriter.is() && xSVGWriter.is() )
2107                             {
2108                                 ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource(
2109                                     xSaxWriter, ::com::sun::star::uno::UNO_QUERY );
2110 
2111                                 if( xActiveDataSource.is() )
2112                                 {
2113                                     const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf(
2114                                         static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) );
2115 
2116                                     SvMemoryStream aMemStm( 65535, 65535 );
2117 
2118                                     aMemStm.SetCompressMode( COMPRESSMODE_FULL );
2119 
2120                                     // #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
2121                                     ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm );
2122 
2123                                     xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >(
2124                                         xStmIf, ::com::sun::star::uno::UNO_QUERY ) );
2125                                     ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() );
2126                                     xSVGWriter->write( xSaxWriter, aMtfSeq );
2127                                 }
2128                             }
2129                         }
2130                     }
2131                     catch( ::com::sun::star::uno::Exception& )
2132                     {
2133                         nStatus = GRFILTER_IOERROR;
2134                     }
2135                 }
2136             }
2137             else
2138                 nStatus = GRFILTER_FILTERERROR;
2139         }
2140         else
2141         {
2142             xub_StrLen i, nTokenCount = aFilterPath.GetTokenCount( ';' );
2143             for ( i = 0; i < nTokenCount; i++ )
2144             {
2145                 String aPhysicalName( ImpCreateFullFilterPath( aFilterPath.GetToken( i ), aFilterName ) );
2146                 osl::Module aLibrary( aPhysicalName );
2147 
2148                 PFilterCall pFunc = (PFilterCall) aLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) );
2149                 // Dialog in DLL ausfuehren
2150                 if( pFunc )
2151                 {
2152                     if ( !(*pFunc)( rOStm, aGraphic, &aConfigItem, sal_False ) )
2153                         nStatus = GRFILTER_FORMATERROR;
2154                     break;
2155                 }
2156                 else
2157                     nStatus = GRFILTER_FILTERERROR;
2158             }
2159         }
2160     }
2161     if( nStatus != GRFILTER_OK )
2162     {
2163         if( bAbort )
2164             nStatus = GRFILTER_ABORT;
2165 
2166         ImplSetError( nStatus, &rOStm );
2167     }
2168     return nStatus;
2169 }
2170 
2171 // ------------------------------------------------------------------------
2172 
Setup(sal_uInt16)2173 sal_Bool GraphicFilter::Setup( sal_uInt16 )
2174 {
2175     return sal_False;
2176 }
2177 
2178 /* ------------------------------------------------------------------------
2179     No Import filter has a dialog, so
2180    the following two methods are obsolete */
2181 
HasImportDialog(sal_uInt16)2182 sal_Bool GraphicFilter::HasImportDialog( sal_uInt16 )
2183 {
2184     return sal_True;
2185 //  return pConfig->IsImportDialog( nFormat );
2186 }
2187 
2188 // ------------------------------------------------------------------------
2189 
DoImportDialog(Window *,sal_uInt16)2190 sal_Bool GraphicFilter::DoImportDialog( Window*, sal_uInt16 )
2191 {
2192     return sal_True;
2193 }
2194 
2195 // ------------------------------------------------------------------------
2196 
HasExportDialog(sal_uInt16 nFormat)2197 sal_Bool GraphicFilter::HasExportDialog( sal_uInt16 nFormat )
2198 {
2199     return pConfig->IsExportDialog( nFormat );
2200 }
2201 
2202 // ------------------------------------------------------------------------
2203 
DoExportDialog(Window * pWindow,sal_uInt16 nFormat)2204 sal_Bool GraphicFilter::DoExportDialog( Window* pWindow, sal_uInt16 nFormat )
2205 {
2206     return DoExportDialog( pWindow, nFormat, FUNIT_MM );
2207 }
2208 
DoExportDialog(Window *,sal_uInt16 nFormat,FieldUnit)2209 sal_Bool GraphicFilter::DoExportDialog( Window*, sal_uInt16 nFormat, FieldUnit )
2210 {
2211     sal_Bool bRet = sal_False;
2212     com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
2213         xSMgr( ::comphelper::getProcessServiceFactory() );
2214 
2215     uno::Reference< com::sun::star::uno::XInterface > xFilterOptionsDialog
2216         ( xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.svtools.SvFilterOptionsDialog" ) ),
2217             com::sun::star::uno::UNO_QUERY );
2218     if ( xFilterOptionsDialog.is() )
2219     {
2220         com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XExecutableDialog > xExecutableDialog
2221             ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
2222         com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xPropertyAccess
2223             ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY );
2224         if ( xExecutableDialog.is() && xPropertyAccess.is() )
2225         {
2226             com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aMediaDescriptor( 1 );
2227             aMediaDescriptor[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
2228             rtl::OUString aStr( pConfig->GetExportInternalFilterName( nFormat ) );
2229             aMediaDescriptor[ 0 ].Value <<= aStr;
2230             xPropertyAccess->setPropertyValues( aMediaDescriptor );
2231             bRet = xExecutableDialog->execute() == com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
2232         }
2233     }
2234     return bRet;
2235 }
2236 
2237 // ------------------------------------------------------------------------
2238 
GetLastError() const2239 const FilterErrorEx& GraphicFilter::GetLastError() const
2240 {
2241     return *pErrorEx;
2242 }
2243 
2244 // ------------------------------------------------------------------------
2245 
ResetLastError()2246 void GraphicFilter::ResetLastError()
2247 {
2248     pErrorEx->nFilterError = pErrorEx->nStreamError = 0UL;
2249 }
2250 
2251 // ------------------------------------------------------------------------
2252 
GetFilterCallback() const2253 const Link GraphicFilter::GetFilterCallback() const
2254 {
2255     const Link aLink( LINK( this, GraphicFilter, FilterCallback ) );
2256     return aLink;
2257 }
2258 
2259 // ------------------------------------------------------------------------
2260 
IMPL_LINK(GraphicFilter,FilterCallback,ConvertData *,pData)2261 IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData )
2262 {
2263     long nRet = 0L;
2264 
2265     if( pData )
2266     {
2267         sal_uInt16      nFormat = GRFILTER_FORMAT_DONTKNOW;
2268         ByteString  aShortName;
2269         switch( pData->mnFormat )
2270         {
2271             case( CVT_BMP ): aShortName = BMP_SHORTNAME; break;
2272             case( CVT_GIF ): aShortName = GIF_SHORTNAME; break;
2273             case( CVT_JPG ): aShortName = JPG_SHORTNAME; break;
2274             case( CVT_MET ): aShortName = MET_SHORTNAME; break;
2275             case( CVT_PCT ): aShortName = PCT_SHORTNAME; break;
2276             case( CVT_PNG ): aShortName = PNG_SHORTNAME; break;
2277             case( CVT_SVM ): aShortName = SVM_SHORTNAME; break;
2278             case( CVT_TIF ): aShortName = TIF_SHORTNAME; break;
2279             case( CVT_WMF ): aShortName = WMF_SHORTNAME; break;
2280             case( CVT_EMF ): aShortName = EMF_SHORTNAME; break;
2281             case( CVT_SVG ): aShortName = SVG_SHORTNAME; break;
2282 
2283             default:
2284             break;
2285         }
2286         if( GRAPHIC_NONE == pData->maGraphic.GetType() || pData->maGraphic.GetContext() ) // Import
2287         {
2288             // Import
2289             nFormat = GetImportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
2290             nRet = ImportGraphic( pData->maGraphic, String(), pData->mrStm ) == 0;
2291         }
2292         else if( aShortName.Len() )
2293         {
2294             // Export
2295             nFormat = GetExportFormatNumberForShortName( String( aShortName.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
2296             nRet = ExportGraphic( pData->maGraphic, String(), pData->mrStm, nFormat ) == 0;
2297         }
2298     }
2299     return nRet;
2300 }
2301 
2302 // ------------------------------------------------------------------------
2303 
GetGraphicFilter()2304 GraphicFilter* GraphicFilter::GetGraphicFilter()
2305 {
2306     if( !pGraphicFilter )
2307     {
2308         pGraphicFilter = new GraphicFilter;
2309         pGraphicFilter->GetImportFormatCount();
2310     }
2311     return pGraphicFilter;
2312 }
2313 
LoadGraphic(const String & rPath,const String & rFilterName,Graphic & rGraphic,GraphicFilter * pFilter,sal_uInt16 * pDeterminedFormat)2314 int GraphicFilter::LoadGraphic( const String &rPath, const String &rFilterName,
2315                  Graphic& rGraphic, GraphicFilter* pFilter,
2316                  sal_uInt16* pDeterminedFormat )
2317 {
2318     if ( !pFilter )
2319         pFilter = GetGraphicFilter();
2320 
2321     const sal_uInt16 nFilter = rFilterName.Len() && pFilter->GetImportFormatCount()
2322                     ? pFilter->GetImportFormatNumber( rFilterName )
2323                     : GRFILTER_FORMAT_DONTKNOW;
2324 
2325     SvStream* pStream = NULL;
2326     INetURLObject aURL( rPath );
2327 
2328     if ( aURL.HasError() || INET_PROT_NOT_VALID == aURL.GetProtocol() )
2329     {
2330         aURL.SetSmartProtocol( INET_PROT_FILE );
2331         aURL.SetSmartURL( rPath );
2332     }
2333     else if ( INET_PROT_FILE != aURL.GetProtocol() )
2334     {
2335         pStream = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
2336     }
2337 
2338     int nRes = GRFILTER_OK;
2339     if ( !pStream )
2340         nRes = pFilter->ImportGraphic( rGraphic, aURL, nFilter, pDeterminedFormat );
2341     else
2342         nRes = pFilter->ImportGraphic( rGraphic, rPath, *pStream, nFilter, pDeterminedFormat );
2343 
2344 #ifdef DBG_UTIL
2345     if( nRes )
2346         DBG_WARNING2( "GrafikFehler [%d] - [%s]", nRes, rPath.GetBuffer() );
2347 #endif
2348 
2349     return nRes;
2350 }
2351