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