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