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