Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <boost/noncopyable.hpp>
23 : #include <comphelper/string.hxx>
24 : #include <sal/macros.h>
25 : #include <com/sun/star/embed/XTransactedObject.hpp>
26 : #include <com/sun/star/embed/ElementModes.hpp>
27 : #include <com/sun/star/beans/XPropertySet.hpp>
28 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 : #include <com/sun/star/lang/XServiceInfo.hpp>
30 : #include <com/sun/star/lang/XInitialization.hpp>
31 : #include <cppuhelper/compbase4.hxx>
32 : #include <cppuhelper/supportsservice.hxx>
33 :
34 : #include <rtl/ref.hxx>
35 : #include <unotools/ucbstreamhelper.hxx>
36 : #include <unotools/streamwrap.hxx>
37 : #include <unotools/tempfile.hxx>
38 : #include <unotools/saveopt.hxx>
39 : #include <vcl/cvtgrf.hxx>
40 : #include <vcl/gfxlink.hxx>
41 : #include <vcl/metaact.hxx>
42 : #include <tools/zcodec.hxx>
43 :
44 : #include <vcl/graphicfilter.hxx>
45 : #include "svx/xmlgrhlp.hxx"
46 : #include "svx/xmleohlp.hxx"
47 :
48 : #include <algorithm>
49 : #include <boost/scoped_ptr.hpp>
50 :
51 : using namespace com::sun::star;
52 : using namespace com::sun::star::uno;
53 : using namespace com::sun::star::io;
54 :
55 : using ::com::sun::star::lang::XMultiServiceFactory;
56 :
57 : #define XML_GRAPHICSTORAGE_NAME "Pictures"
58 : #define XML_GRAPHICOBJECT_URL_BASE "vnd.sun.star.GraphicObject:"
59 :
60 : namespace {
61 :
62 4 : const MetaCommentAction* ImplCheckForEPS( GDIMetaFile& rMtf )
63 : {
64 4 : const MetaCommentAction* pComment = NULL;
65 :
66 8 : if ( ( rMtf.GetActionSize() >= 2 )
67 4 : && ( rMtf.FirstAction()->GetType() == META_EPS_ACTION )
68 0 : && ( ((const MetaAction*)rMtf.GetAction( 1 ))->GetType() == META_COMMENT_ACTION )
69 4 : && ( static_cast<const MetaCommentAction*>(rMtf.GetAction( 1 ))->GetComment() == "EPSReplacementGraphic" ) )
70 0 : pComment = static_cast<const MetaCommentAction*>(rMtf.GetAction( 1 ));
71 :
72 4 : return pComment;
73 : }
74 :
75 : class SvXMLGraphicInputStream:
76 : public cppu::WeakImplHelper1<XInputStream>, private boost::noncopyable
77 : {
78 : private:
79 :
80 : virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
81 : virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
82 : virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw(NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception) SAL_OVERRIDE;
83 : virtual sal_Int32 SAL_CALL available() throw(NotConnectedException, RuntimeException, std::exception) SAL_OVERRIDE;
84 : virtual void SAL_CALL closeInput() throw(NotConnectedException, RuntimeException, std::exception) SAL_OVERRIDE;
85 :
86 : private:
87 :
88 : ::utl::TempFile maTmp;
89 : Reference< XInputStream > mxStmWrapper;
90 :
91 : public:
92 :
93 : SvXMLGraphicInputStream( const OUString& rGraphicId );
94 : virtual ~SvXMLGraphicInputStream();
95 :
96 0 : bool Exists() const { return mxStmWrapper.is(); }
97 : };
98 :
99 0 : SvXMLGraphicInputStream::SvXMLGraphicInputStream( const OUString& rGraphicId )
100 : {
101 0 : GraphicObject aGrfObject( OUStringToOString(rGraphicId, RTL_TEXTENCODING_ASCII_US) );
102 :
103 0 : maTmp.EnableKillingFile();
104 :
105 0 : if( aGrfObject.GetType() != GRAPHIC_NONE )
106 : {
107 0 : SvStream* pStm = ::utl::UcbStreamHelper::CreateStream( maTmp.GetURL(), STREAM_WRITE | STREAM_TRUNC );
108 :
109 0 : if( pStm )
110 : {
111 0 : Graphic aGraphic( (Graphic&) aGrfObject.GetGraphic() );
112 0 : const GfxLink aGfxLink( aGraphic.GetLink() );
113 0 : bool bRet = false;
114 :
115 0 : if( aGfxLink.GetDataSize() && aGfxLink.GetData() )
116 : {
117 0 : pStm->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() );
118 0 : bRet = ( pStm->GetError() == 0 );
119 : }
120 : else
121 : {
122 0 : if( aGraphic.GetType() == GRAPHIC_BITMAP )
123 : {
124 0 : GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
125 0 : OUString aFormat;
126 :
127 0 : if( aGraphic.IsAnimated() )
128 0 : aFormat = "gif";
129 : else
130 0 : aFormat = "png";
131 :
132 0 : bRet = ( rFilter.ExportGraphic( aGraphic, "", *pStm, rFilter.GetExportFormatNumberForShortName( aFormat ) ) == 0 );
133 : }
134 0 : else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE )
135 : {
136 0 : pStm->SetVersion( SOFFICE_FILEFORMAT_8 );
137 0 : pStm->SetCompressMode( COMPRESSMODE_ZBITMAP );
138 0 : ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( *pStm );
139 0 : bRet = ( pStm->GetError() == 0 );
140 : }
141 : }
142 :
143 0 : if( bRet )
144 : {
145 0 : pStm->Seek( 0 );
146 0 : mxStmWrapper = new ::utl::OInputStreamWrapper( pStm, true );
147 : }
148 : else
149 0 : delete pStm;
150 : }
151 0 : }
152 0 : }
153 :
154 0 : SvXMLGraphicInputStream::~SvXMLGraphicInputStream()
155 : {
156 0 : }
157 :
158 0 : sal_Int32 SAL_CALL SvXMLGraphicInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
159 : throw( NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception )
160 : {
161 0 : if( !mxStmWrapper.is() )
162 0 : throw NotConnectedException();
163 :
164 0 : return mxStmWrapper->readBytes( rData, nBytesToRead );
165 : }
166 :
167 0 : sal_Int32 SAL_CALL SvXMLGraphicInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
168 : throw( NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception )
169 : {
170 0 : if( !mxStmWrapper.is() )
171 0 : throw NotConnectedException() ;
172 :
173 0 : return mxStmWrapper->readSomeBytes( rData, nMaxBytesToRead );
174 : }
175 :
176 0 : void SAL_CALL SvXMLGraphicInputStream::skipBytes( sal_Int32 nBytesToSkip )
177 : throw( NotConnectedException, BufferSizeExceededException, RuntimeException, std::exception )
178 : {
179 0 : if( !mxStmWrapper.is() )
180 0 : throw NotConnectedException() ;
181 :
182 0 : mxStmWrapper->skipBytes( nBytesToSkip );
183 0 : }
184 :
185 0 : sal_Int32 SAL_CALL SvXMLGraphicInputStream::available() throw( NotConnectedException, RuntimeException, std::exception )
186 : {
187 0 : if( !mxStmWrapper.is() )
188 0 : throw NotConnectedException() ;
189 :
190 0 : return mxStmWrapper->available();
191 : }
192 :
193 0 : void SAL_CALL SvXMLGraphicInputStream::closeInput() throw( NotConnectedException, RuntimeException, std::exception )
194 : {
195 0 : if( !mxStmWrapper.is() )
196 0 : throw NotConnectedException() ;
197 :
198 0 : mxStmWrapper->closeInput();
199 0 : }
200 :
201 : class SvXMLGraphicOutputStream:
202 : public cppu::WeakImplHelper1<XOutputStream>, private boost::noncopyable
203 : {
204 : private:
205 :
206 : // XOutputStream
207 : virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& rData ) throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
208 : virtual void SAL_CALL flush() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
209 : virtual void SAL_CALL closeOutput() throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
210 :
211 : private:
212 :
213 : ::utl::TempFile* mpTmp;
214 : SvStream* mpOStm;
215 : Reference< XOutputStream > mxStmWrapper;
216 : GraphicObject maGrfObj;
217 : bool mbClosed;
218 :
219 : public:
220 :
221 : SvXMLGraphicOutputStream();
222 : virtual ~SvXMLGraphicOutputStream();
223 :
224 388 : bool Exists() const { return mxStmWrapper.is(); }
225 : const GraphicObject& GetGraphicObject();
226 : };
227 :
228 388 : SvXMLGraphicOutputStream::SvXMLGraphicOutputStream() :
229 388 : mpTmp( new ::utl::TempFile ),
230 776 : mbClosed( false )
231 : {
232 388 : mpTmp->EnableKillingFile();
233 :
234 388 : mpOStm = ::utl::UcbStreamHelper::CreateStream( mpTmp->GetURL(), STREAM_WRITE | STREAM_TRUNC );
235 :
236 388 : if( mpOStm )
237 388 : mxStmWrapper = new ::utl::OOutputStreamWrapper( *mpOStm );
238 388 : }
239 :
240 1164 : SvXMLGraphicOutputStream::~SvXMLGraphicOutputStream()
241 : {
242 388 : delete mpTmp;
243 388 : delete mpOStm;
244 776 : }
245 :
246 958 : void SAL_CALL SvXMLGraphicOutputStream::writeBytes( const Sequence< sal_Int8 >& rData )
247 : throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception )
248 : {
249 958 : if( !mxStmWrapper.is() )
250 0 : throw NotConnectedException() ;
251 :
252 958 : mxStmWrapper->writeBytes( rData );
253 958 : }
254 :
255 0 : void SAL_CALL SvXMLGraphicOutputStream::flush()
256 : throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception )
257 : {
258 0 : if( !mxStmWrapper.is() )
259 0 : throw NotConnectedException() ;
260 :
261 0 : mxStmWrapper->flush();
262 0 : }
263 :
264 388 : void SAL_CALL SvXMLGraphicOutputStream::closeOutput()
265 : throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception )
266 : {
267 388 : if( !mxStmWrapper.is() )
268 0 : throw NotConnectedException() ;
269 :
270 388 : mxStmWrapper->closeOutput();
271 388 : mxStmWrapper.clear();
272 :
273 388 : mbClosed = true;
274 388 : }
275 :
276 388 : const GraphicObject& SvXMLGraphicOutputStream::GetGraphicObject()
277 : {
278 388 : if( mbClosed && ( maGrfObj.GetType() == GRAPHIC_NONE ) && mpOStm )
279 : {
280 388 : Graphic aGraphic;
281 :
282 388 : mpOStm->Seek( 0 );
283 388 : sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
284 388 : sal_uInt16 pDeterminedFormat = GRFILTER_FORMAT_DONTKNOW;
285 388 : GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *mpOStm ,nFormat,&pDeterminedFormat );
286 :
287 388 : if (pDeterminedFormat == GRFILTER_FORMAT_DONTKNOW)
288 : {
289 : //Read the first two byte to check whether it is a gzipped stream, is so it may be in wmz or emz format
290 : //unzip them and try again
291 :
292 : sal_uInt8 sFirstBytes[ 2 ];
293 :
294 0 : mpOStm->Seek( STREAM_SEEK_TO_END );
295 0 : sal_uIntPtr nStreamLen = mpOStm->Tell();
296 0 : mpOStm->Seek( 0 );
297 :
298 0 : if ( !nStreamLen )
299 : {
300 0 : SvLockBytes* pLockBytes = mpOStm->GetLockBytes();
301 0 : if ( pLockBytes )
302 0 : pLockBytes->SetSynchronMode( true );
303 :
304 0 : mpOStm->Seek( STREAM_SEEK_TO_END );
305 0 : nStreamLen = mpOStm->Tell();
306 0 : mpOStm->Seek( 0 );
307 : }
308 0 : if( nStreamLen >= 2 )
309 : {
310 : //read two byte
311 0 : mpOStm->Read( sFirstBytes, 2 );
312 :
313 0 : if( sFirstBytes[0] == 0x1f && sFirstBytes[1] == 0x8b )
314 : {
315 0 : boost::scoped_ptr<SvMemoryStream> pDest(new SvMemoryStream);
316 0 : ZCodec aZCodec( 0x8000, 0x8000 );
317 0 : aZCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, false, true);
318 0 : mpOStm->Seek( 0 );
319 0 : aZCodec.Decompress( *mpOStm, *pDest );
320 :
321 0 : if (aZCodec.EndCompression() && pDest )
322 : {
323 0 : pDest->Seek( STREAM_SEEK_TO_END );
324 0 : sal_uIntPtr nStreamLen_ = pDest->Tell();
325 0 : if (nStreamLen_)
326 : {
327 0 : pDest->Seek(0L);
328 0 : GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *pDest ,nFormat,&pDeterminedFormat );
329 : }
330 0 : }
331 : }
332 : }
333 : }
334 :
335 388 : maGrfObj = aGraphic;
336 388 : if( maGrfObj.GetType() != GRAPHIC_NONE )
337 : {
338 388 : delete mpOStm, mpOStm = NULL;
339 388 : delete mpTmp, mpTmp = NULL;
340 388 : }
341 : }
342 :
343 388 : return maGrfObj;
344 : }
345 :
346 : }
347 :
348 738 : SvXMLGraphicHelper::SvXMLGraphicHelper( SvXMLGraphicHelperMode eCreateMode ) :
349 : ::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver,
350 738 : ::com::sun::star::document::XBinaryStreamResolver >( maMutex )
351 : {
352 738 : Init( NULL, eCreateMode, false );
353 738 : }
354 :
355 2064 : SvXMLGraphicHelper::SvXMLGraphicHelper()
356 : : ::cppu::WeakComponentImplHelper2< ::com::sun::star::document::XGraphicObjectResolver,
357 : ::com::sun::star::document::XBinaryStreamResolver >( maMutex )
358 : , meCreateMode(GRAPHICHELPER_MODE_READ)
359 2064 : , mbDirect(false)
360 : {
361 2064 : }
362 :
363 5604 : SvXMLGraphicHelper::~SvXMLGraphicHelper()
364 : {
365 5604 : }
366 :
367 2802 : void SAL_CALL SvXMLGraphicHelper::disposing()
368 : {
369 2802 : }
370 :
371 142 : bool SvXMLGraphicHelper::ImplGetStreamNames( const OUString& rURLStr,
372 : OUString& rPictureStorageName,
373 : OUString& rPictureStreamName )
374 : {
375 142 : OUString aURLStr( rURLStr );
376 142 : bool bRet = false;
377 :
378 142 : if( !aURLStr.isEmpty() )
379 : {
380 142 : aURLStr = aURLStr.getToken( comphelper::string::getTokenCount(aURLStr, ':') - 1, ':' );
381 :
382 142 : const sal_uInt32 nTokenCount = comphelper::string::getTokenCount(aURLStr, '/');
383 :
384 142 : if( 1 == nTokenCount )
385 : {
386 18 : rPictureStorageName = XML_GRAPHICSTORAGE_NAME;
387 18 : rPictureStreamName = aURLStr;
388 : }
389 : else
390 124 : SvXMLEmbeddedObjectHelper::splitObjectURL(aURLStr, rPictureStorageName, rPictureStreamName);
391 :
392 142 : bRet = !rPictureStreamName.isEmpty();
393 : SAL_WARN_IF(!bRet, "svx", "SvXMLGraphicHelper::ImplInsertGraphicURL: invalid scheme: " << rURLStr);
394 : }
395 :
396 142 : return bRet;
397 : }
398 :
399 142 : uno::Reference < embed::XStorage > SvXMLGraphicHelper::ImplGetGraphicStorage( const OUString& rStorageName )
400 : {
401 142 : uno::Reference < embed::XStorage > xRetStorage;
402 142 : if( mxRootStorage.is() )
403 : {
404 : try
405 : {
406 568 : xRetStorage = mxRootStorage->openStorageElement(
407 142 : maCurStorageName = rStorageName,
408 142 : ( GRAPHICHELPER_MODE_WRITE == meCreateMode )
409 : ? embed::ElementModes::READWRITE
410 284 : : embed::ElementModes::READ );
411 : }
412 0 : catch ( uno::Exception& )
413 : {
414 : }
415 : //#i43196# try again to open the storage element - this time readonly
416 142 : if(!xRetStorage.is())
417 : {
418 : try
419 : {
420 0 : xRetStorage = mxRootStorage->openStorageElement( maCurStorageName = rStorageName, embed::ElementModes::READ );
421 : }
422 0 : catch ( uno::Exception& )
423 : {
424 : }
425 : }
426 : }
427 :
428 142 : return xRetStorage;
429 : }
430 :
431 142 : SvxGraphicHelperStream_Impl SvXMLGraphicHelper::ImplGetGraphicStream( const OUString& rPictureStorageName,
432 : const OUString& rPictureStreamName,
433 : bool bTruncate )
434 : {
435 142 : SvxGraphicHelperStream_Impl aRet;
436 142 : aRet.xStorage = ImplGetGraphicStorage( rPictureStorageName );
437 :
438 142 : if( aRet.xStorage.is() )
439 : {
440 142 : sal_Int32 nMode = embed::ElementModes::READ;
441 142 : if ( GRAPHICHELPER_MODE_WRITE == meCreateMode )
442 : {
443 18 : nMode = embed::ElementModes::READWRITE;
444 18 : if ( bTruncate )
445 0 : nMode |= embed::ElementModes::TRUNCATE;
446 : }
447 :
448 142 : aRet.xStream = aRet.xStorage->openStreamElement( rPictureStreamName, nMode );
449 142 : if( aRet.xStream.is() && ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) )
450 : {
451 18 : OUString aPropName( "UseCommonStoragePasswordEncryption" );
452 36 : uno::Reference < beans::XPropertySet > xProps( aRet.xStream, uno::UNO_QUERY );
453 36 : xProps->setPropertyValue( aPropName, uno::makeAny( sal_True) );
454 : }
455 : }
456 :
457 142 : return aRet;
458 : }
459 :
460 18 : OUString SvXMLGraphicHelper::ImplGetGraphicMimeType( const OUString& rFileName ) const
461 : {
462 : struct XMLGraphicMimeTypeMapper
463 : {
464 : const char* pExt;
465 : const char* pMimeType;
466 : };
467 :
468 : static const XMLGraphicMimeTypeMapper aMapper[] =
469 : {
470 : { "gif", "image/gif" },
471 : { "png", "image/png" },
472 : { "jpg", "image/jpeg" },
473 : { "tif", "image/tiff" },
474 : { "svg", "image/svg+xml" }
475 : };
476 :
477 18 : OUString aMimeType;
478 :
479 18 : if( ( rFileName.getLength() >= 4 ) && ( rFileName[ rFileName.getLength() - 4 ] == '.' ) )
480 : {
481 18 : const OString aExt(OUStringToOString(rFileName.copy(rFileName.getLength() - 3),
482 18 : RTL_TEXTENCODING_ASCII_US));
483 :
484 70 : for( long i = 0, nCount = sizeof (aMapper) / sizeof (aMapper[0]); ( i < nCount ) && aMimeType.isEmpty(); i++ )
485 52 : if( strcmp(aExt.getStr(), aMapper[ i ].pExt) == 0 )
486 34 : aMimeType = OUString( aMapper[ i ].pMimeType, strlen( aMapper[ i ].pMimeType ), RTL_TEXTENCODING_ASCII_US );
487 : }
488 :
489 18 : return aMimeType;
490 : }
491 :
492 124 : Graphic SvXMLGraphicHelper::ImplReadGraphic( const OUString& rPictureStorageName,
493 : const OUString& rPictureStreamName )
494 : {
495 124 : Graphic aGraphic;
496 248 : SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, false ) );
497 124 : if( aStream.xStream.is() )
498 : {
499 124 : boost::scoped_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream( aStream.xStream ));
500 124 : GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *pStream );
501 : }
502 :
503 248 : return aGraphic;
504 : }
505 :
506 18 : bool SvXMLGraphicHelper::ImplWriteGraphic( const OUString& rPictureStorageName,
507 : const OUString& rPictureStreamName,
508 : const OUString& rGraphicId,
509 : bool bUseGfxLink )
510 : {
511 18 : GraphicObject aGrfObject( OUStringToOString(rGraphicId, RTL_TEXTENCODING_ASCII_US) );
512 18 : bool bRet = false;
513 :
514 18 : if( aGrfObject.GetType() != GRAPHIC_NONE )
515 : {
516 18 : SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName, false ) );
517 18 : if( aStream.xStream.is() )
518 : {
519 18 : Graphic aGraphic( (Graphic&) aGrfObject.GetGraphic() );
520 36 : const GfxLink aGfxLink( aGraphic.GetLink() );
521 36 : const OUString aMimeType( ImplGetGraphicMimeType( rPictureStreamName ) );
522 36 : uno::Any aAny;
523 36 : uno::Reference < beans::XPropertySet > xProps( aStream.xStream, uno::UNO_QUERY );
524 :
525 : // set stream properties (MediaType/Compression)
526 18 : if( !aMimeType.isEmpty() )
527 : {
528 16 : aAny <<= aMimeType;
529 16 : xProps->setPropertyValue( "MediaType", aAny );
530 : }
531 :
532 18 : const bool bCompressed = aMimeType.isEmpty() || aMimeType == "image/tiff" || aMimeType == "image/svg+xml";
533 18 : aAny <<= bCompressed;
534 18 : xProps->setPropertyValue( "Compressed", aAny );
535 :
536 36 : boost::scoped_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream( aStream.xStream ));
537 18 : if( bUseGfxLink && aGfxLink.GetDataSize() && aGfxLink.GetData() )
538 16 : pStream->Write( aGfxLink.GetData(), aGfxLink.GetDataSize() );
539 : else
540 : {
541 2 : if( aGraphic.GetType() == GRAPHIC_BITMAP )
542 : {
543 0 : GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
544 0 : OUString aFormat;
545 :
546 0 : if( aGraphic.IsAnimated() )
547 0 : aFormat = "gif";
548 : else
549 0 : aFormat = "png";
550 :
551 0 : bRet = ( rFilter.ExportGraphic( aGraphic, "", *pStream,
552 0 : rFilter.GetExportFormatNumberForShortName( aFormat ) ) == 0 );
553 : }
554 2 : else if( aGraphic.GetType() == GRAPHIC_GDIMETAFILE )
555 : {
556 2 : pStream->SetVersion( SOFFICE_FILEFORMAT_8 );
557 2 : pStream->SetCompressMode( COMPRESSMODE_ZBITMAP );
558 :
559 : // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
560 2 : GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() );
561 2 : const MetaCommentAction* pComment = ImplCheckForEPS( rMtf );
562 2 : if ( pComment )
563 : {
564 0 : sal_uInt32 nSize = pComment->GetDataSize();
565 0 : const sal_uInt8* pData = pComment->GetData();
566 0 : if ( nSize && pData )
567 0 : pStream->Write( pData, nSize );
568 :
569 0 : const MetaEPSAction* pAct = static_cast<const MetaEPSAction*>(rMtf.FirstAction());
570 0 : const GfxLink& rLink = pAct->GetLink();
571 :
572 0 : pStream->Write( rLink.GetData(), rLink.GetDataSize() );
573 : }
574 : else
575 2 : rMtf.Write( *pStream );
576 :
577 2 : bRet = ( pStream->GetError() == 0 );
578 : }
579 : }
580 : uno::Reference < embed::XTransactedObject > xStorage(
581 36 : aStream.xStorage, uno::UNO_QUERY);
582 18 : pStream.reset();
583 18 : aStream.xStream->getOutputStream()->closeOutput();
584 18 : if( xStorage.is() )
585 36 : xStorage->commit();
586 18 : }
587 : }
588 :
589 18 : return bRet;
590 : }
591 :
592 152 : void SvXMLGraphicHelper::ImplInsertGraphicURL( const OUString& rURLStr, sal_uInt32 nInsertPos, OUString& rRequestedFileName )
593 : {
594 152 : OUString aURLString( rURLStr );
595 304 : OUString aPictureStorageName, aPictureStreamName;
596 152 : if( ( maURLSet.find( aURLString ) != maURLSet.end() ) )
597 : {
598 10 : for (URLPairVector::const_iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() ); aIter != aEnd ; ++aIter)
599 : {
600 10 : if( aURLString == (*aIter).first )
601 : {
602 10 : maGrfURLs[ nInsertPos ].second = (*aIter).second;
603 10 : break;
604 : }
605 : }
606 : }
607 142 : else if( ImplGetStreamNames( aURLString, aPictureStorageName, aPictureStreamName ) )
608 : {
609 142 : URLPair& rURLPair = maGrfURLs[ nInsertPos ];
610 :
611 142 : if( GRAPHICHELPER_MODE_READ == meCreateMode )
612 : {
613 124 : const GraphicObject aObj( ImplReadGraphic( aPictureStorageName, aPictureStreamName ) );
614 :
615 124 : if( aObj.GetType() != GRAPHIC_NONE )
616 : {
617 124 : maGrfObjs.push_back( aObj );
618 124 : OUString aBaseURL( XML_GRAPHICOBJECT_URL_BASE );
619 :
620 124 : rURLPair.second = aBaseURL;
621 248 : rURLPair.second += OStringToOUString(aObj.GetUniqueID(),
622 248 : RTL_TEXTENCODING_ASCII_US);
623 : }
624 : else
625 0 : rURLPair.second = "";
626 : }
627 : else
628 : {
629 18 : const OUString aGraphicObjectId( aPictureStreamName );
630 36 : const OString aAsciiObjectID(OUStringToOString(aGraphicObjectId, RTL_TEXTENCODING_ASCII_US));
631 36 : const GraphicObject aGrfObject( aAsciiObjectID );
632 18 : if( aGrfObject.GetType() != GRAPHIC_NONE )
633 : {
634 18 : OUString aStreamName( aGraphicObjectId );
635 36 : Graphic aGraphic( (Graphic&) aGrfObject.GetGraphic() );
636 36 : const GfxLink aGfxLink( aGraphic.GetLink() );
637 36 : OUString aExtension;
638 18 : bool bUseGfxLink( true );
639 :
640 18 : if( aGfxLink.GetDataSize() )
641 : {
642 16 : switch( aGfxLink.GetType() )
643 : {
644 0 : case( GFX_LINK_TYPE_EPS_BUFFER ): aExtension = ".eps"; break;
645 2 : case( GFX_LINK_TYPE_NATIVE_GIF ): aExtension = ".gif"; break;
646 : // #i15508# added BMP type for better exports (checked, works)
647 0 : case( GFX_LINK_TYPE_NATIVE_BMP ): aExtension = ".bmp"; break;
648 12 : case( GFX_LINK_TYPE_NATIVE_JPG ): aExtension = ".jpg"; break;
649 2 : case( GFX_LINK_TYPE_NATIVE_PNG ): aExtension = ".png"; break;
650 0 : case( GFX_LINK_TYPE_NATIVE_TIF ): aExtension = ".tif"; break;
651 0 : case( GFX_LINK_TYPE_NATIVE_WMF ): aExtension = ".wmf"; break;
652 0 : case( GFX_LINK_TYPE_NATIVE_MET ): aExtension = ".met"; break;
653 0 : case( GFX_LINK_TYPE_NATIVE_PCT ): aExtension = ".pct"; break;
654 : case( GFX_LINK_TYPE_NATIVE_SVG ):
655 : // backward-compat kludge: since no released OOo
656 : // version to date can handle svg properly, wrap it up
657 : // into an svm. slight catch22 here, since strict ODF
658 : // conformance _recommends_ svg - then again, most old
659 : // ODF consumers are believed to be OOo
660 0 : if( SvtSaveOptions().GetODFDefaultVersion() <= SvtSaveOptions::ODFVER_012 )
661 : {
662 0 : bUseGfxLink = false;
663 0 : aExtension = ".svm";
664 : }
665 : else
666 0 : aExtension = ".svg";
667 0 : break;
668 :
669 : default:
670 0 : aExtension = ".grf";
671 0 : break;
672 : }
673 : }
674 : else
675 : {
676 2 : if( aGrfObject.GetType() == GRAPHIC_BITMAP )
677 : {
678 0 : if( aGrfObject.IsAnimated() )
679 0 : aExtension = ".gif";
680 : else
681 0 : aExtension = ".png";
682 : }
683 2 : else if( aGrfObject.GetType() == GRAPHIC_GDIMETAFILE )
684 : {
685 : // SJ: first check if this metafile is just a eps file, then we will store the eps instead of svm
686 2 : GDIMetaFile& rMtf( (GDIMetaFile&)aGraphic.GetGDIMetaFile() );
687 2 : if ( ImplCheckForEPS( rMtf ) )
688 0 : aExtension = ".eps";
689 : else
690 2 : aExtension = ".svm";
691 : }
692 : }
693 :
694 18 : OUString aURLEntry;
695 36 : const OUString sPictures( "Pictures/" );
696 :
697 18 : if ( !rRequestedFileName.isEmpty() )
698 : {
699 0 : aURLEntry = sPictures;
700 0 : aURLEntry += rRequestedFileName;
701 0 : aURLEntry += aExtension;
702 :
703 0 : URLPairVector::const_iterator aIter( maGrfURLs.begin() ), aEnd( maGrfURLs.end() );
704 0 : for ( ; aIter != aEnd; ++aIter )
705 : {
706 0 : if( aURLEntry == (*aIter).second )
707 0 : break;
708 : }
709 0 : if ( aIter == aEnd )
710 0 : aStreamName = rRequestedFileName;
711 : }
712 :
713 18 : aStreamName += aExtension;
714 :
715 18 : if( mbDirect && !aStreamName.isEmpty() )
716 18 : ImplWriteGraphic( aPictureStorageName, aStreamName, aGraphicObjectId, bUseGfxLink );
717 :
718 18 : rURLPair.second = sPictures;
719 54 : rURLPair.second += aStreamName;
720 18 : }
721 : #if OSL_DEBUG_LEVEL > 0
722 : else
723 : {
724 : OStringBuffer sMessage("graphic object with ID '");
725 : sMessage.append(aAsciiObjectID).
726 : append("' has an unknown type");
727 : OSL_ENSURE( false, sMessage.getStr() );
728 : }
729 : #endif
730 : }
731 :
732 142 : maURLSet.insert( aURLString );
733 152 : }
734 152 : }
735 :
736 2802 : void SvXMLGraphicHelper::Init( const uno::Reference < embed::XStorage >& rXMLStorage,
737 : SvXMLGraphicHelperMode eCreateMode,
738 : bool bDirect )
739 : {
740 2802 : mxRootStorage = rXMLStorage;
741 2802 : meCreateMode = eCreateMode;
742 2802 : mbDirect = ( ( GRAPHICHELPER_MODE_READ == meCreateMode ) ? bDirect : sal_True );
743 2802 : }
744 :
745 1532 : SvXMLGraphicHelper* SvXMLGraphicHelper::Create( const uno::Reference < embed::XStorage >& rXMLStorage,
746 : SvXMLGraphicHelperMode eCreateMode,
747 : bool bDirect )
748 : {
749 1532 : SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper;
750 :
751 1532 : pThis->acquire();
752 1532 : pThis->Init( rXMLStorage, eCreateMode, bDirect );
753 :
754 1532 : return pThis;
755 : }
756 :
757 532 : SvXMLGraphicHelper* SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode eCreateMode )
758 : {
759 532 : SvXMLGraphicHelper* pThis = new SvXMLGraphicHelper;
760 :
761 532 : pThis->acquire();
762 532 : pThis->Init( NULL, eCreateMode, false );
763 :
764 532 : return pThis;
765 : }
766 :
767 860 : void SvXMLGraphicHelper::Destroy( SvXMLGraphicHelper* pSvXMLGraphicHelper )
768 : {
769 860 : if( pSvXMLGraphicHelper )
770 : {
771 860 : pSvXMLGraphicHelper->dispose();
772 860 : pSvXMLGraphicHelper->release();
773 : }
774 860 : }
775 :
776 : // XGraphicObjectResolver
777 152 : OUString SAL_CALL SvXMLGraphicHelper::resolveGraphicObjectURL( const OUString& rURL )
778 : throw(uno::RuntimeException, std::exception)
779 : {
780 152 : ::osl::MutexGuard aGuard( maMutex );
781 152 : const sal_Int32 nIndex = maGrfURLs.size();
782 :
783 304 : OUString aURL( rURL );
784 304 : OUString aUserData;
785 304 : OUString aRequestedFileName;
786 :
787 152 : sal_Int32 nUser = rURL.indexOf( '?', 0 );
788 152 : if ( nUser >= 0 )
789 : {
790 0 : aURL = rURL.copy( 0, nUser );
791 0 : nUser++;
792 0 : aUserData = rURL.copy( nUser, rURL.getLength() - nUser );
793 : }
794 152 : if ( !aUserData.isEmpty() )
795 : {
796 0 : sal_Int32 nIndex2 = 0;
797 0 : do
798 : {
799 0 : OUString aToken = aUserData.getToken( 0, ';', nIndex2 );
800 0 : sal_Int32 n = aToken.indexOf( '=' );
801 0 : if ( ( n > 0 ) && ( ( n + 1 ) < aToken.getLength() ) )
802 : {
803 0 : OUString aParam( aToken.copy( 0, n ) );
804 0 : OUString aValue( aToken.copy( n + 1, aToken.getLength() - ( n + 1 ) ) );
805 :
806 0 : const OUString sRequestedName( "requestedName" );
807 0 : if ( aParam.match( sRequestedName ) )
808 0 : aRequestedFileName = aValue;
809 0 : }
810 : }
811 0 : while ( nIndex2 >= 0 );
812 : }
813 :
814 152 : maGrfURLs.push_back( ::std::make_pair( aURL, OUString() ) );
815 152 : ImplInsertGraphicURL( aURL, nIndex, aRequestedFileName );
816 :
817 304 : return maGrfURLs[ nIndex ].second;
818 : }
819 :
820 : // XBinaryStreamResolver
821 0 : Reference< XInputStream > SAL_CALL SvXMLGraphicHelper::getInputStream( const OUString& rURL )
822 : throw( RuntimeException, std::exception )
823 : {
824 0 : Reference< XInputStream > xRet;
825 0 : OUString aPictureStorageName, aGraphicId;
826 :
827 :
828 0 : if( ( GRAPHICHELPER_MODE_WRITE == meCreateMode ) &&
829 0 : ImplGetStreamNames( rURL, aPictureStorageName, aGraphicId ) )
830 : {
831 0 : SvXMLGraphicInputStream* pInputStream = new SvXMLGraphicInputStream( aGraphicId );
832 :
833 0 : if( pInputStream->Exists() )
834 0 : xRet = pInputStream;
835 : else
836 0 : delete pInputStream;
837 : }
838 :
839 0 : return xRet;
840 : }
841 :
842 388 : Reference< XOutputStream > SAL_CALL SvXMLGraphicHelper::createOutputStream()
843 : throw( RuntimeException, std::exception )
844 : {
845 388 : Reference< XOutputStream > xRet;
846 :
847 388 : if( GRAPHICHELPER_MODE_READ == meCreateMode )
848 : {
849 388 : SvXMLGraphicOutputStream* pOutputStream = new SvXMLGraphicOutputStream;
850 :
851 388 : if( pOutputStream->Exists() )
852 388 : maGrfStms.push_back( xRet = pOutputStream );
853 : else
854 0 : delete pOutputStream;
855 : }
856 :
857 388 : return xRet;
858 : }
859 :
860 388 : OUString SAL_CALL SvXMLGraphicHelper::resolveOutputStream( const Reference< XOutputStream >& rxBinaryStream )
861 : throw( RuntimeException, std::exception )
862 : {
863 388 : OUString aRet;
864 :
865 388 : if( ( GRAPHICHELPER_MODE_READ == meCreateMode ) && rxBinaryStream.is() )
866 : {
867 388 : if( ::std::find( maGrfStms.begin(), maGrfStms.end(), rxBinaryStream ) != maGrfStms.end() )
868 : {
869 388 : SvXMLGraphicOutputStream* pOStm = static_cast< SvXMLGraphicOutputStream* >( rxBinaryStream.get() );
870 :
871 388 : if( pOStm )
872 : {
873 388 : const GraphicObject& rGrfObj = pOStm->GetGraphicObject();
874 : const OUString aId(OStringToOUString(
875 388 : rGrfObj.GetUniqueID(), RTL_TEXTENCODING_ASCII_US));
876 :
877 388 : if( !aId.isEmpty() )
878 : {
879 388 : aRet = XML_GRAPHICOBJECT_URL_BASE;
880 388 : aRet += aId;
881 388 : }
882 : }
883 : }
884 : }
885 :
886 388 : return aRet;
887 : }
888 :
889 : // for instantiation via service manager
890 : namespace {
891 :
892 : namespace impl
893 : {
894 : typedef ::cppu::WeakComponentImplHelper4<
895 : lang::XInitialization,
896 : document::XGraphicObjectResolver,
897 : document::XBinaryStreamResolver,
898 : lang::XServiceInfo >
899 : SvXMLGraphicImportExportHelper_Base;
900 782 : class MutexContainer
901 : {
902 : public:
903 : virtual ~MutexContainer();
904 :
905 : protected:
906 : mutable ::osl::Mutex m_aMutex;
907 : };
908 782 : MutexContainer::~MutexContainer()
909 782 : {}
910 : } // namespace impl
911 :
912 1564 : class SvXMLGraphicImportExportHelper :
913 : public impl::MutexContainer,
914 : public impl::SvXMLGraphicImportExportHelper_Base
915 : {
916 : public:
917 : SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode );
918 :
919 : protected:
920 : // is called from WeakComponentImplHelper when XComponent::dispose() was
921 : // called from outside
922 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
923 :
924 : // ____ XInitialization ____
925 : // one argument is allowed, which is the XStorage
926 : virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
927 : throw (Exception,
928 : RuntimeException, std::exception) SAL_OVERRIDE;
929 :
930 : // ____ XGraphicObjectResolver ____
931 : virtual OUString SAL_CALL resolveGraphicObjectURL( const OUString& aURL )
932 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
933 :
934 : // ____ XBinaryStreamResolver ____
935 : virtual Reference< io::XInputStream > SAL_CALL getInputStream( const OUString& aURL )
936 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
937 : virtual Reference< io::XOutputStream > SAL_CALL createOutputStream()
938 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
939 : virtual OUString SAL_CALL resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream )
940 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
941 :
942 : // ____ XServiceInfo ____
943 : virtual OUString SAL_CALL getImplementationName()
944 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
945 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName )
946 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
947 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
948 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
949 :
950 : private:
951 : SvXMLGraphicHelperMode m_eGraphicHelperMode;
952 : Reference< XGraphicObjectResolver > m_xGraphicObjectResolver;
953 : Reference< XBinaryStreamResolver > m_xBinaryStreamResolver;
954 : };
955 :
956 782 : SvXMLGraphicImportExportHelper::SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ) :
957 : impl::SvXMLGraphicImportExportHelper_Base( m_aMutex ),
958 782 : m_eGraphicHelperMode( eMode )
959 782 : {}
960 :
961 782 : void SAL_CALL SvXMLGraphicImportExportHelper::disposing()
962 : {
963 782 : Reference< XComponent > xComp( m_xGraphicObjectResolver, UNO_QUERY );
964 : OSL_ASSERT( xComp.is());
965 782 : if( xComp.is())
966 782 : xComp->dispose();
967 : // m_xBinaryStreamResolver is a reference to the same object => don't call
968 : // dispose() again
969 782 : }
970 :
971 : // ____ XInitialization ____
972 782 : void SAL_CALL SvXMLGraphicImportExportHelper::initialize(
973 : const Sequence< Any >& aArguments )
974 : throw (Exception, RuntimeException, std::exception)
975 : {
976 782 : Reference< embed::XStorage > xStorage;
977 782 : if( aArguments.getLength() > 0 )
978 782 : aArguments[0] >>= xStorage;
979 :
980 782 : SvXMLGraphicHelper * pHelper( SvXMLGraphicHelper::Create( xStorage, m_eGraphicHelperMode ));
981 782 : m_xGraphicObjectResolver.set( pHelper );
982 782 : m_xBinaryStreamResolver.set( pHelper );
983 : // SvXMLGraphicHelper::Create calls acquire. Since we have two references
984 : // now it is safe (and necessary) to undo this acquire
985 782 : pHelper->release();
986 782 : }
987 :
988 : // ____ XGraphicObjectResolver ____
989 48 : OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveGraphicObjectURL( const OUString& aURL )
990 : throw (uno::RuntimeException, std::exception)
991 : {
992 48 : return m_xGraphicObjectResolver->resolveGraphicObjectURL( aURL );
993 : }
994 :
995 :
996 : // ____ XBinaryStreamResolver ____
997 0 : Reference< io::XInputStream > SAL_CALL SvXMLGraphicImportExportHelper::getInputStream( const OUString& aURL )
998 : throw (uno::RuntimeException, std::exception)
999 : {
1000 0 : return m_xBinaryStreamResolver->getInputStream( aURL );
1001 : }
1002 0 : Reference< io::XOutputStream > SAL_CALL SvXMLGraphicImportExportHelper::createOutputStream()
1003 : throw (uno::RuntimeException, std::exception)
1004 : {
1005 0 : return m_xBinaryStreamResolver->createOutputStream();
1006 : }
1007 0 : OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream )
1008 : throw (uno::RuntimeException, std::exception)
1009 : {
1010 0 : return m_xBinaryStreamResolver->resolveOutputStream( aBinaryStream );
1011 : }
1012 :
1013 : // ____ XServiceInfo ____
1014 0 : OUString SAL_CALL SvXMLGraphicImportExportHelper::getImplementationName()
1015 : throw (uno::RuntimeException, std::exception)
1016 : {
1017 0 : if( m_eGraphicHelperMode == GRAPHICHELPER_MODE_READ )
1018 0 : return OUString("com.sun.star.comp.Svx.GraphicImportHelper");
1019 0 : return OUString("com.sun.star.comp.Svx.GraphicExportHelper");
1020 : }
1021 :
1022 0 : sal_Bool SAL_CALL SvXMLGraphicImportExportHelper::supportsService( const OUString& ServiceName )
1023 : throw (uno::RuntimeException, std::exception)
1024 : {
1025 0 : return cppu::supportsService(this, ServiceName);
1026 : }
1027 :
1028 0 : Sequence< OUString > SAL_CALL SvXMLGraphicImportExportHelper::getSupportedServiceNames()
1029 : throw (uno::RuntimeException, std::exception)
1030 : {
1031 : // XGraphicObjectResolver and XBinaryStreamResolver are not part of any service
1032 0 : Sequence< OUString > aSupportedServiceNames( 2 );
1033 0 : aSupportedServiceNames[0] = "com.sun.star.document.GraphicObjectResolver";
1034 0 : aSupportedServiceNames[1] = "com.sun.star.document.BinaryStreamResolver";
1035 0 : return aSupportedServiceNames;
1036 : }
1037 :
1038 : }
1039 :
1040 : /** Create this with createInstanceWithArguments. service name
1041 : "com.sun.star.comp.Svx.GraphicImportHelper", one argument which is the
1042 : XStorage. Without arguments no helper class is created. With an empty
1043 : argument the helper class is created and initialized like in the CTOR to
1044 : SvXMLGraphicHelper that only gets the create mode.
1045 :
1046 : You should call dispose after you no longer need this component.
1047 :
1048 : uses eCreateMode == GRAPHICHELPER_MODE_READ, bDirect == sal_True in
1049 : SvXMLGraphicHelper
1050 : */
1051 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1052 238 : com_sun_star_comp_Svx_GraphicImportHelper_get_implementation(
1053 : css::uno::XComponentContext *,
1054 : css::uno::Sequence<css::uno::Any> const &)
1055 : {
1056 238 : return cppu::acquire(new SvXMLGraphicImportExportHelper(GRAPHICHELPER_MODE_READ));
1057 : }
1058 :
1059 : /** Create this with createInstanceWithArguments. service name
1060 : "com.sun.star.comp.Svx.GraphicExportHelper", one argument which is the
1061 : XStorage. Without arguments no helper class is created. With an empty
1062 : argument the helper class is created and initialized like in the CTOR to
1063 : SvXMLGraphicHelper that only gets the create mode
1064 :
1065 : To write the Pictures stream, you have to call dispose at this component.
1066 : Make sure you call dipose before you commit the parent storage.
1067 :
1068 : uses eCreateMode == GRAPHICHELPER_MODE_WRITE, bDirect == sal_True in
1069 : SvXMLGraphicHelper
1070 : */
1071 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1072 544 : com_sun_star_comp_Svx_GraphicExportHelper_get_implementation(
1073 : css::uno::XComponentContext *,
1074 : css::uno::Sequence<css::uno::Any> const &)
1075 : {
1076 544 : return cppu::acquire(new SvXMLGraphicImportExportHelper(GRAPHICHELPER_MODE_WRITE));
1077 651 : }
1078 :
1079 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|