1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/mutex.hxx>
21 #include <comphelper/processfactory.hxx>
22 #include <comphelper/string.hxx>
23 #include <ucbhelper/content.hxx>
24 #include <cppuhelper/implbase1.hxx>
25 #include <tools/urlobj.hxx>
26 #include <vcl/salctype.hxx>
27 #include <vcl/pngread.hxx>
28 #include <vcl/pngwrite.hxx>
29 #include <vcl/svgdata.hxx>
30 #include <vcl/virdev.hxx>
31 #include <vcl/svapp.hxx>
32 #include <osl/file.hxx>
33 #include <vcl/graphicfilter.hxx>
34 #include <vcl/FilterConfigItem.hxx>
35 #include <vcl/wmf.hxx>
36 #include "igif/gifread.hxx"
37 #include "jpeg/jpeg.hxx"
38 #include "ixbm/xbmread.hxx"
39 #include "ixpm/xpmread.hxx"
40 #include "sgffilt.hxx"
41 #include "osl/module.hxx"
42 #include <com/sun/star/uno/Reference.h>
43 #include <com/sun/star/awt/Size.hpp>
44 #include <com/sun/star/uno/XInterface.hpp>
45 #include <com/sun/star/uno/XWeak.hpp>
46 #include <com/sun/star/uno/XAggregation.hpp>
47 #include <com/sun/star/lang/XTypeProvider.hpp>
48 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <com/sun/star/io/XActiveDataSource.hpp>
50 #include <com/sun/star/io/XOutputStream.hpp>
51 #include <com/sun/star/svg/XSVGWriter.hpp>
52 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
53 #include <com/sun/star/xml/sax/Writer.hpp>
54 #include <com/sun/star/ucb/CommandAbortedException.hpp>
55 #include <unotools/ucbstreamhelper.hxx>
56 #include <unotools/localfilehelper.hxx>
57 #include <rtl/bootstrap.hxx>
58 #include <rtl/instance.hxx>
59 #include <rtl/logfile.hxx>
60 #include <vcl/metaact.hxx>
63 #include "FilterConfigCache.hxx"
65 #define PMGCHUNG_msOG 0x6d734f47 // Microsoft Office Animated GIF
67 #ifndef DISABLE_DYNLOADING
68 #define IMPORT_FUNCTION_NAME "GraphicImport"
69 #define EXPORT_FUNCTION_NAME "GraphicExport"
72 using namespace ::rtl
;
73 using namespace ::com::sun::star
;
75 using comphelper::string::getTokenCount
;
76 using comphelper::string::getToken
;
78 typedef ::std::vector
< GraphicFilter
* > FilterList_impl
;
79 static FilterList_impl
* pFilterHdlList
= NULL
;
81 static ::osl::Mutex
& getListMutex()
83 static ::osl::Mutex s_aListProtection
;
84 return s_aListProtection
;
87 class ImpFilterOutputStream
: public ::cppu::WeakImplHelper1
< css::io::XOutputStream
>
93 virtual void SAL_CALL
writeBytes( const css::uno::Sequence
< sal_Int8
>& rData
)
94 throw (css::io::NotConnectedException
, css::io::BufferSizeExceededException
, css::io::IOException
, css::uno::RuntimeException
)
95 { mrStm
.Write( rData
.getConstArray(), rData
.getLength() ); }
96 virtual void SAL_CALL
flush()
97 throw (css::io::NotConnectedException
, css::io::BufferSizeExceededException
, css::io::IOException
, css::uno::RuntimeException
)
99 virtual void SAL_CALL
closeOutput() throw() {}
103 ImpFilterOutputStream( SvStream
& rStm
) : mrStm( rStm
) {}
104 ~ImpFilterOutputStream() {}
107 #ifndef DISABLE_EXPORT
109 static sal_Bool
DirEntryExists( const INetURLObject
& rObj
)
111 sal_Bool bExists
= sal_False
;
115 ::ucbhelper::Content
aCnt( rObj
.GetMainURL( INetURLObject::NO_DECODE
),
116 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
117 comphelper::getProcessComponentContext() );
119 bExists
= aCnt
.isDocument();
121 catch(const css::ucb::CommandAbortedException
&)
123 SAL_WARN( "svtools.filter", "CommandAbortedException" );
125 catch(const css::ucb::ContentCreationException
&)
127 SAL_WARN( "svtools.filter", "ContentCreationException" );
131 SAL_WARN( "svtools.filter", "Any other exception" );
136 static void KillDirEntry( const String
& rMainUrl
)
140 ::ucbhelper::Content
aCnt( rMainUrl
,
141 css::uno::Reference
< css::ucb::XCommandEnvironment
>(),
142 comphelper::getProcessComponentContext() );
144 aCnt
.executeCommand( "delete",
145 css::uno::makeAny( sal_Bool( sal_True
) ) );
147 catch(const css::ucb::CommandAbortedException
&)
149 SAL_WARN( "svtools.filter", "CommandAbortedException" );
153 SAL_WARN( "svtools.filter", "Any other exception" );
157 #endif // !DISABLE_EXPORT
161 sal_uInt8
* ImplSearchEntry( sal_uInt8
* pSource
, sal_uInt8
* pDest
, sal_uLong nComp
, sal_uLong nSize
)
163 while ( nComp
-- >= nSize
)
166 for ( i
= 0; i
< nSize
; i
++ )
168 if ( ( pSource
[i
]&~0x20 ) != ( pDest
[i
]&~0x20 ) )
179 inline String
ImpGetExtension( const String
&rPath
)
182 INetURLObject
aURL( rPath
);
183 aExt
= aURL
.GetFileExtension().toAsciiUpperCase();
187 bool isPCT(SvStream
& rStream
, sal_uLong nStreamPos
, sal_uLong nStreamLen
)
190 // store number format
191 sal_uInt16 oldNumberFormat
= rStream
.GetNumberFormatInt();
192 sal_uInt32 nOffset
; // in MS documents the pict format is used without the first 512 bytes
193 for ( nOffset
= 0; ( nOffset
<= 512 ) && ( ( nStreamPos
+ nOffset
+ 14 ) <= nStreamLen
); nOffset
+= 512 )
196 sal_Bool bdBoxOk
= sal_True
;
198 rStream
.Seek( nStreamPos
+ nOffset
);
199 // size of the pict in version 1 pict ( 2bytes) : ignored
201 // bounding box (bytes 2 -> 9)
202 rStream
.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN
);
203 rStream
>> y1
>> x1
>> y2
>> x2
;
204 rStream
.SetNumberFormatInt(oldNumberFormat
); // reset format
206 if (x1
> x2
|| y1
> y2
|| // bad bdbox
207 (x1
== x2
&& y1
== y2
) || // 1 pixel picture
208 x2
-x1
> 2048 || y2
-y1
> 2048 ) // picture anormaly big
212 rStream
.Read( sBuf
,3 );
213 // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
214 // normal version 2 - page A23 and A24
215 if ( sBuf
[ 0 ] == 0x00 && sBuf
[ 1 ] == 0x11 && sBuf
[ 2 ] == 0x02)
217 // normal version 1 - page A25
218 else if (sBuf
[ 0 ] == 0x11 && sBuf
[ 1 ] == 0x01 && bdBoxOk
)
225 /*************************************************************************
227 * ImpPeekGraphicFormat()
230 * This function is two-fold:
231 * 1.) Start reading file, determine the file format:
234 * rFormatExtension - content matter
235 * bTest - set sal_False
237 * Return value - sal_True if success
238 * rFormatExtension - on success: normal file extension in capitals
239 * 2.) Start reading file, verify file format
242 * rFormatExtension - normal file extension in capitals
243 * bTest - set sal_True
245 * Return value - sal_False, if cannot verify the file type
246 * passed to the function
247 * sal_True, when the format is PROBABLY verified or
248 * WHEN THE FORMAT IS NOT KNOWN!
250 *************************************************************************/
252 static sal_Bool
ImpPeekGraphicFormat( SvStream
& rStream
, String
& rFormatExtension
, sal_Bool bTest
)
255 sal_uInt8 sFirstBytes
[ 256 ];
256 sal_uLong nFirstLong
,nSecondLong
;
257 sal_uLong nStreamPos
= rStream
.Tell();
259 rStream
.Seek( STREAM_SEEK_TO_END
);
260 sal_uLong nStreamLen
= rStream
.Tell() - nStreamPos
;
261 rStream
.Seek( nStreamPos
);
265 SvLockBytes
* pLockBytes
= rStream
.GetLockBytes();
267 pLockBytes
->SetSynchronMode( sal_True
);
269 rStream
.Seek( STREAM_SEEK_TO_END
);
270 nStreamLen
= rStream
.Tell() - nStreamPos
;
271 rStream
.Seek( nStreamPos
);
275 return false; // this prevents at least a STL assertion
277 else if (nStreamLen
>= 256)
278 { // load first 256 bytes into a buffer
279 rStream
.Read( sFirstBytes
, 256 );
283 rStream
.Read( sFirstBytes
, nStreamLen
);
285 for( i
= (sal_uInt16
) nStreamLen
; i
< 256; i
++ )
289 if( rStream
.GetError() )
292 // Accommodate the first 8 bytes in nFirstLong, nSecondLong
294 for( i
= 0, nFirstLong
= 0L, nSecondLong
= 0L; i
< 4; i
++ )
296 nFirstLong
=(nFirstLong
<<8)|(sal_uLong
)sFirstBytes
[i
];
297 nSecondLong
=(nSecondLong
<<8)|(sal_uLong
)sFirstBytes
[i
+4];
300 // The following variable is used when bTest == sal_True. It remains sal_False
301 // if the format (rFormatExtension) has not yet been set.
302 sal_Bool bSomethingTested
= sal_False
;
304 // Now the different formats are checked. The order *does* matter. e.g. a MET file
305 // could also go through the BMP test, howeve a BMP file can hardly go through the MET test.
306 // So MET should be tested prior to BMP. However, theoretically a BMP file could conceivably
307 // go through the MET test. These problems are of course not only in MET and BMP.
308 // Therefore, in the case of a format check (bTest == sal_True) we only test *exactly* this
309 // format. Everything else could have fatal consequences, for example if the user says it is
310 // a BMP file (and it is a BMP) file, and the file would go through the MET test ...
311 //--------------------------- MET ------------------------------------
312 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "MET", 3 ) == COMPARE_EQUAL
) )
314 bSomethingTested
=sal_True
;
315 if( sFirstBytes
[2] == 0xd3 )
317 rStream
.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN
);
318 rStream
.Seek( nStreamPos
);
319 sal_uInt16 nFieldSize
;
321 sal_Bool bOK
=sal_True
;
322 rStream
>> nFieldSize
>> nMagic
;
323 for (i
=0; i
<3; i
++) {
324 if (nFieldSize
<6) { bOK
=sal_False
; break; }
325 if (nStreamLen
< rStream
.Tell() + nFieldSize
) { bOK
=sal_False
; break; }
326 rStream
.SeekRel(nFieldSize
-3);
327 rStream
>> nFieldSize
>> nMagic
;
328 if (nMagic
!=0xd3) { bOK
=sal_False
; break; }
330 rStream
.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
331 if (bOK
&& !rStream
.GetError()) {
332 rFormatExtension
= OUString("MET");
338 //--------------------------- BMP ------------------------------------
339 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "BMP", 3 ) == COMPARE_EQUAL
) )
343 bSomethingTested
=sal_True
;
345 // We're possibly also able to read an OS/2 bitmap array
346 // ('BA'), therefore we must adjust the offset to discover the
347 // first bitmap in the array
348 if ( sFirstBytes
[0] == 0x42 && sFirstBytes
[1] == 0x41 )
353 // Now we initially test on 'BM'
354 if ( sFirstBytes
[0+nOffs
]==0x42 && sFirstBytes
[1+nOffs
]==0x4d )
357 // OS/2 can set the Reserved flags to a value other than 0
358 // (which they really should not do...);
359 // In this case we test the size of the BmpInfoHeaders
360 if ( ( sFirstBytes
[6+nOffs
]==0x00 &&
361 sFirstBytes
[7+nOffs
]==0x00 &&
362 sFirstBytes
[8+nOffs
]==0x00 &&
363 sFirstBytes
[9+nOffs
]==0x00 ) ||
364 sFirstBytes
[14+nOffs
] == 0x28 ||
365 sFirstBytes
[14+nOffs
] == 0x0c )
367 rFormatExtension
= OUString("BMP");
373 //--------------------------- WMF/EMF ------------------------------------
376 ( rFormatExtension
.CompareToAscii( "WMF", 3 ) == COMPARE_EQUAL
) ||
377 ( rFormatExtension
.CompareToAscii( "EMF", 3 ) == COMPARE_EQUAL
) )
379 bSomethingTested
= sal_True
;
381 if ( nFirstLong
==0xd7cdc69a || nFirstLong
==0x01000900 )
383 rFormatExtension
= OUString("WMF");
386 else if( nFirstLong
== 0x01000000 && sFirstBytes
[ 40 ] == 0x20 && sFirstBytes
[ 41 ] == 0x45 &&
387 sFirstBytes
[ 42 ] == 0x4d && sFirstBytes
[ 43 ] == 0x46 )
389 rFormatExtension
= OUString("EMF");
394 //--------------------------- PCX ------------------------------------
395 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "PCX", 3 ) == COMPARE_EQUAL
) )
397 bSomethingTested
=sal_True
;
398 if (sFirstBytes
[0]==0x0a)
400 sal_uInt8 nVersion
=sFirstBytes
[1];
401 sal_uInt8 nEncoding
=sFirstBytes
[2];
402 if( ( nVersion
==0 || nVersion
==2 || nVersion
==3 || nVersion
==5 ) && nEncoding
<=1 )
404 rFormatExtension
= OUString("PCX");
410 //--------------------------- TIF ------------------------------------
411 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "TIF", 3 ) == COMPARE_EQUAL
) )
413 bSomethingTested
=sal_True
;
414 if ( nFirstLong
==0x49492a00 || nFirstLong
==0x4d4d002a )
416 rFormatExtension
= OUString("TIF");
421 //--------------------------- GIF ------------------------------------
422 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "GIF", 3 ) == COMPARE_EQUAL
) )
424 bSomethingTested
=sal_True
;
425 if ( nFirstLong
==0x47494638 && (sFirstBytes
[4]==0x37 || sFirstBytes
[4]==0x39) && sFirstBytes
[5]==0x61 )
427 rFormatExtension
= OUString("GIF");
432 //--------------------------- PNG ------------------------------------
433 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "PNG", 3 ) == COMPARE_EQUAL
) )
435 bSomethingTested
=sal_True
;
436 if (nFirstLong
==0x89504e47 && nSecondLong
==0x0d0a1a0a)
438 rFormatExtension
= OUString("PNG");
443 //--------------------------- JPG ------------------------------------
444 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "JPG", 3 ) == COMPARE_EQUAL
) )
446 bSomethingTested
=sal_True
;
447 if ( ( nFirstLong
==0xffd8ffe0 && sFirstBytes
[6]==0x4a && sFirstBytes
[7]==0x46 && sFirstBytes
[8]==0x49 && sFirstBytes
[9]==0x46 ) ||
448 ( nFirstLong
==0xffd8fffe ) || ( 0xffd8ff00 == ( nFirstLong
& 0xffffff00 ) ) )
450 rFormatExtension
= OUString("JPG");
455 //--------------------------- SVM ------------------------------------
456 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "SVM", 3 ) == COMPARE_EQUAL
) )
458 bSomethingTested
=sal_True
;
459 if( nFirstLong
==0x53564744 && sFirstBytes
[4]==0x49 )
461 rFormatExtension
= OUString("SVM");
464 else if( sFirstBytes
[0]==0x56 && sFirstBytes
[1]==0x43 && sFirstBytes
[2]==0x4C &&
465 sFirstBytes
[3]==0x4D && sFirstBytes
[4]==0x54 && sFirstBytes
[5]==0x46 )
467 rFormatExtension
= OUString("SVM");
472 //--------------------------- PCD ------------------------------------
473 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "PCD", 3 ) == COMPARE_EQUAL
) )
475 bSomethingTested
= sal_True
;
476 if( nStreamLen
>= 2055 )
479 rStream
.Seek( nStreamPos
+ 2048 );
480 rStream
.Read( sBuf
, 7 );
482 if( strncmp( sBuf
, "PCD_IPI", 7 ) == 0 )
484 rFormatExtension
= OUString("PCD");
490 //--------------------------- PSD ------------------------------------
491 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "PSD", 3 ) == COMPARE_EQUAL
) )
493 bSomethingTested
= sal_True
;
494 if ( ( nFirstLong
== 0x38425053 ) && ( (nSecondLong
>> 16 ) == 1 ) )
496 rFormatExtension
= OUString("PSD");
501 //--------------------------- EPS ------------------------------------
502 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "EPS", 3 ) == COMPARE_EQUAL
) )
504 bSomethingTested
= sal_True
;
505 if ( ( nFirstLong
== 0xC5D0D3C6 ) || ( ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"%!PS-Adobe", 10, 10 ) &&
506 ImplSearchEntry( &sFirstBytes
[15], (sal_uInt8
*)"EPS", 3, 3 ) ) )
508 rFormatExtension
= OUString("EPS");
513 //--------------------------- DXF ------------------------------------
514 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "DXF", 3 ) == COMPARE_EQUAL
) )
516 // Binary DXF File Format
517 if( strncmp( (const char*) sFirstBytes
, "AutoCAD Binary DXF", 18 ) == 0 )
519 rFormatExtension
= OUString("DXF");
523 // ASCII DXF File Format
525 while (i
<256 && sFirstBytes
[i
]<=32)
528 if (i
<256 && sFirstBytes
[i
]=='0')
532 // only now do we have sufficient data to make a judgement
533 // based on a '0' + 'SECTION' == DXF argument
534 bSomethingTested
=sal_True
;
536 while( i
<256 && sFirstBytes
[i
]<=32 )
539 if (i
+7<256 && (strncmp((const char*)(sFirstBytes
+i
),"SECTION",7)==0))
541 rFormatExtension
= OUString("DXF");
548 //--------------------------- PCT ------------------------------------
549 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "PCT", 3 ) == COMPARE_EQUAL
) )
551 bSomethingTested
= sal_True
;
552 if (isPCT(rStream
, nStreamPos
, nStreamLen
))
554 rFormatExtension
= OUString("PCT");
559 //------------------------- PBM + PGM + PPM ---------------------------
561 ( rFormatExtension
.CompareToAscii( "PBM", 3 ) == COMPARE_EQUAL
) ||
562 ( rFormatExtension
.CompareToAscii( "PGM", 3 ) == COMPARE_EQUAL
) ||
563 ( rFormatExtension
.CompareToAscii( "PPM", 3 ) == COMPARE_EQUAL
) )
565 bSomethingTested
=sal_True
;
566 if ( sFirstBytes
[ 0 ] == 'P' )
568 switch( sFirstBytes
[ 1 ] )
572 rFormatExtension
= OUString("PBM");
577 rFormatExtension
= OUString("PGM");
582 rFormatExtension
= OUString("PPM");
588 //--------------------------- RAS( SUN RasterFile )------------------
589 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "RAS", 3 ) == COMPARE_EQUAL
) )
591 bSomethingTested
=sal_True
;
592 if( nFirstLong
== 0x59a66a95 )
594 rFormatExtension
= OUString("RAS");
599 //--------------------------- XPM ------------------------------------
602 bSomethingTested
= sal_True
;
603 if( ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"/* XPM */", 256, 9 ) )
605 rFormatExtension
= OUString("XPM");
609 else if( rFormatExtension
.CompareToAscii( "XPM", 3 ) == COMPARE_EQUAL
)
611 bSomethingTested
= sal_True
;
615 //--------------------------- XBM ------------------------------------
618 sal_uLong nSize
= ( nStreamLen
> 2048 ) ? 2048 : nStreamLen
;
619 sal_uInt8
* pBuf
= new sal_uInt8
[ nSize
];
621 rStream
.Seek( nStreamPos
);
622 rStream
.Read( pBuf
, nSize
);
623 sal_uInt8
* pPtr
= ImplSearchEntry( pBuf
, (sal_uInt8
*)"#define", nSize
, 7 );
627 if( ImplSearchEntry( pPtr
, (sal_uInt8
*)"_width", pBuf
+ nSize
- pPtr
, 6 ) )
629 rFormatExtension
= OUString("XBM");
636 else if( rFormatExtension
.CompareToAscii( "XBM", 3 ) == COMPARE_EQUAL
)
638 bSomethingTested
= sal_True
;
642 //--------------------------- SVG ------------------------------------
646 if( ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"<?xml", 256, 5 ) // is it xml
647 && ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"version", 256, 7 )) // does it have a version (required for xml)
651 // check for DOCTYPE svg combination
652 if( ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"DOCTYPE", 256, 7 ) // 'DOCTYPE' is there
653 && ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"svg", 256, 3 )) // 'svg' is there
658 // check for svg element in 1st 256 bytes
659 if(!bIsSvg
&& ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"<svg", 256, 4 )) // '<svg'
666 // it's a xml, look for '<svg' in full file. Should not happen too
667 // often since the tests above will handle most cases, but can happen
668 // with Svg files containing big comment headers or Svg as the host
670 const sal_uLong
nSize((nStreamLen
> 2048) ? 2048 : nStreamLen
);
671 sal_uInt8
* pBuf
= new sal_uInt8
[nSize
];
673 rStream
.Seek(nStreamPos
);
674 rStream
.Read(pBuf
, nSize
);
676 if(ImplSearchEntry(pBuf
, (sal_uInt8
*)"<svg", nSize
, 4)) // '<svg'
686 rFormatExtension
= OUString( "SVG" );
692 // #119176# SVG files which have no xml header at all have shown up,
696 // check for svg element in 1st 256 bytes
697 if(ImplSearchEntry( sFirstBytes
, (sal_uInt8
*)"<svg", 256, 4 )) // '<svg'
704 // look for '<svg' in full file. Should not happen too
705 // often since the tests above will handle most cases, but can happen
706 // with SVG files containing big comment headers or SVG as the host
708 const sal_uLong
nSize((nStreamLen
> 2048) ? 2048 : nStreamLen
);
709 sal_uInt8
* pBuf
= new sal_uInt8
[nSize
];
711 rStream
.Seek(nStreamPos
);
712 rStream
.Read(pBuf
, nSize
);
714 if(ImplSearchEntry(pBuf
, (sal_uInt8
*)"<svg", nSize
, 4)) // '<svg'
724 rFormatExtension
= OUString( "SVG" );
729 else if( rFormatExtension
.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL
)
731 bSomethingTested
= sal_True
;
735 //--------------------------- TGA ------------------------------------
736 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL
) )
738 bSomethingTested
= sal_True
;
740 // just a simple test for the extension
741 if( rFormatExtension
.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL
)
745 //--------------------------- SGV ------------------------------------
746 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL
) )
748 bSomethingTested
= sal_True
;
750 // just a simple test for the extension
751 if( rFormatExtension
.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL
)
755 //--------------------------- SGF ------------------------------------
756 if( !bTest
|| ( rFormatExtension
.CompareToAscii( "SGF", 3 ) == COMPARE_EQUAL
) )
758 bSomethingTested
=sal_True
;
759 if( sFirstBytes
[ 0 ] == 'J' && sFirstBytes
[ 1 ] == 'J' )
761 rFormatExtension
= OUString("SGF");
766 return bTest
&& !bSomethingTested
;
769 //--------------------------------------------------------------------------
771 sal_uInt16
GraphicFilter::ImpTestOrFindFormat( const String
& rPath
, SvStream
& rStream
, sal_uInt16
& rFormat
)
773 // determine or check the filter/format by reading into it
774 if( rFormat
== GRFILTER_FORMAT_DONTKNOW
)
777 if( ImpPeekGraphicFormat( rStream
, aFormatExt
, sal_False
) )
779 rFormat
= pConfig
->GetImportFormatNumberForExtension( aFormatExt
);
780 if( rFormat
!= GRFILTER_FORMAT_DONTKNOW
)
783 // determine filter by file extension
786 String
aExt( ImpGetExtension( rPath
) );
787 rFormat
= pConfig
->GetImportFormatNumberForExtension( aExt
);
788 if( rFormat
!= GRFILTER_FORMAT_DONTKNOW
)
791 return GRFILTER_FORMATERROR
;
795 String
aTmpStr( pConfig
->GetImportFormatExtension( rFormat
) );
796 if( !ImpPeekGraphicFormat( rStream
, aTmpStr
.ToUpperAscii(), sal_True
) )
797 return GRFILTER_FORMATERROR
;
798 if ( pConfig
->GetImportFormatExtension( rFormat
).EqualsIgnoreCaseAscii( "pcd" ) )
800 sal_Int32 nBase
= 2; // default Base0
801 if ( pConfig
->GetImportFilterType( rFormat
).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base4" ) )
803 else if ( pConfig
->GetImportFilterType( rFormat
).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base16" ) )
805 String
aFilterConfigPath( "Office.Common/Filter/Graphic/Import/PCD" );
806 FilterConfigItem
aFilterConfigItem( aFilterConfigPath
);
807 aFilterConfigItem
.WriteInt32( "Resolution", nBase
);
814 //--------------------------------------------------------------------------
816 #ifndef DISABLE_EXPORT
818 static Graphic
ImpGetScaledGraphic( const Graphic
& rGraphic
, FilterConfigItem
& rConfigItem
)
822 ResMgr
* pResMgr
= ResMgr::CreateResMgr( "svt", Application::GetSettings().GetUILanguageTag() );
824 sal_Int32 nLogicalWidth
= rConfigItem
.ReadInt32( "LogicalWidth", 0 );
825 sal_Int32 nLogicalHeight
= rConfigItem
.ReadInt32( "LogicalHeight", 0 );
827 if ( rGraphic
.GetType() != GRAPHIC_NONE
)
829 sal_Int32 nMode
= rConfigItem
.ReadInt32( "ExportMode", -1 );
831 if ( nMode
== -1 ) // the property is not there, this is possible, if the graphic filter
832 { // is called via UnoGraphicExporter and not from a graphic export Dialog
833 nMode
= 0; // then we are defaulting this mode to 0
834 if ( nLogicalWidth
|| nLogicalHeight
)
840 Size
aPrefSize( rGraphic
.GetPrefSize() );
841 MapMode
aPrefMapMode( rGraphic
.GetPrefMapMode() );
842 if ( aPrefMapMode
== MAP_PIXEL
)
843 aOriginalSize
= Application::GetDefaultDevice()->PixelToLogic( aPrefSize
, MAP_100TH_MM
);
845 aOriginalSize
= Application::GetDefaultDevice()->LogicToLogic( aPrefSize
, aPrefMapMode
, MAP_100TH_MM
);
846 if ( !nLogicalWidth
)
847 nLogicalWidth
= aOriginalSize
.Width();
848 if ( !nLogicalHeight
)
849 nLogicalHeight
= aOriginalSize
.Height();
850 if( rGraphic
.GetType() == GRAPHIC_BITMAP
)
856 Bitmap
aBitmap( rGraphic
.GetBitmap() );
857 MapMode
aMap( MAP_100TH_INCH
);
859 sal_Int32 nDPI
= rConfigItem
.ReadInt32( "Resolution", 75 );
860 Fraction
aFrac( 1, std::min( std::max( nDPI
, sal_Int32( 75 ) ), sal_Int32( 600 ) ) );
862 aMap
.SetScaleX( aFrac
);
863 aMap
.SetScaleY( aFrac
);
865 Size aOldSize
= aBitmap
.GetSizePixel();
867 aGraphic
.SetPrefMapMode( aMap
);
868 aGraphic
.SetPrefSize( Size( aOldSize
.Width() * 100,
869 aOldSize
.Height() * 100 ) );
872 else if( nMode
== 2 )
875 aGraphic
.SetPrefMapMode( MapMode( MAP_100TH_MM
) );
876 aGraphic
.SetPrefSize( Size( nLogicalWidth
, nLogicalHeight
) );
881 sal_Int32 nColors
= rConfigItem
.ReadInt32( "Color", 0 ); // #92767#
882 if ( nColors
) // graphic conversion necessary ?
884 BitmapEx
aBmpEx( aGraphic
.GetBitmapEx() );
885 aBmpEx
.Convert( (BmpConversion
)nColors
); // the entries in the xml section have the same meaning as
886 aGraphic
= aBmpEx
; // they have in the BmpConversion enum, so it should be
887 } // allowed to cast them
891 if( ( nMode
== 1 ) || ( nMode
== 2 ) )
893 GDIMetaFile
aMtf( rGraphic
.GetGDIMetaFile() );
894 css::awt::Size
aDefaultSize( 10000, 10000 );
895 Size
aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth
, nLogicalHeight
), MAP_100TH_MM
, aMtf
.GetPrefMapMode() ) );
897 if( aNewSize
.Width() && aNewSize
.Height() )
899 const Size
aPreferredSize( aMtf
.GetPrefSize() );
900 aMtf
.Scale( Fraction( aNewSize
.Width(), aPreferredSize
.Width() ),
901 Fraction( aNewSize
.Height(), aPreferredSize
.Height() ) );
903 aGraphic
= Graphic( aMtf
);
920 static String
ImpCreateFullFilterPath( const String
& rPath
, const String
& rFilterName
)
924 ::osl::FileBase::getFileURLFromSystemPath( rPath
, aPathURL
);
925 aPathURL
+= OUString( '/' );
927 OUString aSystemPath
;
928 ::osl::FileBase::getSystemPathFromFileURL( aPathURL
, aSystemPath
);
929 aSystemPath
+= OUString( rFilterName
);
931 return String( aSystemPath
);
934 class ImpFilterLibCache
;
936 struct ImpFilterLibCacheEntry
938 ImpFilterLibCacheEntry
* mpNext
;
939 #ifndef DISABLE_DYNLOADING
940 osl::Module maLibrary
;
943 PFilterCall mpfnImport
;
944 PFilterDlgCall mpfnImportDlg
;
946 ImpFilterLibCacheEntry( const String
& rPathname
, const String
& rFiltername
);
947 int operator==( const String
& rFiltername
) const { return maFiltername
== rFiltername
; }
949 PFilterCall
GetImportFunction();
952 ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const String
& rPathname
, const String
& rFiltername
) :
954 #ifndef DISABLE_DYNLOADING
955 maLibrary ( rPathname
),
957 maFiltername ( rFiltername
),
959 mpfnImportDlg ( NULL
)
961 #ifdef DISABLE_DYNLOADING
966 #ifdef DISABLE_DYNLOADING
968 extern "C" sal_Bool
icdGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
969 extern "C" sal_Bool
idxGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
970 extern "C" sal_Bool
imeGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
971 extern "C" sal_Bool
ipbGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
972 extern "C" sal_Bool
ipdGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
973 extern "C" sal_Bool
ipsGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
974 extern "C" sal_Bool
iptGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
975 extern "C" sal_Bool
ipxGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
976 extern "C" sal_Bool
iraGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
977 extern "C" sal_Bool
itgGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
978 extern "C" sal_Bool
itiGraphicImport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
982 PFilterCall
ImpFilterLibCacheEntry::GetImportFunction()
986 #ifndef DISABLE_DYNLOADING
987 mpfnImport
= (PFilterCall
) maLibrary
.getFunctionSymbol(OUString(IMPORT_FUNCTION_NAME
));
989 if( maFiltername
.EqualsAscii( "icd" ) )
990 mpfnImport
= icdGraphicImport
;
991 else if( maFiltername
.EqualsAscii( "idx" ) )
992 mpfnImport
= idxGraphicImport
;
993 else if( maFiltername
.EqualsAscii( "ime" ) )
994 mpfnImport
= imeGraphicImport
;
995 else if( maFiltername
.EqualsAscii( "ipb" ) )
996 mpfnImport
= ipbGraphicImport
;
997 else if( maFiltername
.EqualsAscii( "ipd" ) )
998 mpfnImport
= ipdGraphicImport
;
999 else if( maFiltername
.EqualsAscii( "ips" ) )
1000 mpfnImport
= ipsGraphicImport
;
1001 else if( maFiltername
.EqualsAscii( "ipt" ) )
1002 mpfnImport
= iptGraphicImport
;
1003 else if( maFiltername
.EqualsAscii( "ipx" ) )
1004 mpfnImport
= ipxGraphicImport
;
1005 else if( maFiltername
.EqualsAscii( "ira" ) )
1006 mpfnImport
= iraGraphicImport
;
1007 else if( maFiltername
.EqualsAscii( "itg" ) )
1008 mpfnImport
= itgGraphicImport
;
1009 else if( maFiltername
.EqualsAscii( "iti" ) )
1010 mpfnImport
= itiGraphicImport
;
1017 class ImpFilterLibCache
1019 ImpFilterLibCacheEntry
* mpFirst
;
1020 ImpFilterLibCacheEntry
* mpLast
;
1023 ImpFilterLibCache();
1024 ~ImpFilterLibCache();
1026 ImpFilterLibCacheEntry
* GetFilter( const String
& rFilterPath
, const String
& rFiltername
);
1029 ImpFilterLibCache::ImpFilterLibCache() :
1035 ImpFilterLibCache::~ImpFilterLibCache()
1037 ImpFilterLibCacheEntry
* pEntry
= mpFirst
;
1040 ImpFilterLibCacheEntry
* pNext
= pEntry
->mpNext
;
1046 ImpFilterLibCacheEntry
* ImpFilterLibCache::GetFilter( const String
& rFilterPath
, const String
& rFilterName
)
1048 ImpFilterLibCacheEntry
* pEntry
= mpFirst
;
1052 if( *pEntry
== rFilterName
)
1055 pEntry
= pEntry
->mpNext
;
1059 String
aPhysicalName( ImpCreateFullFilterPath( rFilterPath
, rFilterName
) );
1060 pEntry
= new ImpFilterLibCacheEntry( aPhysicalName
, rFilterName
);
1061 #ifndef DISABLE_DYNLOADING
1062 if ( pEntry
->maLibrary
.is() )
1066 mpFirst
= mpLast
= pEntry
;
1068 mpLast
= mpLast
->mpNext
= pEntry
;
1070 #ifndef DISABLE_DYNLOADING
1081 namespace { struct Cache
: public rtl::Static
<ImpFilterLibCache
, Cache
> {}; }
1083 GraphicFilter::GraphicFilter( sal_Bool bConfig
) :
1084 bUseConfig ( bConfig
),
1090 GraphicFilter::~GraphicFilter()
1093 ::osl::MutexGuard
aGuard( getListMutex() );
1095 FilterList_impl::iterator it
= pFilterHdlList
->begin();
1096 it
!= pFilterHdlList
->end();
1101 pFilterHdlList
->erase( it
);
1105 if( pFilterHdlList
->empty() )
1107 delete pFilterHdlList
, pFilterHdlList
= NULL
;
1115 void GraphicFilter::ImplInit()
1118 ::osl::MutexGuard
aGuard( getListMutex() );
1120 if ( !pFilterHdlList
)
1122 pFilterHdlList
= new FilterList_impl
;
1123 pConfig
= new FilterConfigCache( bUseConfig
);
1126 pConfig
= pFilterHdlList
->front()->pConfig
;
1128 pFilterHdlList
->push_back( this );
1133 OUString
url("$BRAND_BASE_DIR/program");
1134 rtl::Bootstrap::expandMacros(url
); //TODO: detect failure
1135 utl::LocalFileHelper::ConvertURLToPhysicalName(url
, aFilterPath
);
1138 pErrorEx
= new FilterErrorEx
;
1142 sal_uLong
GraphicFilter::ImplSetError( sal_uLong nError
, const SvStream
* pStm
)
1144 pErrorEx
->nFilterError
= nError
;
1145 pErrorEx
->nStreamError
= pStm
? pStm
->GetError() : ERRCODE_NONE
;
1149 sal_uInt16
GraphicFilter::GetImportFormatCount()
1151 return pConfig
->GetImportFormatCount();
1154 sal_uInt16
GraphicFilter::GetImportFormatNumber( const String
& rFormatName
)
1156 return pConfig
->GetImportFormatNumber( rFormatName
);
1159 sal_uInt16
GraphicFilter::GetImportFormatNumberForMediaType( const String
& rMediaType
)
1161 return pConfig
->GetImportFormatNumberForMediaType( rMediaType
);
1164 sal_uInt16
GraphicFilter::GetImportFormatNumberForShortName( const String
& rShortName
)
1166 return pConfig
->GetImportFormatNumberForShortName( rShortName
);
1169 sal_uInt16
GraphicFilter::GetImportFormatNumberForTypeName( const String
& rType
)
1171 return pConfig
->GetImportFormatNumberForTypeName( rType
);
1174 String
GraphicFilter::GetImportFormatName( sal_uInt16 nFormat
)
1176 return pConfig
->GetImportFormatName( nFormat
);
1179 String
GraphicFilter::GetImportFormatTypeName( sal_uInt16 nFormat
)
1181 return pConfig
->GetImportFilterTypeName( nFormat
);
1184 String
GraphicFilter::GetImportFormatMediaType( sal_uInt16 nFormat
)
1186 return pConfig
->GetImportFormatMediaType( nFormat
);
1189 String
GraphicFilter::GetImportFormatShortName( sal_uInt16 nFormat
)
1191 return pConfig
->GetImportFormatShortName( nFormat
);
1194 String
GraphicFilter::GetImportOSFileType( sal_uInt16
)
1200 String
GraphicFilter::GetImportWildcard( sal_uInt16 nFormat
, sal_Int32 nEntry
)
1202 return pConfig
->GetImportWildcard( nFormat
, nEntry
);
1205 sal_Bool
GraphicFilter::IsImportPixelFormat( sal_uInt16 nFormat
)
1207 return pConfig
->IsImportPixelFormat( nFormat
);
1210 sal_uInt16
GraphicFilter::GetExportFormatCount()
1212 return pConfig
->GetExportFormatCount();
1215 sal_uInt16
GraphicFilter::GetExportFormatNumber( const String
& rFormatName
)
1217 return pConfig
->GetExportFormatNumber( rFormatName
);
1220 sal_uInt16
GraphicFilter::GetExportFormatNumberForMediaType( const String
& rMediaType
)
1222 return pConfig
->GetExportFormatNumberForMediaType( rMediaType
);
1225 sal_uInt16
GraphicFilter::GetExportFormatNumberForShortName( const String
& rShortName
)
1227 return pConfig
->GetExportFormatNumberForShortName( rShortName
);
1230 String
GraphicFilter::GetExportInternalFilterName( sal_uInt16 nFormat
)
1232 return pConfig
->GetExportInternalFilterName( nFormat
);
1235 sal_uInt16
GraphicFilter::GetExportFormatNumberForTypeName( const String
& rType
)
1237 return pConfig
->GetExportFormatNumberForTypeName( rType
);
1240 String
GraphicFilter::GetExportFormatName( sal_uInt16 nFormat
)
1242 return pConfig
->GetExportFormatName( nFormat
);
1245 String
GraphicFilter::GetExportFormatTypeName( sal_uInt16 nFormat
)
1247 return pConfig
->GetExportFilterTypeName( nFormat
);
1250 String
GraphicFilter::GetExportFormatMediaType( sal_uInt16 nFormat
)
1252 return pConfig
->GetExportFormatMediaType( nFormat
);
1255 String
GraphicFilter::GetExportFormatShortName( sal_uInt16 nFormat
)
1257 return pConfig
->GetExportFormatShortName( nFormat
);
1260 String
GraphicFilter::GetExportOSFileType( sal_uInt16
)
1266 String
GraphicFilter::GetExportWildcard( sal_uInt16 nFormat
, sal_Int32 nEntry
)
1268 return pConfig
->GetExportWildcard( nFormat
, nEntry
);
1271 sal_Bool
GraphicFilter::IsExportPixelFormat( sal_uInt16 nFormat
)
1273 return pConfig
->IsExportPixelFormat( nFormat
);
1276 sal_uInt16
GraphicFilter::CanImportGraphic( const INetURLObject
& rPath
,
1277 sal_uInt16 nFormat
, sal_uInt16
* pDeterminedFormat
)
1279 sal_uInt16 nRetValue
= GRFILTER_FORMATERROR
;
1280 DBG_ASSERT( rPath
.GetProtocol() != INET_PROT_NOT_VALID
, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1282 String
aMainUrl( rPath
.GetMainURL( INetURLObject::NO_DECODE
) );
1283 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream( aMainUrl
, STREAM_READ
| STREAM_SHARE_DENYNONE
);
1286 nRetValue
= CanImportGraphic( aMainUrl
, *pStream
, nFormat
, pDeterminedFormat
);
1292 sal_uInt16
GraphicFilter::CanImportGraphic( const String
& rMainUrl
, SvStream
& rIStream
,
1293 sal_uInt16 nFormat
, sal_uInt16
* pDeterminedFormat
)
1295 sal_uLong nStreamPos
= rIStream
.Tell();
1296 sal_uInt16 nRes
= ImpTestOrFindFormat( rMainUrl
, rIStream
, nFormat
);
1298 rIStream
.Seek(nStreamPos
);
1300 if( nRes
==GRFILTER_OK
&& pDeterminedFormat
!=NULL
)
1301 *pDeterminedFormat
= nFormat
;
1303 return (sal_uInt16
) ImplSetError( nRes
, &rIStream
);
1306 //SJ: TODO, we need to create a GraphicImporter component
1307 sal_uInt16
GraphicFilter::ImportGraphic( Graphic
& rGraphic
, const INetURLObject
& rPath
,
1308 sal_uInt16 nFormat
, sal_uInt16
* pDeterminedFormat
, sal_uInt32 nImportFlags
)
1310 sal_uInt16 nRetValue
= GRFILTER_FORMATERROR
;
1311 DBG_ASSERT( rPath
.GetProtocol() != INET_PROT_NOT_VALID
, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1313 String
aMainUrl( rPath
.GetMainURL( INetURLObject::NO_DECODE
) );
1314 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream( aMainUrl
, STREAM_READ
| STREAM_SHARE_DENYNONE
);
1317 nRetValue
= ImportGraphic( rGraphic
, aMainUrl
, *pStream
, nFormat
, pDeterminedFormat
, nImportFlags
);
1323 sal_uInt16
GraphicFilter::ImportGraphic( Graphic
& rGraphic
, const String
& rPath
, SvStream
& rIStream
,
1324 sal_uInt16 nFormat
, sal_uInt16
* pDeterminedFormat
, sal_uInt32 nImportFlags
, WMF_EXTERNALHEADER
*pExtHeader
)
1326 return ImportGraphic( rGraphic
, rPath
, rIStream
, nFormat
, pDeterminedFormat
, nImportFlags
, NULL
, pExtHeader
);
1329 //-------------------------------------------------------------------------
1331 sal_uInt16
GraphicFilter::ImportGraphic( Graphic
& rGraphic
, const String
& rPath
, SvStream
& rIStream
,
1332 sal_uInt16 nFormat
, sal_uInt16
* pDeterminedFormat
, sal_uInt32 nImportFlags
,
1333 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
>* pFilterData
,
1334 WMF_EXTERNALHEADER
*pExtHeader
)
1337 sal_uLong nStmBegin
;
1339 GraphicReader
* pContext
= rGraphic
.GetContext();
1340 GfxLinkType eLinkType
= GFX_LINK_TYPE_NONE
;
1341 sal_Bool bDummyContext
= ( pContext
== (GraphicReader
*) 1 );
1342 const sal_Bool bLinkSet
= rGraphic
.IsLink();
1343 FilterConfigItem
* pFilterConfigItem
= NULL
;
1345 Size
aPreviewSizeHint( 0, 0 );
1346 sal_Bool bAllowPartialStreamRead
= sal_False
;
1347 sal_Bool bCreateNativeLink
= sal_True
;
1354 for ( i
= 0; i
< pFilterData
->getLength(); i
++ )
1356 if ( (*pFilterData
)[ i
].Name
== "PreviewSizeHint" )
1359 if ( (*pFilterData
)[ i
].Value
>>= aSize
)
1361 aPreviewSizeHint
= Size( aSize
.Width
, aSize
.Height
);
1362 if ( aSize
.Width
|| aSize
.Height
)
1363 nImportFlags
|= GRFILTER_I_FLAGS_FOR_PREVIEW
;
1365 nImportFlags
&=~GRFILTER_I_FLAGS_FOR_PREVIEW
;
1368 else if ( (*pFilterData
)[ i
].Name
== "AllowPartialStreamRead" )
1370 (*pFilterData
)[ i
].Value
>>= bAllowPartialStreamRead
;
1371 if ( bAllowPartialStreamRead
)
1372 nImportFlags
|= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD
;
1374 nImportFlags
&=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD
;
1376 else if ( (*pFilterData
)[ i
].Name
== "CreateNativeLink" )
1378 (*pFilterData
)[ i
].Value
>>= bCreateNativeLink
;
1383 if( !pContext
|| bDummyContext
)
1387 rGraphic
.SetContext( NULL
);
1391 nStmBegin
= rIStream
.Tell();
1394 nStatus
= ImpTestOrFindFormat( rPath
, rIStream
, nFormat
);
1395 // if pending, return GRFILTER_OK in order to request more bytes
1396 if( rIStream
.GetError() == ERRCODE_IO_PENDING
)
1398 rGraphic
.SetContext( (GraphicReader
*) 1 );
1399 rIStream
.ResetError();
1400 rIStream
.Seek( nStmBegin
);
1401 return (sal_uInt16
) ImplSetError( GRFILTER_OK
);
1404 rIStream
.Seek( nStmBegin
);
1406 if( ( nStatus
!= GRFILTER_OK
) || rIStream
.GetError() )
1407 return (sal_uInt16
) ImplSetError( ( nStatus
!= GRFILTER_OK
) ? nStatus
: GRFILTER_OPENERROR
, &rIStream
);
1409 if( pDeterminedFormat
)
1410 *pDeterminedFormat
= nFormat
;
1412 aFilterName
= pConfig
->GetImportFilterName( nFormat
);
1416 if( pContext
&& !bDummyContext
)
1417 aFilterName
= pContext
->GetUpperFilterName();
1420 nStatus
= GRFILTER_OK
;
1424 if ( pConfig
->IsImportInternalFilter( nFormat
) )
1426 if( aFilterName
.EqualsIgnoreCaseAscii( IMP_GIF
) )
1428 if( rGraphic
.GetContext() == (GraphicReader
*) 1 )
1429 rGraphic
.SetContext( NULL
);
1431 if( !ImportGIF( rIStream
, rGraphic
) )
1432 nStatus
= GRFILTER_FILTERERROR
;
1434 eLinkType
= GFX_LINK_TYPE_NATIVE_GIF
;
1436 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_PNG
) )
1438 if ( rGraphic
.GetContext() == (GraphicReader
*) 1 )
1439 rGraphic
.SetContext( NULL
);
1441 vcl::PNGReader
aPNGReader( rIStream
);
1443 // ignore animation for previews and set preview size
1444 if( aPreviewSizeHint
.Width() || aPreviewSizeHint
.Height() )
1446 // position the stream at the end of the image if requested
1447 if( !bAllowPartialStreamRead
)
1448 aPNGReader
.GetChunks();
1452 // check if this PNG contains a GIF chunk!
1453 const std::vector
< vcl::PNGReader::ChunkData
>& rChunkData
= aPNGReader
.GetChunks();
1454 std::vector
< vcl::PNGReader::ChunkData
>::const_iterator
aIter( rChunkData
.begin() );
1455 std::vector
< vcl::PNGReader::ChunkData
>::const_iterator
aEnd ( rChunkData
.end() );
1456 while( aIter
!= aEnd
)
1458 // Microsoft Office is storing Animated GIFs in following chunk
1459 if ( aIter
->nType
== PMGCHUNG_msOG
)
1461 sal_uInt32 nChunkSize
= aIter
->aData
.size();
1462 if ( nChunkSize
> 11 )
1464 const std::vector
< sal_uInt8
>& rData
= aIter
->aData
;
1465 SvMemoryStream
aIStrm( (void*)&rData
[ 11 ], nChunkSize
- 11, STREAM_READ
);
1466 ImportGIF( aIStrm
, rGraphic
);
1467 eLinkType
= GFX_LINK_TYPE_NATIVE_PNG
;
1475 if ( eLinkType
== GFX_LINK_TYPE_NONE
)
1477 BitmapEx
aBmpEx( aPNGReader
.Read( aPreviewSizeHint
) );
1478 if ( aBmpEx
.IsEmpty() )
1479 nStatus
= GRFILTER_FILTERERROR
;
1483 eLinkType
= GFX_LINK_TYPE_NATIVE_PNG
;
1487 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_JPEG
) )
1489 if( rGraphic
.GetContext() == (GraphicReader
*) 1 )
1490 rGraphic
.SetContext( NULL
);
1492 // set LOGSIZE flag always, if not explicitly disabled
1493 // (see #90508 and #106763)
1494 if( 0 == ( nImportFlags
& GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG
) )
1495 nImportFlags
|= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG
;
1497 if( !ImportJPEG( rIStream
, rGraphic
, NULL
, nImportFlags
) )
1498 nStatus
= GRFILTER_FILTERERROR
;
1500 eLinkType
= GFX_LINK_TYPE_NATIVE_JPG
;
1502 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_SVG
) )
1504 if( rGraphic
.GetContext() == (GraphicReader
*) 1 )
1505 rGraphic
.SetContext( NULL
);
1507 const sal_uInt32
nStmPos(rIStream
.Tell());
1508 const sal_uInt32
nStmLen(rIStream
.Seek(STREAM_SEEK_TO_END
) - nStmPos
);
1513 SvgDataArray
aNewData(new sal_uInt8
[nStmLen
]);
1515 rIStream
.Seek(nStmPos
);
1516 rIStream
.Read(aNewData
.get(), nStmLen
);
1518 if(!rIStream
.GetError())
1520 SvgDataPtr
aSvgDataPtr(
1526 rGraphic
= Graphic(aSvgDataPtr
);
1533 eLinkType
= GFX_LINK_TYPE_NATIVE_SVG
;
1537 nStatus
= GRFILTER_FILTERERROR
;
1540 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_XBM
) )
1542 if( rGraphic
.GetContext() == (GraphicReader
*) 1 )
1543 rGraphic
.SetContext( NULL
);
1545 if( !ImportXBM( rIStream
, rGraphic
) )
1546 nStatus
= GRFILTER_FILTERERROR
;
1548 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_XPM
) )
1550 if( rGraphic
.GetContext() == (GraphicReader
*) 1 )
1551 rGraphic
.SetContext( NULL
);
1553 if( !ImportXPM( rIStream
, rGraphic
) )
1554 nStatus
= GRFILTER_FILTERERROR
;
1556 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_BMP
) ||
1557 aFilterName
.EqualsIgnoreCaseAscii( IMP_SVMETAFILE
) )
1559 // SV internal filters for import bitmaps and MetaFiles
1560 rIStream
>> rGraphic
;
1561 if( rIStream
.GetError() )
1562 nStatus
= GRFILTER_FORMATERROR
;
1564 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_WMF
) ||
1565 aFilterName
.EqualsIgnoreCaseAscii( IMP_EMF
) )
1568 if( !ConvertWMFToGDIMetaFile( rIStream
, aMtf
, NULL
, pExtHeader
) )
1569 nStatus
= GRFILTER_FORMATERROR
;
1573 eLinkType
= GFX_LINK_TYPE_NATIVE_WMF
;
1576 else if( aFilterName
.EqualsIgnoreCaseAscii( IMP_SVSGF
)
1577 || aFilterName
.EqualsIgnoreCaseAscii( IMP_SVSGV
) )
1579 sal_uInt16 nVersion
;
1580 unsigned char nTyp
= CheckSgfTyp( rIStream
, nVersion
);
1586 SvMemoryStream aTempStream
;
1587 if( aTempStream
.GetError() )
1588 return GRFILTER_OPENERROR
;
1590 if( !SgfBMapFilter( rIStream
, aTempStream
) )
1591 nStatus
= GRFILTER_FILTERERROR
;
1594 aTempStream
.Seek( 0L );
1595 aTempStream
>> rGraphic
;
1597 if( aTempStream
.GetError() )
1598 nStatus
= GRFILTER_FILTERERROR
;
1606 if( !SgfVectFilter( rIStream
, aMtf
) )
1607 nStatus
= GRFILTER_FILTERERROR
;
1609 rGraphic
= Graphic( aMtf
);
1615 if( nVersion
!= SGV_VERSION
)
1616 nStatus
= GRFILTER_VERSIONERROR
;
1620 if( !SgfSDrwFilter( rIStream
, aMtf
,
1621 INetURLObject(aFilterPath
) ) )
1623 nStatus
= GRFILTER_FILTERERROR
;
1626 rGraphic
= Graphic( aMtf
);
1633 nStatus
= GRFILTER_FORMATERROR
;
1639 nStatus
= GRFILTER_FILTERERROR
;
1643 ImpFilterLibCacheEntry
* pFilter
= NULL
;
1645 // find first filter in filter paths
1646 sal_Int32 i
, nTokenCount
= getTokenCount(aFilterPath
, ';');
1647 ImpFilterLibCache
&rCache
= Cache::get();
1648 for( i
= 0; ( i
< nTokenCount
) && ( pFilter
== NULL
); i
++ )
1649 pFilter
= rCache
.GetFilter( getToken(aFilterPath
, i
, ';'), aFilterName
);
1651 nStatus
= GRFILTER_FILTERERROR
;
1654 PFilterCall pFunc
= pFilter
->GetImportFunction();
1657 nStatus
= GRFILTER_FILTERERROR
;
1661 if( nFormat
!= GRFILTER_FORMAT_DONTKNOW
)
1663 aShortName
= GetImportFormatShortName( nFormat
).ToUpperAscii();
1664 if ( ( pFilterConfigItem
== NULL
) && aShortName
.EqualsAscii( "PCD" ) )
1666 String
aFilterConfigPath( "Office.Common/Filter/Graphic/Import/PCD" );
1667 pFilterConfigItem
= new FilterConfigItem( aFilterConfigPath
);
1670 if( !(*pFunc
)( rIStream
, rGraphic
, pFilterConfigItem
, sal_False
) )
1671 nStatus
= GRFILTER_FORMATERROR
;
1674 // try to set link type if format matches
1675 if( nFormat
!= GRFILTER_FORMAT_DONTKNOW
)
1677 if( aShortName
.CompareToAscii( TIF_SHORTNAME
) == COMPARE_EQUAL
)
1678 eLinkType
= GFX_LINK_TYPE_NATIVE_TIF
;
1679 else if( aShortName
.CompareToAscii( MET_SHORTNAME
) == COMPARE_EQUAL
)
1680 eLinkType
= GFX_LINK_TYPE_NATIVE_MET
;
1681 else if( aShortName
.CompareToAscii( PCT_SHORTNAME
) == COMPARE_EQUAL
)
1682 eLinkType
= GFX_LINK_TYPE_NATIVE_PCT
;
1689 if( nStatus
== GRFILTER_OK
&& bCreateNativeLink
&& ( eLinkType
!= GFX_LINK_TYPE_NONE
) && !rGraphic
.GetContext() && !bLinkSet
)
1691 const sal_uLong nStmEnd
= rIStream
.Tell();
1692 const sal_uLong nBufSize
= nStmEnd
- nStmBegin
;
1699 pBuf
= new sal_uInt8
[ nBufSize
];
1701 catch (const std::bad_alloc
&)
1703 nStatus
= GRFILTER_TOOBIG
;
1706 if( nStatus
== GRFILTER_OK
)
1708 rIStream
.Seek( nStmBegin
);
1709 rIStream
.Read( pBuf
, nBufSize
);
1710 rGraphic
.SetLink( GfxLink( pBuf
, nBufSize
, eLinkType
, sal_True
) );
1715 // Set error code or try to set native buffer
1716 if( nStatus
!= GRFILTER_OK
)
1719 nStatus
= GRFILTER_ABORT
;
1721 ImplSetError( nStatus
, &rIStream
);
1722 rIStream
.Seek( nStmBegin
);
1726 delete pFilterConfigItem
;
1730 sal_uInt16
GraphicFilter::ExportGraphic( const Graphic
& rGraphic
, const INetURLObject
& rPath
,
1731 sal_uInt16 nFormat
, const uno::Sequence
< beans::PropertyValue
>* pFilterData
)
1733 #ifdef DISABLE_EXPORT
1739 return GRFILTER_FORMATERROR
;
1741 RTL_LOGFILE_CONTEXT( aLog
, "GraphicFilter::ExportGraphic() (thb)" );
1742 sal_uInt16 nRetValue
= GRFILTER_FORMATERROR
;
1743 DBG_ASSERT( rPath
.GetProtocol() != INET_PROT_NOT_VALID
, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" );
1744 sal_Bool bAlreadyExists
= DirEntryExists( rPath
);
1746 String
aMainUrl( rPath
.GetMainURL( INetURLObject::NO_DECODE
) );
1747 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream( aMainUrl
, STREAM_WRITE
| STREAM_TRUNC
);
1750 nRetValue
= ExportGraphic( rGraphic
, aMainUrl
, *pStream
, nFormat
, pFilterData
);
1753 if( ( GRFILTER_OK
!= nRetValue
) && !bAlreadyExists
)
1754 KillDirEntry( aMainUrl
);
1760 #ifdef DISABLE_DYNLOADING
1762 #ifndef DISABLE_EXPORT
1764 extern "C" sal_Bool
egiGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1765 extern "C" sal_Bool
emeGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1766 extern "C" sal_Bool
epbGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1767 extern "C" sal_Bool
epgGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1768 extern "C" sal_Bool
eppGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1769 extern "C" sal_Bool
epsGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1770 extern "C" sal_Bool
eptGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1771 extern "C" sal_Bool
eraGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1772 extern "C" sal_Bool
etiGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1773 extern "C" sal_Bool
expGraphicExport( SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
, sal_Bool
);
1779 sal_uInt16
GraphicFilter::ExportGraphic( const Graphic
& rGraphic
, const String
& rPath
,
1780 SvStream
& rOStm
, sal_uInt16 nFormat
, const uno::Sequence
< beans::PropertyValue
>* pFilterData
)
1782 #ifdef DISABLE_EXPORT
1789 return GRFILTER_FORMATERROR
;
1791 RTL_LOGFILE_CONTEXT( aLog
, "GraphicFilter::ExportGraphic() (thb)" );
1792 sal_uInt16 nFormatCount
= GetExportFormatCount();
1797 if( nFormat
== GRFILTER_FORMAT_DONTKNOW
)
1799 INetURLObject
aURL( rPath
);
1800 String
aExt( aURL
.GetFileExtension().toAsciiUpperCase() );
1803 for( sal_uInt16 i
= 0; i
< nFormatCount
; i
++ )
1805 if ( pConfig
->GetExportFormatExtension( i
).EqualsIgnoreCaseAscii( aExt
) )
1812 if( nFormat
>= nFormatCount
)
1813 return (sal_uInt16
) ImplSetError( GRFILTER_FORMATERROR
);
1815 FilterConfigItem
aConfigItem( (uno::Sequence
< beans::PropertyValue
>*)pFilterData
);
1816 String
aFilterName( pConfig
->GetExportFilterName( nFormat
) );
1819 sal_uInt16 nStatus
= GRFILTER_OK
;
1821 Graphic
aGraphic( rGraphic
);
1823 aGraphic
= ImpGetScaledGraphic( rGraphic
, aConfigItem
);
1824 eType
= aGraphic
.GetType();
1826 if( pConfig
->IsExportPixelFormat( nFormat
) )
1828 if( eType
!= GRAPHIC_BITMAP
)
1831 sal_uLong nColorCount
,nBitsPerPixel
,nNeededMem
,nMaxMem
;
1832 VirtualDevice aVirDev
;
1835 nMaxMem
*= 1024; // In Bytes
1837 // Calculate how big the image would normally be:
1838 aSizePixel
=aVirDev
.LogicToPixel(aGraphic
.GetPrefSize(),aGraphic
.GetPrefMapMode());
1840 // Calculate how much memory the image will take up
1841 nColorCount
=aVirDev
.GetColorCount();
1842 if (nColorCount
<=2) nBitsPerPixel
=1;
1843 else if (nColorCount
<=4) nBitsPerPixel
=2;
1844 else if (nColorCount
<=16) nBitsPerPixel
=4;
1845 else if (nColorCount
<=256) nBitsPerPixel
=8;
1846 else if (nColorCount
<=65536) nBitsPerPixel
=16;
1847 else nBitsPerPixel
=24;
1848 nNeededMem
=((sal_uLong
)aSizePixel
.Width()*(sal_uLong
)aSizePixel
.Height()*nBitsPerPixel
+7)/8;
1850 // is the image larger than available memory?
1851 if (nMaxMem
<nNeededMem
)
1853 double fFak
=sqrt(((double)nMaxMem
)/((double)nNeededMem
));
1854 aSizePixel
.Width()=(sal_uLong
)(((double)aSizePixel
.Width())*fFak
);
1855 aSizePixel
.Height()=(sal_uLong
)(((double)aSizePixel
.Height())*fFak
);
1858 aVirDev
.SetMapMode(MapMode(MAP_PIXEL
));
1859 aVirDev
.SetOutputSizePixel(aSizePixel
);
1860 Graphic aGraphic2
=aGraphic
;
1861 aGraphic2
.Draw(&aVirDev
,Point(0,0),aSizePixel
); // this changes the MapMode
1862 aVirDev
.SetMapMode(MapMode(MAP_PIXEL
));
1863 aGraphic
=Graphic(aVirDev
.GetBitmap(Point(0,0),aSizePixel
));
1866 if( rOStm
.GetError() )
1867 nStatus
= GRFILTER_IOERROR
;
1868 if( GRFILTER_OK
== nStatus
)
1870 if ( pConfig
->IsExportInternalFilter( nFormat
) )
1872 if( aFilterName
.EqualsIgnoreCaseAscii( EXP_BMP
) )
1874 Bitmap
aBmp( aGraphic
.GetBitmap() );
1875 sal_Int32 nColorRes
= aConfigItem
.ReadInt32( "Colors", 0 );
1876 if ( nColorRes
&& ( nColorRes
<= (sal_uInt16
)BMP_CONVERSION_24BIT
) )
1878 if( !aBmp
.Convert( (BmpConversion
) nColorRes
) )
1879 aBmp
= aGraphic
.GetBitmap();
1881 sal_Bool bRleCoding
= aConfigItem
.ReadBool( "RLE_Coding", sal_True
);
1882 // save RLE encoded?
1883 aBmp
.Write( rOStm
, bRleCoding
);
1885 if( rOStm
.GetError() )
1886 nStatus
= GRFILTER_IOERROR
;
1888 else if( aFilterName
.EqualsIgnoreCaseAscii( EXP_SVMETAFILE
) )
1890 sal_Int32 nVersion
= aConfigItem
.ReadInt32( "Version", 0 ) ;
1892 rOStm
.SetVersion( nVersion
);
1894 // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1895 GDIMetaFile
aMTF(aGraphic
.GetGDIMetaFile());
1897 aMTF
.Write( rOStm
);
1899 if( rOStm
.GetError() )
1900 nStatus
= GRFILTER_IOERROR
;
1902 else if ( aFilterName
.EqualsIgnoreCaseAscii( EXP_WMF
) )
1904 // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1905 if ( !ConvertGDIMetaFileToWMF( aGraphic
.GetGDIMetaFile(), rOStm
, &aConfigItem
) )
1906 nStatus
= GRFILTER_FORMATERROR
;
1908 if( rOStm
.GetError() )
1909 nStatus
= GRFILTER_IOERROR
;
1911 else if ( aFilterName
.EqualsIgnoreCaseAscii( EXP_EMF
) )
1913 // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
1914 if ( !ConvertGDIMetaFileToEMF( aGraphic
.GetGDIMetaFile(), rOStm
, &aConfigItem
) )
1915 nStatus
= GRFILTER_FORMATERROR
;
1917 if( rOStm
.GetError() )
1918 nStatus
= GRFILTER_IOERROR
;
1920 else if( aFilterName
.EqualsIgnoreCaseAscii( EXP_JPEG
) )
1922 bool bExportedGrayJPEG
= false;
1923 if( !ExportJPEG( rOStm
, aGraphic
, pFilterData
, &bExportedGrayJPEG
) )
1924 nStatus
= GRFILTER_FORMATERROR
;
1925 nExpGraphHint
= bExportedGrayJPEG
? GRFILTER_OUTHINT_GREY
: 0;
1927 if( rOStm
.GetError() )
1928 nStatus
= GRFILTER_IOERROR
;
1930 else if ( aFilterName
.EqualsIgnoreCaseAscii( EXP_PNG
) )
1932 vcl::PNGWriter
aPNGWriter( aGraphic
.GetBitmapEx(), pFilterData
);
1935 sal_Int32 k
, j
, i
= 0;
1936 for ( i
= 0; i
< pFilterData
->getLength(); i
++ )
1938 if ( (*pFilterData
)[ i
].Name
== "AdditionalChunks" )
1940 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
> aAdditionalChunkSequence
;
1941 if ( (*pFilterData
)[ i
].Value
>>= aAdditionalChunkSequence
)
1943 for ( j
= 0; j
< aAdditionalChunkSequence
.getLength(); j
++ )
1945 if ( aAdditionalChunkSequence
[ j
].Name
.getLength() == 4 )
1947 sal_uInt32 nChunkType
= 0;
1948 for ( k
= 0; k
< 4; k
++ )
1951 nChunkType
|= (sal_uInt8
)aAdditionalChunkSequence
[ j
].Name
[ k
];
1953 com::sun::star::uno::Sequence
< sal_Int8
> aByteSeq
;
1954 if ( aAdditionalChunkSequence
[ j
].Value
>>= aByteSeq
)
1956 std::vector
< vcl::PNGWriter::ChunkData
>& rChunkData
= aPNGWriter
.GetChunks();
1957 if ( !rChunkData
.empty() )
1959 sal_uInt32 nChunkLen
= aByteSeq
.getLength();
1961 vcl::PNGWriter::ChunkData aChunkData
;
1962 aChunkData
.nType
= nChunkType
;
1965 aChunkData
.aData
.resize( nChunkLen
);
1966 memcpy( &aChunkData
.aData
[ 0 ], aByteSeq
.getConstArray(), nChunkLen
);
1968 std::vector
< vcl::PNGWriter::ChunkData
>::iterator aIter
= rChunkData
.end() - 1;
1969 rChunkData
.insert( aIter
, aChunkData
);
1978 aPNGWriter
.Write( rOStm
);
1980 if( rOStm
.GetError() )
1981 nStatus
= GRFILTER_IOERROR
;
1983 else if( aFilterName
.EqualsIgnoreCaseAscii( EXP_SVG
) )
1987 // do we have a native SVG RenderGraphic, whose data can be written directly?
1988 const SvgDataPtr
aSvgDataPtr(rGraphic
.getSvgData());
1990 if(aSvgDataPtr
.get() && aSvgDataPtr
->getSvgDataArrayLength())
1992 rOStm
.Write(aSvgDataPtr
->getSvgDataArray().get(), aSvgDataPtr
->getSvgDataArrayLength());
1994 if( rOStm
.GetError() )
1996 nStatus
= GRFILTER_IOERROR
;
2006 // do the normal GDIMetaFile export instead
2009 css::uno::Reference
< css::uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
2011 css::uno::Reference
< css::xml::sax::XDocumentHandler
> xSaxWriter(
2012 xml::sax::Writer::create( xContext
), uno::UNO_QUERY_THROW
);
2014 css::uno::Reference
< css::svg::XSVGWriter
> xSVGWriter(
2015 xContext
->getServiceManager()->createInstanceWithContext( "com.sun.star.svg.SVGWriter", xContext
),
2016 css::uno::UNO_QUERY
);
2018 if( xSaxWriter
.is() && xSVGWriter
.is() )
2020 css::uno::Reference
< css::io::XActiveDataSource
> xActiveDataSource(
2021 xSaxWriter
, css::uno::UNO_QUERY
);
2023 if( xActiveDataSource
.is() )
2025 const css::uno::Reference
< css::uno::XInterface
> xStmIf(
2026 static_cast< ::cppu::OWeakObject
* >( new ImpFilterOutputStream( rOStm
) ) );
2028 SvMemoryStream
aMemStm( 65535, 65535 );
2030 // #i119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
2031 ( (GDIMetaFile
&) aGraphic
.GetGDIMetaFile() ).Write( aMemStm
);
2033 xActiveDataSource
->setOutputStream( css::uno::Reference
< css::io::XOutputStream
>(
2034 xStmIf
, css::uno::UNO_QUERY
) );
2035 css::uno::Sequence
< sal_Int8
> aMtfSeq( (sal_Int8
*) aMemStm
.GetData(), aMemStm
.Tell() );
2036 xSVGWriter
->write( xSaxWriter
, aMtfSeq
);
2040 catch(const css::uno::Exception
&)
2042 nStatus
= GRFILTER_IOERROR
;
2047 nStatus
= GRFILTER_FILTERERROR
;
2051 sal_Int32 i
, nTokenCount
= getTokenCount(aFilterPath
, ';');
2052 for ( i
= 0; i
< nTokenCount
; i
++ )
2054 #ifndef DISABLE_DYNLOADING
2055 String
aPhysicalName( ImpCreateFullFilterPath( getToken(aFilterPath
, i
, ';'), aFilterName
) );
2056 osl::Module
aLibrary( aPhysicalName
);
2058 PFilterCall pFunc
= (PFilterCall
) aLibrary
.getFunctionSymbol(OUString(EXPORT_FUNCTION_NAME
));
2059 // Execute dialog in DLL
2061 PFilterCall pFunc
= NULL
;
2062 if( aFilterName
.EqualsAscii( "egi" ) )
2063 pFunc
= egiGraphicExport
;
2064 else if( aFilterName
.EqualsAscii( "eme" ) )
2065 pFunc
= emeGraphicExport
;
2066 else if( aFilterName
.EqualsAscii( "epb" ) )
2067 pFunc
= epbGraphicExport
;
2068 else if( aFilterName
.EqualsAscii( "epg" ) )
2069 pFunc
= epgGraphicExport
;
2070 else if( aFilterName
.EqualsAscii( "epp" ) )
2071 pFunc
= eppGraphicExport
;
2072 else if( aFilterName
.EqualsAscii( "eps" ) )
2073 pFunc
= epsGraphicExport
;
2074 else if( aFilterName
.EqualsAscii( "ept" ) )
2075 pFunc
= eptGraphicExport
;
2076 else if( aFilterName
.EqualsAscii( "era" ) )
2077 pFunc
= eraGraphicExport
;
2078 else if( aFilterName
.EqualsAscii( "eti" ) )
2079 pFunc
= etiGraphicExport
;
2080 else if( aFilterName
.EqualsAscii( "exp" ) )
2081 pFunc
= expGraphicExport
;
2085 if ( !(*pFunc
)( rOStm
, aGraphic
, &aConfigItem
, sal_False
) )
2086 nStatus
= GRFILTER_FORMATERROR
;
2090 nStatus
= GRFILTER_FILTERERROR
;
2094 if( nStatus
!= GRFILTER_OK
)
2097 nStatus
= GRFILTER_ABORT
;
2099 ImplSetError( nStatus
, &rOStm
);
2105 const FilterErrorEx
& GraphicFilter::GetLastError() const
2110 void GraphicFilter::ResetLastError()
2112 pErrorEx
->nFilterError
= pErrorEx
->nStreamError
= 0UL;
2115 const Link
GraphicFilter::GetFilterCallback() const
2117 const Link
aLink( LINK( this, GraphicFilter
, FilterCallback
) );
2121 IMPL_LINK( GraphicFilter
, FilterCallback
, ConvertData
*, pData
)
2127 sal_uInt16 nFormat
= GRFILTER_FORMAT_DONTKNOW
;
2129 switch( pData
->mnFormat
)
2131 case( CVT_BMP
): aShortName
= BMP_SHORTNAME
; break;
2132 case( CVT_GIF
): aShortName
= GIF_SHORTNAME
; break;
2133 case( CVT_JPG
): aShortName
= JPG_SHORTNAME
; break;
2134 case( CVT_MET
): aShortName
= MET_SHORTNAME
; break;
2135 case( CVT_PCT
): aShortName
= PCT_SHORTNAME
; break;
2136 case( CVT_PNG
): aShortName
= PNG_SHORTNAME
; break;
2137 case( CVT_SVM
): aShortName
= SVM_SHORTNAME
; break;
2138 case( CVT_TIF
): aShortName
= TIF_SHORTNAME
; break;
2139 case( CVT_WMF
): aShortName
= WMF_SHORTNAME
; break;
2140 case( CVT_EMF
): aShortName
= EMF_SHORTNAME
; break;
2141 case( CVT_SVG
): aShortName
= SVG_SHORTNAME
; break;
2146 if( GRAPHIC_NONE
== pData
->maGraphic
.GetType() || pData
->maGraphic
.GetContext() ) // Import
2149 nFormat
= GetImportFormatNumberForShortName( OStringToOUString( aShortName
, RTL_TEXTENCODING_UTF8
) );
2150 nRet
= ImportGraphic( pData
->maGraphic
, String(), pData
->mrStm
, nFormat
) == 0;
2152 #ifndef DISABLE_EXPORT
2153 else if( !aShortName
.isEmpty() )
2156 nFormat
= GetExportFormatNumberForShortName( OStringToOUString(aShortName
, RTL_TEXTENCODING_UTF8
) );
2157 nRet
= ExportGraphic( pData
->maGraphic
, String(), pData
->mrStm
, nFormat
) == 0;
2166 class StandardGraphicFilter
2169 StandardGraphicFilter()
2171 m_aFilter
.GetImportFormatCount();
2173 GraphicFilter m_aFilter
;
2176 class theGraphicFilter
: public rtl::Static
<StandardGraphicFilter
, theGraphicFilter
> {};
2179 GraphicFilter
& GraphicFilter::GetGraphicFilter()
2181 return theGraphicFilter::get().m_aFilter
;
2184 int GraphicFilter::LoadGraphic( const String
&rPath
, const String
&rFilterName
,
2185 Graphic
& rGraphic
, GraphicFilter
* pFilter
,
2186 sal_uInt16
* pDeterminedFormat
)
2189 pFilter
= &GetGraphicFilter();
2191 const sal_uInt16 nFilter
= rFilterName
.Len() && pFilter
->GetImportFormatCount()
2192 ? pFilter
->GetImportFormatNumber( rFilterName
)
2193 : GRFILTER_FORMAT_DONTKNOW
;
2195 SvStream
* pStream
= NULL
;
2196 INetURLObject
aURL( rPath
);
2198 if ( aURL
.HasError() || INET_PROT_NOT_VALID
== aURL
.GetProtocol() )
2200 aURL
.SetSmartProtocol( INET_PROT_FILE
);
2201 aURL
.SetSmartURL( rPath
);
2203 else if ( INET_PROT_FILE
!= aURL
.GetProtocol() )
2205 pStream
= ::utl::UcbStreamHelper::CreateStream( rPath
, STREAM_READ
);
2208 int nRes
= GRFILTER_OK
;
2210 nRes
= pFilter
->ImportGraphic( rGraphic
, aURL
, nFilter
, pDeterminedFormat
);
2212 nRes
= pFilter
->ImportGraphic( rGraphic
, rPath
, *pStream
, nFilter
, pDeterminedFormat
);
2216 DBG_WARNING2( "GrafikFehler [%d] - [%s]", nRes
, rPath
.GetBuffer() );
2222 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */