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