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