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