LibreOffice Module svx (master)  1
xmlgrhlp.cxx
Go to the documentation of this file.
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 #include <sal/log.hxx>
22 
23 #include <com/sun/star/embed/XTransactedObject.hpp>
24 #include <com/sun/star/embed/ElementModes.hpp>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/io/NotConnectedException.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <comphelper/fileformat.h>
31 #include <cppuhelper/compbase.hxx>
32 #include <cppuhelper/implbase.hxx>
34 
35 #include <rtl/ref.hxx>
37 #include <unotools/streamwrap.hxx>
38 #include <unotools/tempfile.hxx>
39 #include <unotools/saveopt.hxx>
40 #include <vcl/gfxlink.hxx>
41 #include <vcl/metaact.hxx>
42 #include <tools/zcodec.hxx>
43 
44 #include <vcl/GraphicObject.hxx>
45 #include <vcl/graphicfilter.hxx>
46 #include <svx/xmlgrhlp.hxx>
47 #include <svx/xmleohlp.hxx>
48 
49 #include <algorithm>
50 #include <memory>
51 #include <utility>
52 
53 using namespace com::sun::star;
54 using namespace com::sun::star::uno;
55 using namespace com::sun::star::io;
56 
57 namespace com::sun::star::uno { class XComponentContext; }
58 
59 #define XML_GRAPHICSTORAGE_NAME "Pictures"
60 #define XML_GRAPHICOBJECT_URL_BASE "vnd.sun.star.GraphicObject:"
61 
62 namespace {
63 
64 const MetaCommentAction* ImplCheckForEPS( GDIMetaFile const & rMtf )
65 {
66  const MetaCommentAction* pComment = nullptr;
67 
68  if ( rMtf.GetActionSize() >= 2
69  && rMtf.GetAction(0)->GetType() == MetaActionType::EPS
70  && rMtf.GetAction(1)->GetType() == MetaActionType::COMMENT
71  && ( static_cast<const MetaCommentAction*>(rMtf.GetAction( 1 ))->GetComment() == "EPSReplacementGraphic" ) )
72  pComment = static_cast<const MetaCommentAction*>(rMtf.GetAction( 1 ));
73 
74  return pComment;
75 }
76 
77 class GraphicInputStream : public cppu::WeakImplHelper<XInputStream>
78 {
79 private:
80  virtual sal_Int32 SAL_CALL readBytes(Sequence<sal_Int8> & aData, sal_Int32 nBytesToRead) override;
81  virtual sal_Int32 SAL_CALL readSomeBytes(Sequence<sal_Int8> & aData, sal_Int32 nMaxBytesToRead) override;
82  virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override;
83  virtual sal_Int32 SAL_CALL available() override;
84  virtual void SAL_CALL closeInput() override;
85 
86 private:
87  utl::TempFile maTempFile;
88  Reference<XInputStream> mxStreamWrapper;
89 
90 public:
91 
92  explicit GraphicInputStream(GraphicObject const & raGraphicObject, const OUString & rMimeType);
93  GraphicInputStream(const GraphicInputStream&) = delete;
94 
95  GraphicInputStream& operator=(const GraphicInputStream&) = delete;
96 
97  bool exists() const
98  {
99  return mxStreamWrapper.is();
100  }
101 };
102 
103 
104 GraphicInputStream::GraphicInputStream(GraphicObject const & aGraphicObject, const OUString & rMimeType)
105 {
106  maTempFile.EnableKillingFile();
107 
108  if (aGraphicObject.GetType() != GraphicType::NONE)
109  {
110  std::unique_ptr<SvStream> pStream = ::utl::UcbStreamHelper::CreateStream(maTempFile.GetURL(), StreamMode::WRITE | StreamMode::TRUNC);
111 
112  if (pStream)
113  {
114  const Graphic& aGraphic(aGraphicObject.GetGraphic());
115  const GfxLink aGfxLink(aGraphic.GetGfxLink());
116  bool bRet = false;
117 
118  if (aGfxLink.GetDataSize() && aGfxLink.GetData())
119  {
120  if (rMimeType.isEmpty())
121  {
122  pStream->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
123  bRet = (pStream->GetError() == ERRCODE_NONE);
124  }
125  else
126  {
128  bRet = (rFilter.ExportGraphic(aGraphic, "", *pStream, rFilter.GetExportFormatNumberForMediaType(rMimeType)) == ERRCODE_NONE);
129  }
130  }
131  else
132  {
133  if (aGraphic.GetType() == GraphicType::Bitmap)
134  {
136  OUString aFormat = rMimeType;
137 
138  if (aGraphic.IsAnimated())
139  aFormat = "image/gif";
140  else if (aFormat.isEmpty())
141  aFormat = "image/png";
142 
143  bRet = (rFilter.ExportGraphic(aGraphic, "", *pStream, rFilter.GetExportFormatNumberForMediaType(aFormat)) == ERRCODE_NONE);
144  }
145  else if (rMimeType.isEmpty() && aGraphic.GetType() == GraphicType::GdiMetafile)
146  {
147  pStream->SetVersion(SOFFICE_FILEFORMAT_8);
148  pStream->SetCompressMode(SvStreamCompressFlags::ZBITMAP);
149  const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile()).Write(*pStream);
150  bRet = (pStream->GetError() == ERRCODE_NONE);
151  }
152  else if (!rMimeType.isEmpty())
153  {
155  bRet = ( rFilter.ExportGraphic( aGraphic, "", *pStream, rFilter.GetExportFormatNumberForMediaType( rMimeType ) ) == ERRCODE_NONE );
156  }
157  }
158 
159  if (bRet)
160  {
161  pStream->Seek( 0 );
162  mxStreamWrapper = new ::utl::OInputStreamWrapper(std::move(pStream));
163  }
164  }
165  }
166 }
167 
168 sal_Int32 SAL_CALL GraphicInputStream::readBytes(Sequence<sal_Int8> & rData, sal_Int32 nBytesToRead)
169 {
170  if (!mxStreamWrapper.is())
171  throw NotConnectedException();
172 
173  return mxStreamWrapper->readBytes(rData, nBytesToRead);
174 }
175 
176 sal_Int32 SAL_CALL GraphicInputStream::readSomeBytes(Sequence<sal_Int8>& rData, sal_Int32 nMaxBytesToRead )
177 {
178  if (!mxStreamWrapper.is())
179  throw NotConnectedException() ;
180 
181  return mxStreamWrapper->readSomeBytes(rData, nMaxBytesToRead);
182 }
183 
184 void SAL_CALL GraphicInputStream::skipBytes(sal_Int32 nBytesToSkip)
185 {
186  if (!mxStreamWrapper.is())
187  throw NotConnectedException();
188 
189  mxStreamWrapper->skipBytes(nBytesToSkip);
190 }
191 
192 sal_Int32 SAL_CALL GraphicInputStream::available()
193 {
194  if (!mxStreamWrapper.is())
195  throw NotConnectedException();
196 
197  return mxStreamWrapper->available();
198 }
199 
200 void SAL_CALL GraphicInputStream::closeInput()
201 {
202  if (!mxStreamWrapper.is())
203  throw NotConnectedException();
204 
205  mxStreamWrapper->closeInput();
206 }
207 
208 class SvXMLGraphicOutputStream:
209  public cppu::WeakImplHelper<XOutputStream>
210 {
211 private:
212 
213  // XOutputStream
214  virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& rData ) override;
215  virtual void SAL_CALL flush() override;
216  virtual void SAL_CALL closeOutput() override;
217 
218 private:
219 
220  std::unique_ptr<::utl::TempFile> mpTmp;
221  std::unique_ptr<SvStream> mpOStm;
222  Reference< XOutputStream > mxStmWrapper;
223  std::unique_ptr<GraphicObject> mxGrfObj;
224  bool mbClosed;
225 
226 public:
227 
228  SvXMLGraphicOutputStream();
229  virtual ~SvXMLGraphicOutputStream() override;
230  SvXMLGraphicOutputStream(const SvXMLGraphicOutputStream&) = delete;
231  SvXMLGraphicOutputStream& operator=(const SvXMLGraphicOutputStream&) = delete;
232 
233  bool Exists() const { return mxStmWrapper.is(); }
234  const GraphicObject& GetGraphicObject();
235  Graphic GetGraphic();
236 };
237 
238 SvXMLGraphicOutputStream::SvXMLGraphicOutputStream()
239  : mpTmp(new ::utl::TempFile)
240  , mxGrfObj(new GraphicObject)
241  , mbClosed(false)
242 {
243  mpTmp->EnableKillingFile();
244 
245  mpOStm = ::utl::UcbStreamHelper::CreateStream( mpTmp->GetURL(), StreamMode::WRITE | StreamMode::TRUNC );
246 
247  if( mpOStm )
248  mxStmWrapper = new ::utl::OOutputStreamWrapper( *mpOStm );
249 }
250 
251 SvXMLGraphicOutputStream::~SvXMLGraphicOutputStream()
252 {
253  mpTmp.reset();
254  mpOStm.reset();
255 }
256 
257 void SAL_CALL SvXMLGraphicOutputStream::writeBytes( const Sequence< sal_Int8 >& rData )
258 {
259  if( !mxStmWrapper.is() )
260  throw NotConnectedException() ;
261 
262  mxStmWrapper->writeBytes( rData );
263 }
264 
265 void SAL_CALL SvXMLGraphicOutputStream::flush()
266 {
267  if( !mxStmWrapper.is() )
268  throw NotConnectedException() ;
269 
270  mxStmWrapper->flush();
271 }
272 
273 void SAL_CALL SvXMLGraphicOutputStream::closeOutput()
274 {
275  if( !mxStmWrapper.is() )
276  throw NotConnectedException() ;
277 
278  mxStmWrapper->closeOutput();
279  mxStmWrapper.clear();
280 
281  mbClosed = true;
282 }
283 
284 Graphic SvXMLGraphicOutputStream::GetGraphic()
285 {
286  Graphic aGraphic;
287 
288  if (mbClosed && mxGrfObj->GetType() == GraphicType::NONE && mpOStm)
289  {
290  mpOStm->Seek( 0 );
291  sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
292  sal_uInt16 nDeterminedFormat = GRFILTER_FORMAT_DONTKNOW;
293  GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *mpOStm ,nFormat,&nDeterminedFormat);
294 
295  if (nDeterminedFormat == GRFILTER_FORMAT_DONTKNOW)
296  {
297  //Read the first two byte to check whether it is a gzipped stream, is so it may be in wmz or emz format
298  //unzip them and try again
299 
300  sal_uInt8 sFirstBytes[ 2 ];
301 
302  sal_uInt64 nStreamLen = mpOStm->TellEnd();
303  mpOStm->Seek( 0 );
304 
305  if ( nStreamLen == 0 )
306  {
307  SvLockBytes* pLockBytes = mpOStm->GetLockBytes();
308  if ( pLockBytes )
309  pLockBytes->SetSynchronMode();
310 
311  nStreamLen = mpOStm->TellEnd();
312  mpOStm->Seek( 0 );
313  }
314  if( nStreamLen >= 2 )
315  {
316  //read two byte
317  mpOStm->ReadBytes(sFirstBytes, 2);
318 
319  if( sFirstBytes[0] == 0x1f && sFirstBytes[1] == 0x8b )
320  {
321  std::unique_ptr<SvMemoryStream> pDest(new SvMemoryStream);
322  ZCodec aZCodec( 0x8000, 0x8000 );
323  aZCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/true);
324  mpOStm->Seek( 0 );
325  aZCodec.Decompress( *mpOStm, *pDest );
326 
327  if (aZCodec.EndCompression())
328  {
329  sal_uInt64 nStreamLen_ = pDest->TellEnd();
330  if (nStreamLen_ > 0)
331  {
332  pDest->Seek(0);
333  GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *pDest ,nFormat,&nDeterminedFormat );
334  }
335  }
336  }
337  }
338  }
339  }
340 
341  if (aGraphic.GetType() != GraphicType::NONE)
342  {
343  mpOStm.reset();
344  mpTmp.reset();
345  }
346  return aGraphic;
347 }
348 
349 const GraphicObject& SvXMLGraphicOutputStream::GetGraphicObject()
350 {
351  Graphic aGraphic(GetGraphic());
352  if (aGraphic.GetType() != GraphicType::NONE)
353  {
354  mxGrfObj.reset(new GraphicObject(aGraphic));
355  }
356  return *mxGrfObj;
357 }
358 
359 }
360 
362  : cppu::WeakComponentImplHelper<document::XGraphicObjectResolver,
363  document::XGraphicStorageHandler,
364  document::XBinaryStreamResolver>(maMutex)
365 {
366  Init( nullptr, eCreateMode );
367 }
368 
370  : cppu::WeakComponentImplHelper<document::XGraphicObjectResolver,
371  document::XGraphicStorageHandler,
372  document::XBinaryStreamResolver>(maMutex)
373  , meCreateMode(SvXMLGraphicHelperMode::Read)
374 {
375 }
376 
378 {
379 }
380 
382 {
383 }
384 
385 bool SvXMLGraphicHelper::ImplGetStreamNames( const OUString& rURLStr,
386  OUString& rPictureStorageName,
387  OUString& rPictureStreamName )
388 {
389  if (rURLStr.isEmpty())
390  return false;
391 
392  const OUString aURLStr {rURLStr.copy(rURLStr.lastIndexOf(':')+1)};
393 
394  if( !aURLStr.isEmpty() && aURLStr.indexOf('/')<0 ) // just one token?
395  {
396  rPictureStorageName = XML_GRAPHICSTORAGE_NAME;
397  rPictureStreamName = aURLStr;
398  }
399  else
400  SvXMLEmbeddedObjectHelper::splitObjectURL(aURLStr, rPictureStorageName, rPictureStreamName);
401 
402  SAL_WARN_IF(rPictureStreamName.isEmpty(), "svx", "SvXMLGraphicHelper::ImplInsertGraphicURL: invalid scheme: " << rURLStr);
403 
404  return !rPictureStreamName.isEmpty();
405 }
406 
407 uno::Reference < embed::XStorage > SvXMLGraphicHelper::ImplGetGraphicStorage( const OUString& rStorageName )
408 {
409  uno::Reference < embed::XStorage > xRetStorage;
410  if( mxRootStorage.is() )
411  {
412  try
413  {
414  maCurStorageName = rStorageName;
415  xRetStorage = mxRootStorage->openStorageElement(
418  ? embed::ElementModes::READWRITE
419  : embed::ElementModes::READ );
420  }
421  catch ( uno::Exception& )
422  {
423  }
424  //#i43196# try again to open the storage element - this time readonly
425  if(!xRetStorage.is())
426  {
427  try
428  {
429  maCurStorageName = rStorageName;
430  xRetStorage = mxRootStorage->openStorageElement( maCurStorageName, embed::ElementModes::READ );
431  }
432  catch ( uno::Exception& )
433  {
434  }
435  }
436  }
437 
438  return xRetStorage;
439 }
440 
442  const OUString& rPictureStreamName )
443 {
445  aRet.xStorage = ImplGetGraphicStorage( rPictureStorageName );
446 
447  if( aRet.xStorage.is() )
448  {
449  sal_Int32 nMode = embed::ElementModes::READ;
451  {
452  nMode = embed::ElementModes::READWRITE;
453  }
454 
455  aRet.xStream = aRet.xStorage->openStreamElement( rPictureStreamName, nMode );
456  if( aRet.xStream.is() && ( SvXMLGraphicHelperMode::Write == meCreateMode ) )
457  {
458  uno::Reference < beans::XPropertySet > xProps( aRet.xStream, uno::UNO_QUERY );
459  xProps->setPropertyValue( "UseCommonStoragePasswordEncryption", uno::makeAny( true) );
460  }
461  }
462 
463  return aRet;
464 }
465 
466 OUString SvXMLGraphicHelper::ImplGetGraphicMimeType( const OUString& rFileName )
467 {
468  if( ( rFileName.getLength() >= 4 ) && ( rFileName[ rFileName.getLength() - 4 ] == '.' ) )
469  {
470  const OString aExt(OUStringToOString(rFileName.copy(rFileName.getLength() - 3),
471  RTL_TEXTENCODING_ASCII_US));
473  }
474 
475  return OUString();
476 }
477 
478 Graphic SvXMLGraphicHelper::ImplReadGraphic( const OUString& rPictureStorageName,
479  const OUString& rPictureStreamName )
480 {
481  Graphic aReturnGraphic;
482  SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName ) );
483  if (aStream.xStream.is())
484  {
486  std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(aStream.xStream));
487  Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(*pStream);
488  if (!aGraphic.IsNone())
489  aReturnGraphic = aGraphic;
490  else
491  rGraphicFilter.ImportGraphic(aReturnGraphic, "", *pStream);
492  }
493 
494  return aReturnGraphic;
495 }
496 
497 void SvXMLGraphicHelper::Init( const uno::Reference < embed::XStorage >& rXMLStorage,
498  SvXMLGraphicHelperMode eCreateMode,
499  const OUString& rGraphicMimeType )
500 {
501  mxRootStorage = rXMLStorage;
502  meCreateMode = eCreateMode;
503  maOutputMimeType = rGraphicMimeType;
504 }
505 
506 rtl::Reference<SvXMLGraphicHelper> SvXMLGraphicHelper::Create( const uno::Reference < embed::XStorage >& rXMLStorage,
507  SvXMLGraphicHelperMode eCreateMode )
508 {
510  pThis->Init( rXMLStorage, eCreateMode, OUString() );
511 
512  return pThis;
513 }
514 
516  const OUString& rGraphicMimeType )
517 {
519 
520  pThis->Init( nullptr, eCreateMode, rGraphicMimeType );
521 
522  return pThis;
523 }
524 
525 namespace
526 {
527 
528 void splitUserDataFromURL(OUString const & rWholeURL, OUString & rJustURL, OUString & rUserData)
529 {
530  sal_Int32 nUser = rWholeURL.indexOf('?');
531  if (nUser >= 0)
532  {
533  rJustURL = rWholeURL.copy(0, nUser);
534  nUser++;
535  rUserData = rWholeURL.copy(nUser);
536  }
537  else
538  {
539  rJustURL = rWholeURL;
540  }
541 }
542 
543 } // end anonymous namespace
544 
545 // XGraphicObjectResolver
546 OUString SAL_CALL SvXMLGraphicHelper::resolveGraphicObjectURL( const OUString& /*rURL*/ )
547 {
548  throw uno::RuntimeException("XGraphicObjectResolver has been removed in LibreOffice 6.1");
549 }
550 
551 // XGraphicStorageHandler
552 uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicHelper::loadGraphic(OUString const & rURL)
553 {
554  osl::MutexGuard aGuard(maMutex);
555 
556  uno::Reference<graphic::XGraphic> xGraphic;
557 
558  OUString aURLOnly;
559  OUString aUserData;
560  splitUserDataFromURL(rURL, aURLOnly, aUserData);
561 
562  auto aIterator = maGraphicObjects.find(aURLOnly);
563  if (aIterator != maGraphicObjects.end())
564  {
565  return aIterator->second;
566  }
567 
568  OUString aPictureStorageName, aPictureStreamName;
569 
570  if (ImplGetStreamNames(aURLOnly, aPictureStorageName, aPictureStreamName))
571  {
572  const GraphicObject aGraphicObject(ImplReadGraphic(aPictureStorageName, aPictureStreamName));
573 
574  if (aGraphicObject.GetType() != GraphicType::NONE)
575  {
576  xGraphic = aGraphicObject.GetGraphic().GetXGraphic();
577  maGraphicObjects[aURLOnly] = xGraphic;
578  }
579  }
580 
581  return xGraphic;
582 }
583 
584 uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicHelper::loadGraphicFromOutputStream(uno::Reference<io::XOutputStream> const & rxOutputStream)
585 {
586  osl::MutexGuard aGuard(maMutex);
587 
588  uno::Reference<graphic::XGraphic> xGraphic;
589 
590  if ((SvXMLGraphicHelperMode::Read == meCreateMode) && rxOutputStream.is())
591  {
592 
593  SvXMLGraphicOutputStream* pGraphicOutputStream = static_cast<SvXMLGraphicOutputStream*>(rxOutputStream.get());
594  if (pGraphicOutputStream)
595  {
596  xGraphic = pGraphicOutputStream->GetGraphic().GetXGraphic();
597  }
598  }
599  return xGraphic;
600 }
601 
602 OUString SAL_CALL SvXMLGraphicHelper::saveGraphicByName(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic,
603  OUString & rOutSavedMimeType, OUString const & rRequestName)
604 {
605  return implSaveGraphic(rxGraphic, rOutSavedMimeType, rRequestName);
606 }
607 
608 OUString SAL_CALL SvXMLGraphicHelper::saveGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic)
609 {
610  OUString aOutMimeType;
611  return implSaveGraphic(rxGraphic, aOutMimeType, OUString());
612 }
613 
614 OUString SvXMLGraphicHelper::implSaveGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic,
615  OUString & rOutSavedMimeType, OUString const & rRequestName)
616 {
617  Graphic aGraphic(rxGraphic);
618 
619  auto aIterator = maExportGraphics.find(aGraphic);
620  if (aIterator != maExportGraphics.end())
621  {
622  auto const & aURLAndMimePair = aIterator->second;
623  rOutSavedMimeType = aURLAndMimePair.second;
624  return aURLAndMimePair.first;
625  }
626 
627  GraphicObject aGraphicObject(aGraphic);
628 
629  if (aGraphicObject.GetType() != GraphicType::NONE)
630  {
631  const GfxLink aGfxLink(aGraphic.GetGfxLink());
632  OUString aExtension;
633  bool bUseGfxLink = true;
634 
635  if (aGfxLink.GetDataSize())
636  {
637  switch (aGfxLink.GetType())
638  {
639  case GfxLinkType::EpsBuffer: aExtension = ".eps"; break;
640  case GfxLinkType::NativeGif: aExtension = ".gif"; break;
641  // #i15508# added BMP type for better exports (checked, works)
642  case GfxLinkType::NativeBmp: aExtension = ".bmp"; break;
643  case GfxLinkType::NativeJpg: aExtension = ".jpg"; break;
644  case GfxLinkType::NativePng: aExtension = ".png"; break;
645  case GfxLinkType::NativeTif: aExtension = ".tif"; break;
646  case GfxLinkType::NativeWmf:
647  if (aGfxLink.IsEMF())
648  aExtension = ".emf";
649  else
650  aExtension = ".wmf";
651  break;
652  case GfxLinkType::NativeMet: aExtension = ".met"; break;
653  case GfxLinkType::NativePct: aExtension = ".pct"; break;
654  case GfxLinkType::NativeSvg:
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
662  {
663  bUseGfxLink = false;
664  aExtension = ".svm";
665  }
666  else
667  {
668  aExtension = ".svg";
669  }
670  break;
671  case GfxLinkType::NativePdf: aExtension = ".pdf"; break;
672 
673  default:
674  aExtension = ".grf";
675  break;
676  }
677  }
678  else
679  {
680  if (aGraphicObject.GetType() == GraphicType::Bitmap)
681  {
682  if (aGraphicObject.IsAnimated())
683  aExtension = ".gif";
684  else
685  aExtension = ".png";
686  }
687  else if (aGraphicObject.GetType() == GraphicType::GdiMetafile)
688  {
689  // SJ: first check if this metafile is just an eps file, then we will store the eps instead of svm
690  GDIMetaFile& rMetafile(const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile()));
691 
692  if (ImplCheckForEPS(rMetafile))
693  aExtension = ".eps";
694  else
695  aExtension = ".svm";
696  }
697  }
698 
699  OUString rPictureStreamName;
700  if (!rRequestName.isEmpty())
701  {
702  rPictureStreamName = rRequestName + aExtension;
703  }
704  else
705  {
706  OUString sId = OStringToOUString(aGraphicObject.GetUniqueID(), RTL_TEXTENCODING_ASCII_US);
707  rPictureStreamName = sId + aExtension;
708  }
709 
711 
712  if (aStream.xStream.is())
713  {
714  const OUString aMimeType(ImplGetGraphicMimeType(rPictureStreamName));
715  uno::Reference<beans::XPropertySet> xProps(aStream.xStream, uno::UNO_QUERY);
716 
717  // set stream properties (MediaType/Compression)
718  if (!aMimeType.isEmpty())
719  {
720  xProps->setPropertyValue("MediaType", uno::Any(aMimeType));
721  }
722 
723  // picture formats that actually _do_ benefit from zip
724  // storage compression
725  // .svm pics gets compressed via ZBITMAP old-style stream
726  // option below
727  static const char* aCompressiblePics[] =
728  {
729  "image/svg+xml",
730  "image/x-emf",
731  "image/x-wmf",
732  "image/tiff",
733  "image/x-eps",
734  "image/bmp",
735  "image/x-pict"
736  };
737 
738  bool bSuccess = false;
739 
740  bool bCompressed = aMimeType.isEmpty();
741  if( !bCompressed )
742  {
743  for(const char* p : aCompressiblePics)
744  {
745  if( aMimeType.equalsIgnoreAsciiCaseAscii(p) )
746  {
747  bCompressed = true;
748  break;
749  }
750  }
751  }
752 
753  xProps->setPropertyValue("Compressed", Any(bCompressed));
754 
755  std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(aStream.xStream));
756  if (bUseGfxLink && aGfxLink.GetDataSize() && aGfxLink.GetData())
757  {
758  pStream->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
759  rOutSavedMimeType = aMimeType;
760  bSuccess = (pStream->GetError() == ERRCODE_NONE);
761  }
762  else
763  {
764  if (aGraphic.GetType() == GraphicType::Bitmap)
765  {
767  OUString aFormat;
768 
769  if (aGraphic.IsAnimated())
770  {
771  aFormat = "gif";
772  }
773  else
774  {
775  aFormat = "png";
776  }
777  rOutSavedMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForExtension(aFormat.toUtf8());
778 
779  bSuccess = (rFilter.ExportGraphic(aGraphic, "", *pStream, rFilter.GetExportFormatNumberForShortName(aFormat)) == ERRCODE_NONE);
780  }
781  else if (aGraphic.GetType() == GraphicType::GdiMetafile)
782  {
783  pStream->SetVersion(SOFFICE_FILEFORMAT_8);
784  pStream->SetCompressMode(SvStreamCompressFlags::ZBITMAP);
786 
787  // SJ: first check if this metafile is just an eps file, then we will store the eps instead of svm
788  GDIMetaFile& rMtf(const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile()));
789  const MetaCommentAction* pComment = ImplCheckForEPS(rMtf);
790  if (pComment)
791  {
792  sal_uInt32 nSize = pComment->GetDataSize();
793  const sal_uInt8* pData = pComment->GetData();
794  if (nSize && pData)
795  pStream->WriteBytes(pData, nSize);
796 
797  const MetaEPSAction* pAct = static_cast<const MetaEPSAction*>(rMtf.FirstAction());
798  const GfxLink& rLink = pAct->GetLink();
799 
800  pStream->WriteBytes(rLink.GetData(), rLink.GetDataSize());
801  }
802  else
803  {
804  rMtf.Write(*pStream);
805  }
806 
807  bSuccess = (pStream->GetError() == ERRCODE_NONE);
808  }
809  }
810 
811  if (!bSuccess)
812  return OUString();
813 
814  uno::Reference<embed::XTransactedObject> xStorage(aStream.xStorage, uno::UNO_QUERY);
815  pStream.reset();
816  aStream.xStream->getOutputStream()->closeOutput();
817  if (xStorage.is())
818  xStorage->commit();
819 
820  OUString aStoragePath = "Pictures/" + rPictureStreamName;
821 
822  // put into cache
823  maExportGraphics[aGraphic] = std::make_pair(aStoragePath, rOutSavedMimeType);
824 
825  return aStoragePath;
826  }
827  }
828 
829  return OUString();
830 }
831 
832 uno::Reference<io::XInputStream> SAL_CALL SvXMLGraphicHelper::createInputStream(uno::Reference<graphic::XGraphic> const & rxGraphic)
833 {
834  Reference<XInputStream> xInputStream;
835 
836  Graphic aGraphic(rxGraphic);
837  GraphicObject aGraphicObject(aGraphic);
838 
840  {
842  std::unique_ptr<GraphicInputStream> pInputStream(new GraphicInputStream(aGraphicObject, sMimeType));
843 
844  // We release the pointer from unique_ptr and assign it to the input stream return type.
845  // In case the stream doesn't exists, unique_ptr will delete the pointer when we go out of scope.
846  if (pInputStream->exists())
847  xInputStream = pInputStream.release();
848  }
849 
850  return xInputStream;
851 }
852 
853 // XBinaryStreamResolver
855 {
857  return xRet;
858 }
859 
861 {
863 
865  {
866  std::unique_ptr<SvXMLGraphicOutputStream> pOutputStream(new SvXMLGraphicOutputStream);
867 
868  if( pOutputStream->Exists() )
869  {
870  xRet = pOutputStream.release();
871  maGrfStms.push_back( xRet );
872  }
873  }
874 
875  return xRet;
876 }
877 
878 OUString SAL_CALL SvXMLGraphicHelper::resolveOutputStream( const Reference< XOutputStream >& rxBinaryStream )
879 {
880  OUString aRet;
881 
882  if( ( SvXMLGraphicHelperMode::Read == meCreateMode ) && rxBinaryStream.is() )
883  {
884  if( ::std::find( maGrfStms.begin(), maGrfStms.end(), rxBinaryStream ) != maGrfStms.end() )
885  {
886  SvXMLGraphicOutputStream* pOStm = static_cast< SvXMLGraphicOutputStream* >( rxBinaryStream.get() );
887 
888  if( pOStm )
889  {
890  const GraphicObject& rGrfObj = pOStm->GetGraphicObject();
891  const OUString aId(OStringToOUString(
892  rGrfObj.GetUniqueID(), RTL_TEXTENCODING_ASCII_US));
893 
894  if( !aId.isEmpty() )
895  {
896  aRet = XML_GRAPHICOBJECT_URL_BASE + aId;
897  }
898  }
899  }
900  }
901 
902  return aRet;
903 }
904 
905 // for instantiation via service manager
906 namespace {
907 
908 namespace impl
909 {
910 typedef cppu::WeakComponentImplHelper<lang::XInitialization,
911  document::XGraphicObjectResolver,
912  document::XGraphicStorageHandler,
913  document::XBinaryStreamResolver,
914  lang::XServiceInfo>
915  SvXMLGraphicImportExportHelper_Base;
916 
917 class MutexContainer
918 {
919 public:
920  virtual ~MutexContainer();
921 
922 protected:
923  mutable ::osl::Mutex m_aMutex;
924 };
925 
926 MutexContainer::~MutexContainer()
927 {}
928 
929 } // namespace impl
930 
931 class SvXMLGraphicImportExportHelper :
932  public impl::MutexContainer,
933  public impl::SvXMLGraphicImportExportHelper_Base
934 {
935 public:
936  explicit SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode );
937 
938 protected:
939  // is called from WeakComponentImplHelper when XComponent::dispose() was
940  // called from outside
941  virtual void SAL_CALL disposing() override;
942 
943  // ____ XInitialization ____
944  // one argument is allowed, which is the XStorage
945  virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
946 
947  // ____ XGraphicObjectResolver ____
948  virtual OUString SAL_CALL resolveGraphicObjectURL( const OUString& aURL ) override;
949 
950  // ____ XGraphicStorageHandler ____
951  virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL
952  loadGraphic(const OUString& aURL) override;
953 
954  virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL
955  loadGraphicFromOutputStream(css::uno::Reference<css::io::XOutputStream> const & rxOutputStream) override;
956 
957  virtual OUString SAL_CALL
958  saveGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic) override;
959 
960  virtual OUString SAL_CALL
961  saveGraphicByName(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic, OUString & rOutSavedMimeType, OUString const & rRequestName) override;
962 
963  virtual css::uno::Reference<css::io::XInputStream> SAL_CALL
964  createInputStream(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic) override;
965 
966  // ____ XBinaryStreamResolver ____
967  virtual Reference< io::XInputStream > SAL_CALL getInputStream( const OUString& aURL ) override;
968  virtual Reference< io::XOutputStream > SAL_CALL createOutputStream() override;
969  virtual OUString SAL_CALL resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream ) override;
970 
971  // ____ XServiceInfo ____
972  virtual OUString SAL_CALL getImplementationName() override;
973  virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
974  virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
975 
976 private:
977  SvXMLGraphicHelperMode m_eGraphicHelperMode;
978  Reference< XGraphicObjectResolver > m_xGraphicObjectResolver;
979  Reference< XGraphicStorageHandler > m_xGraphicStorageHandler;
980  Reference< XBinaryStreamResolver > m_xBinaryStreamResolver;
981 };
982 
983 SvXMLGraphicImportExportHelper::SvXMLGraphicImportExportHelper( SvXMLGraphicHelperMode eMode ) :
984  impl::SvXMLGraphicImportExportHelper_Base( m_aMutex ),
985  m_eGraphicHelperMode( eMode )
986 {}
987 
988 void SAL_CALL SvXMLGraphicImportExportHelper::disposing()
989 {
990  Reference< XComponent > xComp( m_xGraphicObjectResolver, UNO_QUERY );
991  OSL_ASSERT( xComp.is());
992  if( xComp.is())
993  xComp->dispose();
994  // m_xBinaryStreamResolver and m_xGraphicStorageHandler are a reference to the same object,
995  // don't call dispose() again
996 }
997 
998 // ____ XInitialization ____
999 void SAL_CALL SvXMLGraphicImportExportHelper::initialize(
1000  const Sequence< Any >& aArguments )
1001 {
1003  if( aArguments.hasElements() )
1004  aArguments[0] >>= xStorage;
1005 
1006  rtl::Reference<SvXMLGraphicHelper> pHelper( SvXMLGraphicHelper::Create( xStorage, m_eGraphicHelperMode ));
1007  m_xGraphicObjectResolver.set( pHelper.get() );
1008  m_xGraphicStorageHandler.set( pHelper.get() );
1009  m_xBinaryStreamResolver.set( pHelper.get() );
1010 }
1011 
1012 // ____ XGraphicObjectResolver ____
1013 OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveGraphicObjectURL( const OUString& aURL )
1014 {
1015  return m_xGraphicObjectResolver->resolveGraphicObjectURL( aURL );
1016 }
1017 
1018 // ____ XGraphicStorageHandler ____
1019 uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicImportExportHelper::loadGraphic(OUString const & rURL)
1020 {
1021  return m_xGraphicStorageHandler->loadGraphic(rURL);
1022 }
1023 
1024 uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicImportExportHelper::loadGraphicFromOutputStream(uno::Reference<io::XOutputStream> const & rxOutputStream)
1025 {
1026  return m_xGraphicStorageHandler->loadGraphicFromOutputStream(rxOutputStream);
1027 }
1028 
1029 OUString SAL_CALL SvXMLGraphicImportExportHelper::saveGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic)
1030 {
1031  return m_xGraphicStorageHandler->saveGraphic(rxGraphic);
1032 }
1033 
1034 OUString SAL_CALL SvXMLGraphicImportExportHelper::saveGraphicByName(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic,
1035  OUString & rOutSavedMimeType, OUString const & rRequestName)
1036 {
1037  return m_xGraphicStorageHandler->saveGraphicByName(rxGraphic, rOutSavedMimeType, rRequestName);
1038 }
1039 
1040 uno::Reference<io::XInputStream> SAL_CALL SvXMLGraphicImportExportHelper::createInputStream(uno::Reference<graphic::XGraphic> const & rxGraphic)
1041 {
1042  return m_xGraphicStorageHandler->createInputStream(rxGraphic);
1043 }
1044 
1045 // ____ XBinaryStreamResolver ____
1046 Reference< io::XInputStream > SAL_CALL SvXMLGraphicImportExportHelper::getInputStream( const OUString& aURL )
1047 {
1048  return m_xBinaryStreamResolver->getInputStream( aURL );
1049 }
1050 Reference< io::XOutputStream > SAL_CALL SvXMLGraphicImportExportHelper::createOutputStream()
1051 {
1052  return m_xBinaryStreamResolver->createOutputStream();
1053 }
1054 OUString SAL_CALL SvXMLGraphicImportExportHelper::resolveOutputStream( const Reference< io::XOutputStream >& aBinaryStream )
1055 {
1056  return m_xBinaryStreamResolver->resolveOutputStream( aBinaryStream );
1057 }
1058 
1059 // ____ XServiceInfo ____
1060 OUString SAL_CALL SvXMLGraphicImportExportHelper::getImplementationName()
1061 {
1062  if( m_eGraphicHelperMode == SvXMLGraphicHelperMode::Read )
1063  return "com.sun.star.comp.Svx.GraphicImportHelper";
1064  return "com.sun.star.comp.Svx.GraphicExportHelper";
1065 }
1066 
1067 sal_Bool SAL_CALL SvXMLGraphicImportExportHelper::supportsService( const OUString& ServiceName )
1068 {
1069  return cppu::supportsService(this, ServiceName);
1070 }
1071 
1072 Sequence< OUString > SAL_CALL SvXMLGraphicImportExportHelper::getSupportedServiceNames()
1073 {
1074  return { "com.sun.star.document.GraphicObjectResolver",
1075  "com.sun.star.document.GraphicStorageHandler",
1076  "com.sun.star.document.BinaryStreamResolver" };
1077 }
1078 
1079 }
1080 
1092 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1094  css::uno::XComponentContext *,
1095  css::uno::Sequence<css::uno::Any> const &)
1096 {
1097  return cppu::acquire(new SvXMLGraphicImportExportHelper(SvXMLGraphicHelperMode::Read));
1098 }
1099 
1112 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1114  css::uno::XComponentContext *,
1115  css::uno::Sequence<css::uno::Any> const &)
1116 {
1117  return cppu::acquire(new SvXMLGraphicImportExportHelper(SvXMLGraphicHelperMode::Write));
1118 }
1119 
1120 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString maOutputMimeType
Definition: xmlgrhlp.hxx:63
SVX_DLLPRIVATE OUString implSaveGraphic(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic, OUString &rOutMimeType, OUString const &rRequestName)
Definition: xmlgrhlp.cxx:614
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_Svx_GraphicImportHelper_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Create this with createInstanceWithArguments.
Definition: xmlgrhlp.cxx:1093
virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL loadGraphicFromOutputStream(css::uno::Reference< css::io::XOutputStream > const &rxOutputStream) override
Definition: xmlgrhlp.cxx:584
ErrCode ImportGraphic(Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat=GRFILTER_FORMAT_DONTKNOW, sal_uInt16 *pDeterminedFormat=nullptr, GraphicFilterImportFlags nImportFlags=GraphicFilterImportFlags::NONE)
osl::Mutex m_aMutex
const char aData[]
void SetSynchronMode(bool bTheSync=true)
std::unique_ptr< ContentProperties > pData
bool IsNone() const
static void splitObjectURL(const OUString &aURLNoPar, OUString &rContainerStorageName, OUString &rObjectStorageName)
Definition: xmleohlp.cxx:149
static SVX_DLLPRIVATE bool ImplGetStreamNames(const OUString &rURLStr, OUString &rPictureStorageName, OUString &rPictureStreamName)
Definition: xmlgrhlp.cxx:385
css::uno::Reference< css::embed::XStorage > xStorage
Definition: xmlgrhlp.hxx:43
GraphicOutputStreamVector maGrfStms
Definition: xmlgrhlp.hxx:57
#define ZCODEC_DEFAULT_COMPRESSION
void Init(const css::uno::Reference< css::embed::XStorage > &xXMLStorage, SvXMLGraphicHelperMode eCreateMode, const OUString &rGraphicMimeType=OUString())
Definition: xmlgrhlp.cxx:497
const ContentProperties & rData
OUString getImplementationName()
OUString aId
virtual OUString SAL_CALL resolveGraphicObjectURL(const OUString &aURL) override
Definition: xmlgrhlp.cxx:546
css::uno::Reference< css::graphic::XGraphic > GetXGraphic() const
static SVX_DLLPRIVATE OUString ImplGetGraphicMimeType(const OUString &rFileName)
Definition: xmlgrhlp.cxx:466
const sal_uInt8 * GetData() const
Graphic ImportUnloadedGraphic(SvStream &rIStream, sal_uInt64 sizeLimit=0, const Size *pSizeHint=nullptr)
long EndCompression()
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
OUString maCurStorageName
Definition: xmlgrhlp.hxx:56
OString GetUniqueID() const
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual OUString SAL_CALL resolveOutputStream(const css::uno::Reference< css::io::XOutputStream > &rxBinaryStream) override
Definition: xmlgrhlp.cxx:878
sal_uInt16 GetExportFormatNumberForShortName(const OUString &rShortName)
const GDIMetaFile & GetGDIMetaFile() const
css::uno::Reference< css::embed::XStorage > mxRootStorage
Definition: xmlgrhlp.hxx:55
bool IsAnimated() const
::osl::Mutex maMutex
virtual OUString SAL_CALL saveGraphicByName(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic, OUString &rOutSavedMimeType, OUString const &rRequestName) override
Definition: xmlgrhlp.cxx:602
css::uno::Sequence< OUString > getSupportedServiceNames()
sal_uInt16 GetExportFormatNumberForMediaType(const OUString &rShortName)
long Decompress(SvStream &rIStm, SvStream &rOStm)
GraphicType GetType() const
SVX_DLLPRIVATE Graphic ImplReadGraphic(const OUString &rPictureStorageName, const OUString &rPictureStreamName)
Definition: xmlgrhlp.cxx:478
const char *const aMimeType[]
static OUString GetMimeTypeForExtension(const OString &rExt)
#define XML_GRAPHICOBJECT_URL_BASE
Definition: xmlgrhlp.cxx:60
std::unordered_map< OUString, css::uno::Reference< css::graphic::XGraphic > > maGraphicObjects
Definition: xmlgrhlp.hxx:59
void BeginCompression(int nCompressLevel=ZCODEC_DEFAULT_COMPRESSION, bool gzLib=false)
unsigned char sal_Bool
virtual css::uno::Reference< css::io::XOutputStream > SAL_CALL createOutputStream() override
Definition: xmlgrhlp.cxx:860
virtual ~SvXMLGraphicHelper() override
Definition: xmlgrhlp.cxx:377
#define GRFILTER_FORMAT_DONTKNOW
Exists
GfxLink GetGfxLink() const
::osl::Mutex maMutex
Definition: xmlgrhlp.hxx:54
ErrCode ExportGraphic(const Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat, const css::uno::Sequence< css::beans::PropertyValue > *pFilterData=nullptr)
ODFSaneDefaultVersion GetODFSaneDefaultVersion() const
GraphicType GetType() const
#define XML_GRAPHICSTORAGE_NAME
Definition: xmlgrhlp.cxx:59
SVX_DLLPRIVATE css::uno::Reference< css::embed::XStorage > ImplGetGraphicStorage(const OUString &rPictureStorageName)
Definition: xmlgrhlp.cxx:407
const GfxLink & GetLink() const
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
SvXMLGraphicHelperMode meCreateMode
Definition: xmlgrhlp.hxx:62
sal_uInt32 GetDataSize() const
virtual OUString SAL_CALL saveGraphic(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic) override
Definition: xmlgrhlp.cxx:608
const Graphic & GetGraphic() const
#define SAL_WARN_IF(condition, area, stream)
#define ERRCODE_NONE
unsigned char sal_uInt8
MetaAction * GetAction(size_t nAction) const
void * p
size_t GetActionSize() const
SvXMLGraphicHelperMode
Definition: xmlgrhlp.hxx:36
virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL loadGraphic(OUString const &aURL) override
Definition: xmlgrhlp.cxx:552
MetaActionType GetType() const
css::uno::Reference< css::io::XStream > xStream
Definition: xmlgrhlp.hxx:44
OUString sId
MetaAction * FirstAction()
static GraphicFilter & GetGraphicFilter()
static rtl::Reference< SvXMLGraphicHelper > Create(const css::uno::Reference< css::embed::XStorage > &rXMLStorage, SvXMLGraphicHelperMode eCreateMode)
bool IsAnimated() const
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL createInputStream(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic) override
Definition: xmlgrhlp.cxx:832
virtual void SAL_CALL disposing() override
Definition: xmlgrhlp.cxx:381
Reference< XGraphic > xGraphic
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_Svx_GraphicExportHelper_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Create this with createInstanceWithArguments.
Definition: xmlgrhlp.cxx:1113
SVX_DLLPRIVATE SvxGraphicHelperStream_Impl ImplGetGraphicStream(const OUString &rPictureStorageName, const OUString &rPictureStreamName)
Definition: xmlgrhlp.cxx:441
std::unordered_map< Graphic, std::pair< OUString, OUString > > maExportGraphics
Definition: xmlgrhlp.hxx:60
SvStream & Write(SvStream &rOStm)
#define SOFFICE_FILEFORMAT_8
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getInputStream(const OUString &rURL) override
Definition: xmlgrhlp.cxx:854