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