LibreOffice Module vcl (master)  1
graphicfilter.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 <config_folders.h>
21 
22 #include <sal/log.hxx>
25 #include <cppuhelper/implbase.hxx>
26 #include <tools/fract.hxx>
27 #include <unotools/configmgr.hxx>
28 #include <tools/stream.hxx>
29 #include <tools/urlobj.hxx>
30 #include <tools/zcodec.hxx>
31 #include <fltcall.hxx>
32 #include <vcl/salctype.hxx>
34 #include <vcl/pngwrite.hxx>
36 #include <vcl/virdev.hxx>
37 #include <impgraph.hxx>
38 #include <vcl/svapp.hxx>
39 #include <osl/file.hxx>
40 #include <vcl/graphicfilter.hxx>
41 #include <vcl/FilterConfigItem.hxx>
42 #include <vcl/wmf.hxx>
43 #include "igif/gifread.hxx"
44 #include <vcl/pdfread.hxx>
45 #include "jpeg/jpeg.hxx"
46 #include "png/png.hxx"
47 #include "ixbm/xbmread.hxx"
48 #include <filter/XpmReader.hxx>
49 #include <filter/TiffReader.hxx>
50 #include <filter/TiffWriter.hxx>
51 #include <filter/TgaReader.hxx>
52 #include <filter/PictReader.hxx>
53 #include <filter/MetReader.hxx>
54 #include <filter/RasReader.hxx>
55 #include <filter/PcxReader.hxx>
56 #include <filter/EpsReader.hxx>
57 #include <filter/EpsWriter.hxx>
58 #include <filter/PsdReader.hxx>
59 #include <filter/PcdReader.hxx>
60 #include <filter/PbmReader.hxx>
61 #include <filter/DxfReader.hxx>
62 #include <filter/GifWriter.hxx>
63 #include <filter/BmpReader.hxx>
64 #include <filter/BmpWriter.hxx>
65 #include <osl/module.hxx>
66 #include <com/sun/star/uno/Reference.h>
67 #include <com/sun/star/awt/Size.hpp>
68 #include <com/sun/star/uno/XInterface.hpp>
69 #include <com/sun/star/io/XActiveDataSource.hpp>
70 #include <com/sun/star/io/XOutputStream.hpp>
71 #include <com/sun/star/svg/XSVGWriter.hpp>
72 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
73 #include <com/sun/star/xml/sax/Writer.hpp>
75 #include <rtl/bootstrap.hxx>
76 #include <tools/svlibrary.h>
77 #include <comphelper/string.hxx>
78 #include <unotools/ucbhelper.hxx>
79 #include <vector>
80 #include <memory>
81 #include <mutex>
82 #include <string_view>
83 #include <vcl/TypeSerializer.hxx>
84 
85 #include "FilterConfigCache.hxx"
87 
90 
91 static std::vector< GraphicFilter* > gaFilterHdlList;
92 
93 static std::mutex& getListMutex()
94 {
95  static std::mutex s_aListProtection;
96  return s_aListProtection;
97 }
98 
99 namespace {
100 
101 class ImpFilterOutputStream : public ::cppu::WeakImplHelper< css::io::XOutputStream >
102 {
103  SvStream& mrStm;
104 
105  virtual void SAL_CALL writeBytes( const css::uno::Sequence< sal_Int8 >& rData ) override
106  { mrStm.WriteBytes(rData.getConstArray(), rData.getLength()); }
107  virtual void SAL_CALL flush() override
108  { mrStm.Flush(); }
109  virtual void SAL_CALL closeOutput() override {}
110 
111 public:
112 
113  explicit ImpFilterOutputStream( SvStream& rStm ) : mrStm( rStm ) {}
114 };
115 
116 }
117 
118 // Helper functions
119 
120 sal_uInt8* ImplSearchEntry( sal_uInt8* pSource, sal_uInt8 const * pDest, sal_uLong nComp, sal_uLong nSize )
121 {
122  while ( nComp-- >= nSize )
123  {
124  sal_uLong i;
125  for ( i = 0; i < nSize; i++ )
126  {
127  if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
128  break;
129  }
130  if ( i == nSize )
131  return pSource;
132  pSource++;
133  }
134  return nullptr;
135 }
136 
137 static OUString ImpGetExtension( const OUString &rPath )
138 {
139  OUString aExt;
140  INetURLObject aURL( rPath );
141  aExt = aURL.GetFileExtension().toAsciiUpperCase();
142  return aExt;
143 }
144 
145 bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
146 {
147  sal_uInt8 sBuf[3];
148  // store number format
149  SvStreamEndian oldNumberFormat = rStream.GetEndian();
150  sal_uInt32 nOffset; // in MS documents the pict format is used without the first 512 bytes
151  for ( nOffset = 0; ( nOffset <= 512 ) && ( ( nStreamPos + nOffset + 14 ) <= nStreamLen ); nOffset += 512 )
152  {
153  short y1,x1,y2,x2;
154  bool bdBoxOk = true;
155 
156  rStream.Seek( nStreamPos + nOffset);
157  // size of the pict in version 1 pict ( 2bytes) : ignored
158  rStream.SeekRel(2);
159  // bounding box (bytes 2 -> 9)
160  rStream.SetEndian(SvStreamEndian::BIG);
161  rStream.ReadInt16( y1 ).ReadInt16( x1 ).ReadInt16( y2 ).ReadInt16( x2 );
162  rStream.SetEndian(oldNumberFormat); // reset format
163 
164  if (x1 > x2 || y1 > y2 || // bad bdbox
165  (x1 == x2 && y1 == y2) || // 1 pixel picture
166  x2-x1 > 2048 || y2-y1 > 2048 ) // picture abnormally big
167  bdBoxOk = false;
168 
169  // read version op
170  rStream.ReadBytes(sBuf, 3);
171  // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
172  // normal version 2 - page A23 and A24
173  if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x02)
174  return true;
175  // normal version 1 - page A25
176  else if (sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 && bdBoxOk)
177  return true;
178  }
179  return false;
180 }
181 
182 ErrCode GraphicFilter::ImpTestOrFindFormat( const OUString& rPath, SvStream& rStream, sal_uInt16& rFormat )
183 {
184  // determine or check the filter/format by reading into it
185  if( rFormat == GRFILTER_FORMAT_DONTKNOW )
186  {
187  OUString aFormatExt;
188  if (vcl::peekGraphicFormat(rStream, aFormatExt, false))
189  {
190  rFormat = pConfig->GetImportFormatNumberForExtension( aFormatExt );
191  if( rFormat != GRFILTER_FORMAT_DONTKNOW )
192  return ERRCODE_NONE;
193  }
194  // determine filter by file extension
195  if( !rPath.isEmpty() )
196  {
197  OUString aExt( ImpGetExtension( rPath ) );
198  rFormat = pConfig->GetImportFormatNumberForExtension( aExt );
199  if( rFormat != GRFILTER_FORMAT_DONTKNOW )
200  return ERRCODE_NONE;
201  }
203  }
204  else
205  {
206  OUString aTmpStr( pConfig->GetImportFormatExtension( rFormat ) );
207  aTmpStr = aTmpStr.toAsciiUpperCase();
208  if (!vcl::peekGraphicFormat(rStream, aTmpStr, true))
210  if ( pConfig->GetImportFormatExtension( rFormat ).equalsIgnoreAsciiCase( "pcd" ) )
211  {
212  sal_Int32 nBase = 2; // default Base0
213  if ( pConfig->GetImportFilterType( rFormat ).equalsIgnoreAsciiCase( "pcd_Photo_CD_Base4" ) )
214  nBase = 1;
215  else if ( pConfig->GetImportFilterType( rFormat ).equalsIgnoreAsciiCase( "pcd_Photo_CD_Base16" ) )
216  nBase = 0;
217  FilterConfigItem aFilterConfigItem( u"Office.Common/Filter/Graphic/Import/PCD" );
218  aFilterConfigItem.WriteInt32( "Resolution", nBase );
219  }
220  }
221 
222  return ERRCODE_NONE;
223 }
224 
225 static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem )
226 {
227  Graphic aGraphic;
228 
229  sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( "LogicalWidth", 0 );
230  sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( "LogicalHeight", 0 );
231 
232  if ( rGraphic.GetType() != GraphicType::NONE )
233  {
234  sal_Int32 nMode = rConfigItem.ReadInt32( "ExportMode", -1 );
235 
236  if ( nMode == -1 ) // the property is not there, this is possible, if the graphic filter
237  { // is called via UnoGraphicExporter and not from a graphic export Dialog
238  nMode = 0; // then we are defaulting this mode to 0
239  if ( nLogicalWidth || nLogicalHeight )
240  nMode = 2;
241  }
242 
243  Size aOriginalSize;
244  Size aPrefSize( rGraphic.GetPrefSize() );
245  MapMode aPrefMapMode( rGraphic.GetPrefMapMode() );
246  if (aPrefMapMode.GetMapUnit() == MapUnit::MapPixel)
247  aOriginalSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MapMode(MapUnit::Map100thMM));
248  else
249  aOriginalSize = OutputDevice::LogicToLogic(aPrefSize, aPrefMapMode, MapMode(MapUnit::Map100thMM));
250  if ( !nLogicalWidth )
251  nLogicalWidth = aOriginalSize.Width();
252  if ( !nLogicalHeight )
253  nLogicalHeight = aOriginalSize.Height();
254  if( rGraphic.GetType() == GraphicType::Bitmap )
255  {
256 
257  // Resolution is set
258  if( nMode == 1 )
259  {
260  BitmapEx aBitmap( rGraphic.GetBitmapEx() );
261  MapMode aMap( MapUnit::Map100thInch );
262 
263  sal_Int32 nDPI = rConfigItem.ReadInt32( "Resolution", 75 );
264  Fraction aFrac( 1, std::clamp( nDPI, sal_Int32(75), sal_Int32(600) ) );
265 
266  aMap.SetScaleX( aFrac );
267  aMap.SetScaleY( aFrac );
268 
269  Size aOldSize = aBitmap.GetSizePixel();
270  aGraphic = rGraphic;
271  aGraphic.SetPrefMapMode( aMap );
272  aGraphic.SetPrefSize( Size( aOldSize.Width() * 100,
273  aOldSize.Height() * 100 ) );
274  }
275  // Size is set
276  else if( nMode == 2 )
277  {
278  aGraphic = rGraphic;
279  aGraphic.SetPrefMapMode( MapMode( MapUnit::Map100thMM ) );
280  aGraphic.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) );
281  }
282  else
283  aGraphic = rGraphic;
284 
285  sal_Int32 nColors = rConfigItem.ReadInt32( "Color", 0 );
286  if ( nColors ) // graphic conversion necessary ?
287  {
288  BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
289  aBmpEx.Convert( static_cast<BmpConversion>(nColors) ); // the entries in the xml section have the same meaning as
290  aGraphic = aBmpEx; // they have in the BmpConversion enum, so it should be
291  } // allowed to cast them
292  }
293  else
294  {
295  if( ( nMode == 1 ) || ( nMode == 2 ) )
296  {
297  GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
298  Size aNewSize( OutputDevice::LogicToLogic(Size(nLogicalWidth, nLogicalHeight), MapMode(MapUnit::Map100thMM), aMtf.GetPrefMapMode()) );
299 
300  if( aNewSize.Width() && aNewSize.Height() )
301  {
302  const Size aPreferredSize( aMtf.GetPrefSize() );
303  aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ),
304  Fraction( aNewSize.Height(), aPreferredSize.Height() ) );
305  }
306  aGraphic = Graphic( aMtf );
307  }
308  else
309  aGraphic = rGraphic;
310  }
311 
312  }
313  else
314  aGraphic = rGraphic;
315 
316  return aGraphic;
317 }
318 
320  : bUseConfig(bConfig)
321 {
322  ImplInit();
323 }
324 
326 {
327  {
328  std::lock_guard aGuard( getListMutex() );
329  auto it = std::find(gaFilterHdlList.begin(), gaFilterHdlList.end(), this);
330  if( it != gaFilterHdlList.end() )
331  gaFilterHdlList.erase( it );
332 
333  if( gaFilterHdlList.empty() )
334  delete pConfig;
335  }
336 
337  mxErrorEx.reset();
338 }
339 
341 {
342  {
343  std::lock_guard aGuard( getListMutex() );
344 
345  if ( gaFilterHdlList.empty() )
347  else
348  pConfig = gaFilterHdlList.front()->pConfig;
349 
350  gaFilterHdlList.push_back( this );
351  }
352 
353  if( bUseConfig )
354  {
355  OUString url("$BRAND_BASE_DIR/" LIBO_LIB_FOLDER);
356  rtl::Bootstrap::expandMacros(url); //TODO: detect failure
357  osl::FileBase::getSystemPathFromFileURL(url, aFilterPath);
358  }
359 
361 }
362 
364 {
365  mxErrorEx = pStm ? pStm->GetError() : ERRCODE_NONE;
366  return nError;
367 }
368 
370 {
371  return pConfig->GetImportFormatCount();
372 }
373 
374 sal_uInt16 GraphicFilter::GetImportFormatNumber( std::u16string_view rFormatName )
375 {
376  return pConfig->GetImportFormatNumber( rFormatName );
377 }
378 
379 sal_uInt16 GraphicFilter::GetImportFormatNumberForShortName( std::u16string_view rShortName )
380 {
381  return pConfig->GetImportFormatNumberForShortName( rShortName );
382 }
383 
384 sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( std::u16string_view rType )
385 {
386  return pConfig->GetImportFormatNumberForTypeName( rType );
387 }
388 
389 OUString GraphicFilter::GetImportFormatName( sal_uInt16 nFormat )
390 {
391  return pConfig->GetImportFormatName( nFormat );
392 }
393 
394 OUString GraphicFilter::GetImportFormatTypeName( sal_uInt16 nFormat )
395 {
396  return pConfig->GetImportFilterTypeName( nFormat );
397 }
398 
399 #ifdef _WIN32
400 OUString GraphicFilter::GetImportFormatMediaType( sal_uInt16 nFormat )
401 {
402  return pConfig->GetImportFormatMediaType( nFormat );
403 }
404 #endif
405 
406 OUString GraphicFilter::GetImportFormatShortName( sal_uInt16 nFormat )
407 {
408  return pConfig->GetImportFormatShortName( nFormat );
409 }
410 
411 OUString GraphicFilter::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
412 {
413  return pConfig->GetImportWildcard( nFormat, nEntry );
414 }
415 
417 {
418  return pConfig->GetExportFormatCount();
419 }
420 
421 sal_uInt16 GraphicFilter::GetExportFormatNumber( std::u16string_view rFormatName )
422 {
423  return pConfig->GetExportFormatNumber( rFormatName );
424 }
425 
426 sal_uInt16 GraphicFilter::GetExportFormatNumberForMediaType( std::u16string_view rMediaType )
427 {
428  return pConfig->GetExportFormatNumberForMediaType( rMediaType );
429 }
430 
431 sal_uInt16 GraphicFilter::GetExportFormatNumberForShortName( std::u16string_view rShortName )
432 {
433  return pConfig->GetExportFormatNumberForShortName( rShortName );
434 }
435 
436 OUString GraphicFilter::GetExportInternalFilterName( sal_uInt16 nFormat )
437 {
438  return pConfig->GetExportInternalFilterName( nFormat );
439 }
440 
441 sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( std::u16string_view rType )
442 {
443  return pConfig->GetExportFormatNumberForTypeName( rType );
444 }
445 
446 OUString GraphicFilter::GetExportFormatName( sal_uInt16 nFormat )
447 {
448  return pConfig->GetExportFormatName( nFormat );
449 }
450 
451 OUString GraphicFilter::GetExportFormatMediaType( sal_uInt16 nFormat )
452 {
453  return pConfig->GetExportFormatMediaType( nFormat );
454 }
455 
456 OUString GraphicFilter::GetExportFormatShortName( sal_uInt16 nFormat )
457 {
458  return pConfig->GetExportFormatShortName( nFormat );
459 }
460 
461 OUString GraphicFilter::GetExportWildcard( sal_uInt16 nFormat )
462 {
463  return pConfig->GetExportWildcard( nFormat, 0 );
464 }
465 
466 bool GraphicFilter::IsExportPixelFormat( sal_uInt16 nFormat )
467 {
468  return pConfig->IsExportPixelFormat( nFormat );
469 }
470 
472  sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
473 {
475  SAL_WARN_IF( rPath.GetProtocol() == INetProtocol::NotValid, "vcl.filter", "GraphicFilter::CanImportGraphic() : ProtType == INetProtocol::NotValid" );
476 
477  OUString aMainUrl( rPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
478  std::unique_ptr<SvStream> xStream(::utl::UcbStreamHelper::CreateStream( aMainUrl, StreamMode::READ | StreamMode::SHARE_DENYNONE ));
479  if (xStream)
480  {
481  nRetValue = CanImportGraphic( aMainUrl, *xStream, nFormat, pDeterminedFormat );
482  }
483  return nRetValue;
484 }
485 
486 ErrCode GraphicFilter::CanImportGraphic( const OUString& rMainUrl, SvStream& rIStream,
487  sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
488 {
489  sal_uLong nStreamPos = rIStream.Tell();
490  ErrCode nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat );
491 
492  rIStream.Seek(nStreamPos);
493 
494  if( nRes==ERRCODE_NONE && pDeterminedFormat!=nullptr )
495  *pDeterminedFormat = nFormat;
496 
497  return ImplSetError( nRes, &rIStream );
498 }
499 
500 //SJ: TODO, we need to create a GraphicImporter component
502  sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, GraphicFilterImportFlags nImportFlags )
503 {
505  SAL_WARN_IF( rPath.GetProtocol() == INetProtocol::NotValid, "vcl.filter", "GraphicFilter::ImportGraphic() : ProtType == INetProtocol::NotValid" );
506 
507  OUString aMainUrl( rPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
508  std::unique_ptr<SvStream> xStream(::utl::UcbStreamHelper::CreateStream( aMainUrl, StreamMode::READ | StreamMode::SHARE_DENYNONE ));
509  if (xStream)
510  {
511  nRetValue = ImportGraphic( rGraphic, aMainUrl, *xStream, nFormat, pDeterminedFormat, nImportFlags );
512  }
513  return nRetValue;
514 }
515 
517  Graphic& rGraphic,
518  const OUString& rPath,
519  SvStream& rIStream,
520  sal_uInt16 nFormat,
521  sal_uInt16* pDeterminedFormat,
522  GraphicFilterImportFlags nImportFlags,
523  WmfExternal const *pExtHeader)
524 {
525  return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, nullptr, pExtHeader );
526 }
527 
528 namespace {
529 
532 struct GraphicImportContext
533 {
535  std::unique_ptr<SvStream> m_pStream;
537  std::shared_ptr<Graphic> m_pGraphic;
539  std::unique_ptr<BitmapScopedWriteAccess> m_pAccess;
540  std::unique_ptr<AlphaScopedWriteAccess> m_pAlphaAccess;
541  // Need to have an AlphaMask instance to keep its lifetime.
542  AlphaMask mAlphaMask;
546  GfxLinkType m_eLinkType = GfxLinkType::NONE;
548  sal_uInt64 m_nStreamBegin = 0;
551 };
552 
554 class GraphicImportTask : public comphelper::ThreadTask
555 {
556  GraphicImportContext& m_rContext;
557 public:
558  GraphicImportTask(const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, GraphicImportContext& rContext);
559  void doWork() override;
561  static void doImport(GraphicImportContext& rContext);
562 };
563 
564 }
565 
566 GraphicImportTask::GraphicImportTask(const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, GraphicImportContext& rContext)
567  : comphelper::ThreadTask(pTag),
568  m_rContext(rContext)
569 {
570 }
571 
572 void GraphicImportTask::doWork()
573 {
574  GraphicImportTask::doImport(m_rContext);
575 }
576 
577 void GraphicImportTask::doImport(GraphicImportContext& rContext)
578 {
579  if(rContext.m_eLinkType == GfxLinkType::NativeJpg)
580  {
581  if (!ImportJPEG(*rContext.m_pStream, *rContext.m_pGraphic, rContext.m_nImportFlags | GraphicFilterImportFlags::UseExistingBitmap, rContext.m_pAccess.get()))
582  rContext.m_nStatus = ERRCODE_GRFILTER_FILTERERROR;
583  }
584  else if(rContext.m_eLinkType == GfxLinkType::NativePng)
585  {
586  if (!vcl::ImportPNG(*rContext.m_pStream, *rContext.m_pGraphic,
587  rContext.m_nImportFlags | GraphicFilterImportFlags::UseExistingBitmap,
588  rContext.m_pAccess.get(), rContext.m_pAlphaAccess.get()))
589  {
590  rContext.m_nStatus = ERRCODE_GRFILTER_FILTERERROR;
591  }
592  }
593 }
594 
595 void GraphicFilter::ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGraphics, std::vector< std::unique_ptr<SvStream> > vStreams)
596 {
597  static bool bThreads = !getenv("VCL_NO_THREAD_IMPORT");
598  std::vector<GraphicImportContext> aContexts;
599  aContexts.reserve(vStreams.size());
601  std::shared_ptr<comphelper::ThreadTaskTag> pTag = comphelper::ThreadPool::createThreadTaskTag();
602 
603  for (auto& pStream : vStreams)
604  {
605  aContexts.emplace_back();
606  GraphicImportContext& rContext = aContexts.back();
607 
608  if (pStream)
609  {
610  rContext.m_pStream = std::move(pStream);
611  rContext.m_pGraphic = std::make_shared<Graphic>();
612  rContext.m_nStatus = ERRCODE_NONE;
613 
614  // Detect the format.
615  ResetLastError();
616  rContext.m_nStreamBegin = rContext.m_pStream->Tell();
617  sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
618  rContext.m_nStatus = ImpTestOrFindFormat(OUString(), *rContext.m_pStream, nFormat);
619  rContext.m_pStream->Seek(rContext.m_nStreamBegin);
620 
621  // Import the graphic.
622  if (rContext.m_nStatus == ERRCODE_NONE && !rContext.m_pStream->GetError())
623  {
624  OUString aFilterName = pConfig->GetImportFilterName(nFormat);
625 
626  if (aFilterName.equalsIgnoreAsciiCase(IMP_JPEG))
627  {
628  rContext.m_eLinkType = GfxLinkType::NativeJpg;
629  rContext.m_nImportFlags = GraphicFilterImportFlags::SetLogsizeForJpeg;
630 
631  if (ImportJPEG( *rContext.m_pStream, *rContext.m_pGraphic, rContext.m_nImportFlags | GraphicFilterImportFlags::OnlyCreateBitmap, nullptr))
632  {
633  Bitmap& rBitmap = const_cast<Bitmap&>(rContext.m_pGraphic->GetBitmapExRef().GetBitmap());
634  rContext.m_pAccess = std::make_unique<BitmapScopedWriteAccess>(rBitmap);
635  rContext.m_pStream->Seek(rContext.m_nStreamBegin);
636  if (bThreads)
637  rSharedPool.pushTask(std::make_unique<GraphicImportTask>(pTag, rContext));
638  else
639  GraphicImportTask::doImport(rContext);
640  }
641  else
642  rContext.m_nStatus = ERRCODE_GRFILTER_FILTERERROR;
643  }
644  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PNG))
645  {
646  rContext.m_eLinkType = GfxLinkType::NativePng;
647 
648  if (vcl::ImportPNG( *rContext.m_pStream, *rContext.m_pGraphic, rContext.m_nImportFlags | GraphicFilterImportFlags::OnlyCreateBitmap, nullptr, nullptr))
649  {
650  const BitmapEx& rBitmapEx = rContext.m_pGraphic->GetBitmapExRef();
651  Bitmap& rBitmap = const_cast<Bitmap&>(rBitmapEx.GetBitmap());
652  rContext.m_pAccess = std::make_unique<BitmapScopedWriteAccess>(rBitmap);
653  if(rBitmapEx.IsAlpha())
654  {
655  // The separate alpha bitmap causes a number of complications. Not only
656  // we need to have an extra bitmap access for it, but we also need
657  // to keep an AlphaMask instance in the context. This is because
658  // BitmapEx internally keeps Bitmap and not AlphaMask (because the Bitmap
659  // may be also a mask, not alpha). So BitmapEx::GetAlpha() returns
660  // a temporary, and direct access to the Bitmap wouldn't work
661  // with AlphaScopedBitmapAccess. *sigh*
662  rContext.mAlphaMask = rBitmapEx.GetAlpha();
663  rContext.m_pAlphaAccess = std::make_unique<AlphaScopedWriteAccess>(rContext.mAlphaMask);
664  }
665  rContext.m_pStream->Seek(rContext.m_nStreamBegin);
666  if (bThreads)
667  rSharedPool.pushTask(std::make_unique<GraphicImportTask>(pTag, rContext));
668  else
669  GraphicImportTask::doImport(rContext);
670  }
671  else
672  rContext.m_nStatus = ERRCODE_GRFILTER_FILTERERROR;
673  }
674  else
675  rContext.m_nStatus = ERRCODE_GRFILTER_FILTERERROR;
676  }
677  }
678  }
679 
680  rSharedPool.waitUntilDone(pTag);
681 
682  // Process data after import.
683  for (auto& rContext : aContexts)
684  {
685  if(rContext.m_pAlphaAccess) // Need to move the AlphaMask back to the BitmapEx.
686  *rContext.m_pGraphic = BitmapEx( rContext.m_pGraphic->GetBitmapExRef().GetBitmap(), rContext.mAlphaMask );
687  rContext.m_pAccess.reset();
688  rContext.m_pAlphaAccess.reset();
689 
690  if (rContext.m_nStatus == ERRCODE_NONE && (rContext.m_eLinkType != GfxLinkType::NONE) && !rContext.m_pGraphic->GetReaderContext())
691  {
692  std::unique_ptr<sal_uInt8[]> pGraphicContent;
693 
694  const sal_uInt64 nStreamEnd = rContext.m_pStream->Tell();
695  sal_Int32 nGraphicContentSize = nStreamEnd - rContext.m_nStreamBegin;
696 
697  if (nGraphicContentSize > 0)
698  {
699  try
700  {
701  pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
702  }
703  catch (const std::bad_alloc&)
704  {
705  rContext.m_nStatus = ERRCODE_GRFILTER_TOOBIG;
706  }
707 
708  if (rContext.m_nStatus == ERRCODE_NONE)
709  {
710  rContext.m_pStream->Seek(rContext.m_nStreamBegin);
711  rContext.m_pStream->ReadBytes(pGraphicContent.get(), nGraphicContentSize);
712  }
713  }
714 
715  if (rContext.m_nStatus == ERRCODE_NONE)
716  rContext.m_pGraphic->SetGfxLink(std::make_shared<GfxLink>(std::move(pGraphicContent), nGraphicContentSize, rContext.m_eLinkType));
717  }
718 
719  if (rContext.m_nStatus != ERRCODE_NONE)
720  rContext.m_pGraphic = nullptr;
721 
722  rGraphics.push_back(rContext.m_pGraphic);
723  }
724 }
725 
726 void GraphicFilter::MakeGraphicsAvailableThreaded(std::vector<Graphic*>& graphics)
727 {
728  // Graphic::makeAvailable() is not thread-safe. Only the jpeg and png loaders are, so here
729  // we process only jpeg and png images that also have their stream data, load new Graphic's
730  // from them and then update the passed objects using them.
731  std::vector< Graphic* > toLoad;
732  for(auto graphic : graphics)
733  {
734  // Need to use GetSharedGfxLink, to access the pointer without copying.
735  if(!graphic->isAvailable() && graphic->IsGfxLink()
736  && graphic->GetSharedGfxLink()->GetDataSize() != 0
737  && (graphic->GetSharedGfxLink()->GetType() == GfxLinkType::NativeJpg
738  || graphic->GetSharedGfxLink()->GetType() == GfxLinkType::NativePng))
739  {
740  // Graphic objects share internal ImpGraphic, do not process any of those twice.
741  const auto predicate = [graphic](Graphic* item) { return item->ImplGetImpGraphic() == graphic->ImplGetImpGraphic(); };
742  if( std::find_if(toLoad.begin(), toLoad.end(), predicate ) == toLoad.end())
743  toLoad.push_back( graphic );
744  }
745  }
746  if( toLoad.empty())
747  return;
748  std::vector< std::unique_ptr<SvStream>> streams;
749  for( auto graphic : toLoad )
750  {
751  streams.push_back( std::make_unique<SvMemoryStream>( const_cast<sal_uInt8*>(graphic->GetSharedGfxLink()->GetData()),
752  graphic->GetSharedGfxLink()->GetDataSize(), StreamMode::READ | StreamMode::WRITE));
753  }
754  std::vector< std::shared_ptr<Graphic>> loadedGraphics;
755  ImportGraphics(loadedGraphics, std::move(streams));
756  assert(loadedGraphics.size() == toLoad.size());
757  for( size_t i = 0; i < toLoad.size(); ++i )
758  {
759  if(loadedGraphics[ i ] != nullptr)
760  toLoad[ i ]->ImplGetImpGraphic()->updateFromLoadedGraphic(loadedGraphics[ i ]->ImplGetImpGraphic());
761  }
762 }
763 
764 Graphic GraphicFilter::ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 sizeLimit,
765  const Size* pSizeHint)
766 {
767  Graphic aGraphic;
768  sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
769  GfxLinkType eLinkType = GfxLinkType::NONE;
770 
771  ResetLastError();
772 
773  const sal_uLong nStreamBegin = rIStream.Tell();
774 
775  rIStream.Seek(nStreamBegin);
776 
777  ErrCode nStatus = ImpTestOrFindFormat("", rIStream, nFormat);
778 
779  rIStream.Seek(nStreamBegin);
780  sal_uInt32 nStreamLength(rIStream.remainingSize());
781  if (sizeLimit && sizeLimit < nStreamLength)
782  nStreamLength = sizeLimit;
783 
784  OUString aFilterName = pConfig->GetImportFilterName(nFormat);
785 
786  std::unique_ptr<sal_uInt8[]> pGraphicContent;
787  sal_Int32 nGraphicContentSize = 0;
788 
789  // read graphic
790  {
791  if (aFilterName.equalsIgnoreAsciiCase(IMP_GIF))
792  {
793  eLinkType = GfxLinkType::NativeGif;
794  }
795  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PNG))
796  {
797  // check if this PNG contains a GIF chunk!
798  pGraphicContent = vcl::PngImageReader::getMicrosoftGifChunk(rIStream, &nGraphicContentSize);
799  if( pGraphicContent )
800  eLinkType = GfxLinkType::NativeGif;
801  else
802  eLinkType = GfxLinkType::NativePng;
803  }
804  else if (aFilterName.equalsIgnoreAsciiCase(IMP_JPEG))
805  {
806  eLinkType = GfxLinkType::NativeJpg;
807  }
808  else if (aFilterName.equalsIgnoreAsciiCase(IMP_SVG))
809  {
810  bool bOkay(false);
811 
812  if (nStreamLength > 0)
813  {
814  std::vector<sal_uInt8> aTwoBytes(2);
815  rIStream.ReadBytes(aTwoBytes.data(), 2);
816  rIStream.Seek(nStreamBegin);
817 
818  if (aTwoBytes[0] == 0x1F && aTwoBytes[1] == 0x8B)
819  {
820  SvMemoryStream aMemStream;
821  ZCodec aCodec;
822  tools::Long nMemoryLength;
823 
824  aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/true);
825  nMemoryLength = aCodec.Decompress(rIStream, aMemStream);
826  aCodec.EndCompression();
827 
828  if (!rIStream.GetError() && nMemoryLength >= 0)
829  {
830  nGraphicContentSize = nMemoryLength;
831  pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
832 
833  aMemStream.Seek(STREAM_SEEK_TO_BEGIN);
834  aMemStream.ReadBytes(pGraphicContent.get(), nGraphicContentSize);
835 
836  bOkay = true;
837  }
838  }
839  else
840  {
841  nGraphicContentSize = nStreamLength;
842  pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
843  rIStream.ReadBytes(pGraphicContent.get(), nStreamLength);
844 
845  bOkay = true;
846  }
847  }
848 
849  if (bOkay)
850  {
851  eLinkType = GfxLinkType::NativeSvg;
852  }
853  else
854  {
856  }
857  }
858  else if (aFilterName.equalsIgnoreAsciiCase(IMP_BMP))
859  {
860  eLinkType = GfxLinkType::NativeBmp;
861  }
862  else if (aFilterName.equalsIgnoreAsciiCase(IMP_MOV))
863  {
864  eLinkType = GfxLinkType::NativeMov;
865  }
866  else if (aFilterName.equalsIgnoreAsciiCase(IMP_WMF) ||
867  aFilterName.equalsIgnoreAsciiCase(IMP_EMF))
868  {
869  nGraphicContentSize = nStreamLength;
870  pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
871 
872  rIStream.Seek(nStreamBegin);
873  rIStream.ReadBytes(pGraphicContent.get(), nStreamLength);
874 
875  if (!rIStream.GetError())
876  {
877  eLinkType = GfxLinkType::NativeWmf;
878  }
879  else
880  {
882  }
883  }
884  else if (aFilterName == IMP_PDF)
885  {
886  eLinkType = GfxLinkType::NativePdf;
887  }
888  else if (aFilterName == IMP_TIFF)
889  {
890  eLinkType = GfxLinkType::NativeTif;
891  }
892  else if (aFilterName == IMP_PICT)
893  {
894  eLinkType = GfxLinkType::NativePct;
895  }
896  else if (aFilterName == IMP_MET)
897  {
898  eLinkType = GfxLinkType::NativeMet;
899  }
900  else
901  {
903  }
904  }
905 
906  if (nStatus == ERRCODE_NONE && eLinkType != GfxLinkType::NONE)
907  {
908  if (!pGraphicContent)
909  {
910  nGraphicContentSize = nStreamLength;
911 
912  if (nGraphicContentSize > 0)
913  {
914  try
915  {
916  pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
917  }
918  catch (const std::bad_alloc&)
919  {
920  nStatus = ERRCODE_GRFILTER_TOOBIG;
921  }
922 
923  if (nStatus == ERRCODE_NONE)
924  {
925  rIStream.Seek(nStreamBegin);
926  rIStream.ReadBytes(pGraphicContent.get(), nGraphicContentSize);
927  }
928  }
929  }
930 
931  if( nStatus == ERRCODE_NONE )
932  {
933  bool bAnimated = false;
934  Size aLogicSize;
935  if (eLinkType == GfxLinkType::NativeGif)
936  {
937  SvMemoryStream aMemoryStream(pGraphicContent.get(), nGraphicContentSize, StreamMode::READ);
938  bAnimated = IsGIFAnimated(aMemoryStream, aLogicSize);
939  if (!pSizeHint && aLogicSize.getWidth() && aLogicSize.getHeight())
940  {
941  pSizeHint = &aLogicSize;
942  }
943  }
944  aGraphic.SetGfxLink(std::make_shared<GfxLink>(std::move(pGraphicContent), nGraphicContentSize, eLinkType));
945  aGraphic.ImplGetImpGraphic()->setPrepared(bAnimated, pSizeHint);
946  }
947  }
948 
949  // Set error code or try to set native buffer
950  if (nStatus != ERRCODE_NONE)
951  ImplSetError(nStatus, &rIStream);
952  if (nStatus != ERRCODE_NONE || eLinkType == GfxLinkType::NONE)
953  rIStream.Seek(nStreamBegin);
954 
955  return aGraphic;
956 }
957 
958 ErrCode GraphicFilter::readGIF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType)
959 {
960  if (ImportGIF(rStream, rGraphic))
961  {
962  rLinkType = GfxLinkType::NativeGif;
963  return ERRCODE_NONE;
964  }
965  else
967 }
968 
969 ErrCode GraphicFilter::readPNG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, std::unique_ptr<sal_uInt8[]> & rpGraphicContent,
970  sal_Int32& rGraphicContentSize)
971 {
972  ErrCode aReturnCode = ERRCODE_NONE;
973 
974  // check if this PNG contains a GIF chunk!
975  rpGraphicContent = vcl::PngImageReader::getMicrosoftGifChunk(rStream, &rGraphicContentSize);
976  if( rpGraphicContent )
977  {
978  SvMemoryStream aIStrm(rpGraphicContent.get(), rGraphicContentSize, StreamMode::READ);
979  ImportGIF(aIStrm, rGraphic);
980  rLinkType = GfxLinkType::NativeGif;
981  return aReturnCode;
982  }
983 
984  // PNG has no GIF chunk
985  vcl::PngImageReader aPNGReader(rStream);
986  BitmapEx aBitmapEx(aPNGReader.read());
987  if (!aBitmapEx.IsEmpty())
988  {
989  rGraphic = aBitmapEx;
990  rLinkType = GfxLinkType::NativePng;
991  }
992  else
993  aReturnCode = ERRCODE_GRFILTER_FILTERERROR;
994 
995  return aReturnCode;
996 }
997 
998 ErrCode GraphicFilter::readJPEG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, GraphicFilterImportFlags nImportFlags)
999 {
1000  ErrCode aReturnCode = ERRCODE_NONE;
1001 
1002  // set LOGSIZE flag always, if not explicitly disabled
1003  // (see #90508 and #106763)
1005  {
1007  }
1008 
1009  sal_uInt64 nPosition = rStream.Tell();
1010  if (!ImportJPEG(rStream, rGraphic, nImportFlags | GraphicFilterImportFlags::OnlyCreateBitmap, nullptr))
1011  aReturnCode = ERRCODE_GRFILTER_FILTERERROR;
1012  else
1013  {
1014  Bitmap& rBitmap = const_cast<Bitmap&>(rGraphic.GetBitmapExRef().GetBitmap());
1015  BitmapScopedWriteAccess pWriteAccess(rBitmap);
1016  rStream.Seek(nPosition);
1017  if (!ImportJPEG(rStream, rGraphic, nImportFlags | GraphicFilterImportFlags::UseExistingBitmap, &pWriteAccess))
1018  aReturnCode = ERRCODE_GRFILTER_FILTERERROR;
1019  else
1020  rLinkType = GfxLinkType::NativeJpg;
1021  }
1022 
1023  return aReturnCode;
1024 }
1025 
1026 ErrCode GraphicFilter::readSVG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, std::unique_ptr<sal_uInt8[]> & rpGraphicContent,
1027  sal_Int32& rGraphicContentSize)
1028 {
1029  ErrCode aReturnCode = ERRCODE_NONE;
1030 
1031  const sal_uInt32 nStreamPosition(rStream.Tell());
1032  const sal_uInt32 nStreamLength(rStream.remainingSize());
1033 
1034  bool bOkay(false);
1035 
1036  if (nStreamLength > 0)
1037  {
1038  std::vector<sal_uInt8> aTwoBytes(2);
1039  rStream.ReadBytes(aTwoBytes.data(), 2);
1040  rStream.Seek(nStreamPosition);
1041 
1042  if (aTwoBytes[0] == 0x1F && aTwoBytes[1] == 0x8B)
1043  {
1044  SvMemoryStream aMemStream;
1045  ZCodec aCodec;
1046  tools::Long nMemoryLength;
1047 
1048  aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/true);
1049  nMemoryLength = aCodec.Decompress(rStream, aMemStream);
1050  aCodec.EndCompression();
1051 
1052  if (!rStream.GetError() && nMemoryLength >= 0)
1053  {
1054  VectorGraphicDataArray aNewData(nMemoryLength);
1055  aMemStream.Seek(STREAM_SEEK_TO_BEGIN);
1056  aMemStream.ReadBytes(aNewData.begin(), nMemoryLength);
1057 
1058  // Make a uncompressed copy for GfxLink
1059  rGraphicContentSize = nMemoryLength;
1060  rpGraphicContent.reset(new sal_uInt8[rGraphicContentSize]);
1061  std::copy(aNewData.begin(), aNewData.end(), rpGraphicContent.get());
1062 
1063  if (!aMemStream.GetError())
1064  {
1065  BinaryDataContainer aDataContainer(reinterpret_cast<const sal_uInt8*>(aNewData.getConstArray()), aNewData.getLength());
1066  auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aDataContainer, VectorGraphicDataType::Svg);
1067  rGraphic = Graphic(aVectorGraphicDataPtr);
1068  bOkay = true;
1069  }
1070  }
1071  }
1072  else
1073  {
1074  VectorGraphicDataArray aNewData(nStreamLength);
1075  rStream.ReadBytes(aNewData.begin(), nStreamLength);
1076 
1077  if (!rStream.GetError())
1078  {
1079  BinaryDataContainer aDataContainer(reinterpret_cast<const sal_uInt8*>(aNewData.getConstArray()), aNewData.getLength());
1080  auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aDataContainer, VectorGraphicDataType::Svg);
1081  rGraphic = Graphic(aVectorGraphicDataPtr);
1082  bOkay = true;
1083  }
1084  }
1085  }
1086 
1087  if (bOkay)
1088  {
1089  rLinkType = GfxLinkType::NativeSvg;
1090  }
1091  else
1092  {
1093  aReturnCode = ERRCODE_GRFILTER_FILTERERROR;
1094  }
1095 
1096  return aReturnCode;
1097 }
1098 
1100 {
1101  if (ImportXBM(rStream, rGraphic))
1102  return ERRCODE_NONE;
1103  else
1105 }
1106 
1108 {
1109  if (ImportXPM(rStream, rGraphic))
1110  return ERRCODE_NONE;
1111  else
1113 }
1114 
1116  WmfExternal const *pExtHeader, VectorGraphicDataType eType)
1117 {
1118  // use new UNO API service, do not directly import but create a
1119  // Graphic that contains the original data and decomposes to
1120  // primitives on demand
1121 
1122  ErrCode aReturnCode = ERRCODE_GRFILTER_FILTERERROR;
1123 
1124  const sal_uInt32 nStreamLength(rStream.remainingSize());
1125  VectorGraphicDataArray aNewData(nStreamLength);
1126 
1127  rStream.ReadBytes(aNewData.begin(), nStreamLength);
1128 
1129  if (!rStream.GetError())
1130  {
1131  const VectorGraphicDataType aDataType(eType);
1132  BinaryDataContainer aDataContainer(reinterpret_cast<const sal_uInt8*>(aNewData.getConstArray()), aNewData.getLength());
1133 
1134  auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aDataContainer, aDataType);
1135 
1136  if (pExtHeader)
1137  {
1138  aVectorGraphicDataPtr->setWmfExternalHeader(*pExtHeader);
1139  }
1140 
1141  rGraphic = Graphic(aVectorGraphicDataPtr);
1142  rLinkType = GfxLinkType::NativeWmf;
1143  aReturnCode = ERRCODE_NONE;
1144  }
1145 
1146  return aReturnCode;
1147 }
1148 
1149 ErrCode GraphicFilter::readWMF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, WmfExternal const* pExtHeader)
1150 {
1151  return readWMF_EMF(rStream, rGraphic, rLinkType, pExtHeader, VectorGraphicDataType::Wmf);
1152 }
1153 
1154 ErrCode GraphicFilter::readEMF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, WmfExternal const* pExtHeader)
1155 {
1156  return readWMF_EMF(rStream, rGraphic, rLinkType, pExtHeader, VectorGraphicDataType::Emf);
1157 }
1158 
1159 ErrCode GraphicFilter::readPDF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType)
1160 {
1161  if (vcl::ImportPDF(rStream, rGraphic))
1162  {
1163  rLinkType = GfxLinkType::NativePdf;
1164  return ERRCODE_NONE;
1165  }
1166  else
1168 }
1169 
1170 ErrCode GraphicFilter::readTIFF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType)
1171 {
1172  if (ImportTiffGraphicImport(rStream, rGraphic))
1173  {
1174  rLinkType = GfxLinkType::NativeTif;
1175  return ERRCODE_NONE;
1176  }
1177  else
1179 }
1180 
1181 ErrCode GraphicFilter::readWithTypeSerializer(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, OUString aFilterName)
1182 {
1183  ErrCode aReturnCode = ERRCODE_GRFILTER_FILTERERROR;
1184 
1185  // SV internal filters for import bitmaps and MetaFiles
1186  TypeSerializer aSerializer(rStream);
1187  aSerializer.readGraphic(rGraphic);
1188 
1189  if (!rStream.GetError())
1190  {
1191  if (aFilterName.equalsIgnoreAsciiCase(IMP_MOV))
1192  {
1193  rGraphic.SetDefaultType();
1194  rStream.Seek(STREAM_SEEK_TO_END);
1195  rLinkType = GfxLinkType::NativeMov;
1196  }
1197  aReturnCode = ERRCODE_NONE;
1198  }
1199  return aReturnCode;
1200 }
1201 
1202 ErrCode GraphicFilter::readBMP(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType)
1203 {
1204  if (BmpReader(rStream, rGraphic))
1205  {
1206  rLinkType = GfxLinkType::NativeBmp;
1207  return ERRCODE_NONE;
1208  }
1209  else
1211 }
1212 
1214 {
1215  if (ImportTgaGraphic(rStream, rGraphic))
1216  return ERRCODE_NONE;
1217  else
1219 }
1220 
1221 ErrCode GraphicFilter::readPICT(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType)
1222 {
1223  if (ImportPictGraphic(rStream, rGraphic))
1224  {
1225  rLinkType = GfxLinkType::NativePct;
1226  return ERRCODE_NONE;
1227  }
1228  else
1230 }
1231 
1232 ErrCode GraphicFilter::readMET(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType)
1233 {
1234  if (ImportMetGraphic(rStream, rGraphic))
1235  {
1236  rLinkType = GfxLinkType::NativeMet;
1237  return ERRCODE_NONE;
1238  }
1239  else
1241 }
1242 
1244 {
1245  if (ImportRasGraphic(rStream, rGraphic))
1246  return ERRCODE_NONE;
1247  else
1249 }
1250 
1252 {
1253  if (ImportPcxGraphic(rStream, rGraphic))
1254  return ERRCODE_NONE;
1255  else
1257 }
1258 
1260 {
1261  if (ImportEpsGraphic(rStream, rGraphic))
1262  return ERRCODE_NONE;
1263  else
1265 }
1266 
1268 {
1269  if (ImportPsdGraphic(rStream, rGraphic))
1270  return ERRCODE_NONE;
1271  else
1273 }
1274 
1276 {
1277  std::unique_ptr<FilterConfigItem> pFilterConfigItem;
1279  {
1280  OUString aFilterConfigPath( "Office.Common/Filter/Graphic/Import/PCD" );
1281  pFilterConfigItem = std::make_unique<FilterConfigItem>(aFilterConfigPath);
1282  }
1283 
1284  if (ImportPcdGraphic(rStream, rGraphic, pFilterConfigItem.get()))
1285  return ERRCODE_NONE;
1286  else
1288 }
1289 
1291 {
1292  if (ImportPbmGraphic(rStream, rGraphic))
1293  return ERRCODE_NONE;
1294  else
1296 }
1297 
1299 {
1300  if (ImportDxfGraphic(rStream, rGraphic))
1301  return ERRCODE_NONE;
1302  else
1304 }
1305 
1306 ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
1307  sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
1308  const css::uno::Sequence< css::beans::PropertyValue >* /*pFilterData*/,
1309  WmfExternal const *pExtHeader )
1310 {
1311  OUString aFilterName;
1312  sal_uLong nStreamBegin;
1313  ErrCode nStatus;
1314  GfxLinkType eLinkType = GfxLinkType::NONE;
1315  const bool bLinkSet = rGraphic.IsGfxLink();
1316 
1317  std::unique_ptr<sal_uInt8[]> pGraphicContent;
1318  sal_Int32 nGraphicContentSize = 0;
1319 
1320  ResetLastError();
1321 
1322  std::shared_ptr<GraphicReader> pContext = rGraphic.GetReaderContext();
1323  bool bDummyContext = rGraphic.IsDummyContext();
1324  if( !pContext || bDummyContext )
1325  {
1326  if( bDummyContext )
1327  {
1328  rGraphic.SetDummyContext( false );
1329  nStreamBegin = 0;
1330  }
1331  else
1332  nStreamBegin = rIStream.Tell();
1333 
1334  nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat );
1335  // if pending, return ERRCODE_NONE in order to request more bytes
1336  if( rIStream.GetError() == ERRCODE_IO_PENDING )
1337  {
1338  rGraphic.SetDummyContext(true);
1339  rIStream.ResetError();
1340  rIStream.Seek( nStreamBegin );
1341  return ImplSetError( ERRCODE_NONE );
1342  }
1343 
1344  rIStream.Seek( nStreamBegin );
1345 
1346  if( ( nStatus != ERRCODE_NONE ) || rIStream.GetError() )
1347  return ImplSetError( ( nStatus != ERRCODE_NONE ) ? nStatus : ERRCODE_GRFILTER_OPENERROR, &rIStream );
1348 
1349  if( pDeterminedFormat )
1350  *pDeterminedFormat = nFormat;
1351 
1352  aFilterName = pConfig->GetImportFilterName( nFormat );
1353  }
1354  else
1355  {
1356  aFilterName = pContext->GetUpperFilterName();
1357 
1358  nStreamBegin = 0;
1359  nStatus = ERRCODE_NONE;
1360  }
1361 
1362  // read graphic
1363  {
1364  if (aFilterName.equalsIgnoreAsciiCase(IMP_GIF))
1365  {
1366  nStatus = readGIF(rIStream, rGraphic, eLinkType);
1367  }
1368  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PNG))
1369  {
1370  nStatus = readPNG(rIStream, rGraphic, eLinkType, pGraphicContent, nGraphicContentSize);
1371  }
1372  else if (aFilterName.equalsIgnoreAsciiCase(IMP_JPEG))
1373  {
1374  nStatus = readJPEG(rIStream, rGraphic, eLinkType, nImportFlags);
1375  }
1376  else if (aFilterName.equalsIgnoreAsciiCase(IMP_SVG))
1377  {
1378  nStatus = readSVG(rIStream, rGraphic, eLinkType, pGraphicContent, nGraphicContentSize);
1379  }
1380  else if( aFilterName.equalsIgnoreAsciiCase( IMP_XBM ) )
1381  {
1382  nStatus = readXBM(rIStream, rGraphic);
1383  }
1384  else if( aFilterName.equalsIgnoreAsciiCase( IMP_XPM ) )
1385  {
1386  nStatus = readXPM(rIStream, rGraphic);
1387  }
1388  else if (aFilterName.equalsIgnoreAsciiCase(IMP_BMP))
1389  {
1390  nStatus = readBMP(rIStream, rGraphic, eLinkType);
1391  }
1392  else if (aFilterName.equalsIgnoreAsciiCase(IMP_SVMETAFILE))
1393  {
1394  nStatus = readWithTypeSerializer(rIStream, rGraphic, eLinkType, aFilterName);
1395  }
1396  else if( aFilterName.equalsIgnoreAsciiCase(IMP_MOV))
1397  {
1398  nStatus = readWithTypeSerializer(rIStream, rGraphic, eLinkType, aFilterName);
1399  }
1400  else if (aFilterName.equalsIgnoreAsciiCase(IMP_WMF))
1401  {
1402  nStatus = readWMF(rIStream, rGraphic, eLinkType, pExtHeader);
1403  }
1404  else if (aFilterName.equalsIgnoreAsciiCase(IMP_EMF))
1405  {
1406  nStatus = readEMF(rIStream, rGraphic, eLinkType, pExtHeader);
1407  }
1408  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PDF))
1409  {
1410  nStatus = readPDF(rIStream, rGraphic, eLinkType);
1411  }
1412  else if (aFilterName.equalsIgnoreAsciiCase(IMP_TIFF) )
1413  {
1414  nStatus = readTIFF(rIStream, rGraphic, eLinkType);
1415  }
1416  else if (aFilterName.equalsIgnoreAsciiCase(IMP_TGA) )
1417  {
1418  nStatus = readTGA(rIStream, rGraphic);
1419  }
1420  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PICT))
1421  {
1422  nStatus = readPICT(rIStream, rGraphic, eLinkType);
1423  }
1424  else if (aFilterName.equalsIgnoreAsciiCase(IMP_MET))
1425  {
1426  nStatus = readMET(rIStream, rGraphic, eLinkType);
1427  }
1428  else if (aFilterName.equalsIgnoreAsciiCase(IMP_RAS))
1429  {
1430  nStatus = readRAS(rIStream, rGraphic);
1431  }
1432  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PCX))
1433  {
1434  nStatus = readPCX(rIStream, rGraphic);
1435  }
1436  else if (aFilterName.equalsIgnoreAsciiCase(IMP_EPS))
1437  {
1438  nStatus = readEPS(rIStream, rGraphic);
1439  }
1440  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PSD))
1441  {
1442  nStatus = readPSD(rIStream, rGraphic);
1443  }
1444  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PCD))
1445  {
1446  nStatus = readPCD(rIStream, rGraphic);
1447  }
1448  else if (aFilterName.equalsIgnoreAsciiCase(IMP_PBM))
1449  {
1450  nStatus = readPBM(rIStream, rGraphic);
1451  }
1452  else if (aFilterName.equalsIgnoreAsciiCase(IMP_DXF))
1453  {
1454  nStatus = readDXF(rIStream, rGraphic);
1455  }
1456  else
1457  nStatus = ERRCODE_GRFILTER_FILTERERROR;
1458  }
1459 
1460  if( nStatus == ERRCODE_NONE && ( eLinkType != GfxLinkType::NONE ) && !rGraphic.GetReaderContext() && !bLinkSet )
1461  {
1462  if (!pGraphicContent)
1463  {
1464  const sal_uLong nStreamEnd = rIStream.Tell();
1465  nGraphicContentSize = nStreamEnd - nStreamBegin;
1466 
1467  if (nGraphicContentSize > 0)
1468  {
1469  try
1470  {
1471  pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
1472  }
1473  catch (const std::bad_alloc&)
1474  {
1475  nStatus = ERRCODE_GRFILTER_TOOBIG;
1476  }
1477 
1478  if( nStatus == ERRCODE_NONE )
1479  {
1480  rIStream.Seek(nStreamBegin);
1481  rIStream.ReadBytes(pGraphicContent.get(), nGraphicContentSize);
1482  }
1483  }
1484  }
1485  if( nStatus == ERRCODE_NONE )
1486  {
1487  rGraphic.SetGfxLink(std::make_shared<GfxLink>(std::move(pGraphicContent), nGraphicContentSize, eLinkType));
1488  }
1489  }
1490 
1491  // Set error code or try to set native buffer
1492  if( nStatus != ERRCODE_NONE )
1493  {
1494  ImplSetError( nStatus, &rIStream );
1495  rIStream.Seek( nStreamBegin );
1496  rGraphic.Clear();
1497  }
1498 
1499  return nStatus;
1500 }
1501 
1503  sal_uInt16 nFormat, const css::uno::Sequence< css::beans::PropertyValue >* pFilterData )
1504 {
1505  SAL_INFO( "vcl.filter", "GraphicFilter::ExportGraphic() (thb)" );
1507  SAL_WARN_IF( rPath.GetProtocol() == INetProtocol::NotValid, "vcl.filter", "GraphicFilter::ExportGraphic() : ProtType == INetProtocol::NotValid" );
1508 
1509  OUString aMainUrl(rPath.GetMainURL(INetURLObject::DecodeMechanism::NONE));
1510  bool bAlreadyExists = utl::UCBContentHelper::IsDocument(aMainUrl);
1511 
1512  std::unique_ptr<SvStream> xStream(::utl::UcbStreamHelper::CreateStream( aMainUrl, StreamMode::WRITE | StreamMode::TRUNC ));
1513  if (xStream)
1514  {
1515  nRetValue = ExportGraphic( rGraphic, aMainUrl, *xStream, nFormat, pFilterData );
1516  xStream.reset();
1517 
1518  if( ( ERRCODE_NONE != nRetValue ) && !bAlreadyExists )
1519  utl::UCBContentHelper::Kill(aMainUrl);
1520  }
1521  return nRetValue;
1522 }
1523 
1524 ErrCode GraphicFilter::ExportGraphic( const Graphic& rGraphic, const OUString& rPath,
1525  SvStream& rOStm, sal_uInt16 nFormat, const css::uno::Sequence< css::beans::PropertyValue >* pFilterData )
1526 {
1527  SAL_INFO( "vcl.filter", "GraphicFilter::ExportGraphic() (thb)" );
1528  sal_uInt16 nFormatCount = GetExportFormatCount();
1529 
1530  ResetLastError();
1531 
1532  if( nFormat == GRFILTER_FORMAT_DONTKNOW )
1533  {
1534  INetURLObject aURL( rPath );
1535  OUString aExt( aURL.GetFileExtension().toAsciiUpperCase() );
1536 
1537  for( sal_uInt16 i = 0; i < nFormatCount; i++ )
1538  {
1539  if ( pConfig->GetExportFormatExtension( i ).equalsIgnoreAsciiCase( aExt ) )
1540  {
1541  nFormat=i;
1542  break;
1543  }
1544  }
1545  }
1546  if( nFormat >= nFormatCount )
1548 
1549  FilterConfigItem aConfigItem( pFilterData );
1550  OUString aFilterName( pConfig->GetExportFilterName( nFormat ) );
1551  ErrCode nStatus = ERRCODE_NONE;
1553  Graphic aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem );
1554  eType = aGraphic.GetType();
1555 
1556  if( pConfig->IsExportPixelFormat( nFormat ) )
1557  {
1558  if( eType != GraphicType::Bitmap )
1559  {
1560  Size aSizePixel;
1561  sal_uLong nBitsPerPixel,nNeededMem,nMaxMem;
1563 
1564  nMaxMem = 1024;
1565  nMaxMem *= 1024; // In Bytes
1566 
1567  // Calculate how big the image would normally be:
1568  aSizePixel=aVirDev->LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode());
1569 
1570  // Calculate how much memory the image will take up
1571  nBitsPerPixel=aVirDev->GetBitCount();
1572  nNeededMem=(static_cast<sal_uLong>(aSizePixel.Width())*static_cast<sal_uLong>(aSizePixel.Height())*nBitsPerPixel+7)/8;
1573 
1574  // is the image larger than available memory?
1575  if (nMaxMem<nNeededMem)
1576  {
1577  double fFak=sqrt(static_cast<double>(nMaxMem)/static_cast<double>(nNeededMem));
1578  aSizePixel.setWidth(static_cast<sal_uLong>(static_cast<double>(aSizePixel.Width())*fFak) );
1579  aSizePixel.setHeight(static_cast<sal_uLong>(static_cast<double>(aSizePixel.Height())*fFak) );
1580  }
1581 
1582  aVirDev->SetMapMode(MapMode(MapUnit::MapPixel));
1583  aVirDev->SetOutputSizePixel(aSizePixel);
1584  Graphic aGraphic2=aGraphic;
1585  aGraphic2.Draw(*aVirDev, Point(0, 0), aSizePixel); // this changes the MapMode
1586  aVirDev->SetMapMode(MapMode(MapUnit::MapPixel));
1587  aGraphic=Graphic(aVirDev->GetBitmapEx(Point(0,0),aSizePixel));
1588  }
1589  }
1590  if( rOStm.GetError() )
1591  nStatus = ERRCODE_GRFILTER_IOERROR;
1592  if( ERRCODE_NONE == nStatus )
1593  {
1594  if( aFilterName.equalsIgnoreAsciiCase( EXP_BMP ) )
1595  {
1596  if (!BmpWriter(rOStm, aGraphic, &aConfigItem))
1597  nStatus = ERRCODE_GRFILTER_FORMATERROR;
1598  if (rOStm.GetError())
1599  nStatus = ERRCODE_GRFILTER_IOERROR;
1600  }
1601  else if (aFilterName.equalsIgnoreAsciiCase(EXP_TIFF))
1602  {
1603  if (!ExportTiffGraphicImport(rOStm, aGraphic, &aConfigItem))
1604  nStatus = ERRCODE_GRFILTER_FORMATERROR;
1605 
1606  if( rOStm.GetError() )
1607  nStatus = ERRCODE_GRFILTER_IOERROR;
1608  }
1609  else if (aFilterName.equalsIgnoreAsciiCase(EXP_GIF))
1610  {
1611  if (!ExportGifGraphic(rOStm, aGraphic, &aConfigItem))
1612  nStatus = ERRCODE_GRFILTER_FORMATERROR;
1613 
1614  if( rOStm.GetError() )
1615  nStatus = ERRCODE_GRFILTER_IOERROR;
1616  }
1617  else if( aFilterName.equalsIgnoreAsciiCase( EXP_SVMETAFILE ) )
1618  {
1619  sal_Int32 nVersion = aConfigItem.ReadInt32( "Version", 0 ) ;
1620  if ( nVersion )
1621  rOStm.SetVersion( nVersion );
1622 
1623  // #i119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
1624  GDIMetaFile aMTF(aGraphic.GetGDIMetaFile());
1625 
1626  aMTF.Write( rOStm );
1627 
1628  if( rOStm.GetError() )
1629  nStatus = ERRCODE_GRFILTER_IOERROR;
1630  }
1631  else if ( aFilterName.equalsIgnoreAsciiCase( EXP_WMF ) )
1632  {
1633  bool bDone(false);
1634 
1635  // do we have a native Vector Graphic Data RenderGraphic, whose data can be written directly?
1636  auto const & rVectorGraphicDataPtr(rGraphic.getVectorGraphicData());
1637 
1638  bool bIsEMF = rGraphic.GetGfxLink().IsEMF();
1639 
1640  // VectorGraphicDataType::Wmf means WMF or EMF, allow direct write in the WMF case
1641  // only.
1642  if (rVectorGraphicDataPtr
1643  && rVectorGraphicDataPtr->getType() == VectorGraphicDataType::Wmf
1644  && !rVectorGraphicDataPtr->getBinaryDataContainer().isEmpty()
1645  && !bIsEMF)
1646  {
1647  auto & aDataContainer = rVectorGraphicDataPtr->getBinaryDataContainer();
1648  rOStm.WriteBytes(aDataContainer.getData(), aDataContainer.getSize());
1649 
1650  if (rOStm.GetError())
1651  {
1652  nStatus = ERRCODE_GRFILTER_IOERROR;
1653  }
1654  else
1655  {
1656  bDone = true;
1657  }
1658  }
1659 
1660  if (!bDone)
1661  {
1662  // #i119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
1663  if (!ConvertGraphicToWMF(aGraphic, rOStm, &aConfigItem))
1664  nStatus = ERRCODE_GRFILTER_FORMATERROR;
1665 
1666  if (rOStm.GetError())
1667  nStatus = ERRCODE_GRFILTER_IOERROR;
1668  }
1669  }
1670  else if ( aFilterName.equalsIgnoreAsciiCase( EXP_EMF ) )
1671  {
1672  bool bDone(false);
1673 
1674  // do we have a native Vector Graphic Data RenderGraphic, whose data can be written directly?
1675  auto const & rVectorGraphicDataPtr(rGraphic.getVectorGraphicData());
1676 
1677  if (rVectorGraphicDataPtr
1678  && rVectorGraphicDataPtr->getType() == VectorGraphicDataType::Emf
1679  && !rVectorGraphicDataPtr->getBinaryDataContainer().isEmpty())
1680  {
1681  auto & aDataContainer = rVectorGraphicDataPtr->getBinaryDataContainer();
1682  rOStm.WriteBytes(aDataContainer.getData(), aDataContainer.getSize());
1683 
1684  if (rOStm.GetError())
1685  {
1686  nStatus = ERRCODE_GRFILTER_IOERROR;
1687  }
1688  else
1689  {
1690  bDone = true;
1691  }
1692  }
1693 
1694  if (!bDone)
1695  {
1696  // #i119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
1697  if (!ConvertGDIMetaFileToEMF(aGraphic.GetGDIMetaFile(), rOStm))
1698  nStatus = ERRCODE_GRFILTER_FORMATERROR;
1699 
1700  if (rOStm.GetError())
1701  nStatus = ERRCODE_GRFILTER_IOERROR;
1702  }
1703  }
1704  else if( aFilterName.equalsIgnoreAsciiCase( EXP_JPEG ) )
1705  {
1706  bool bExportedGrayJPEG = false;
1707  if( !ExportJPEG( rOStm, aGraphic, pFilterData, &bExportedGrayJPEG ) )
1708  nStatus = ERRCODE_GRFILTER_FORMATERROR;
1709 
1710  if( rOStm.GetError() )
1711  nStatus = ERRCODE_GRFILTER_IOERROR;
1712  }
1713  else if (aFilterName.equalsIgnoreAsciiCase(EXP_EPS))
1714  {
1715  if (!ExportEpsGraphic(rOStm, aGraphic, &aConfigItem))
1716  nStatus = ERRCODE_GRFILTER_FORMATERROR;
1717 
1718  if (rOStm.GetError())
1719  nStatus = ERRCODE_GRFILTER_IOERROR;
1720  }
1721  else if ( aFilterName.equalsIgnoreAsciiCase( EXP_PNG ) )
1722  {
1723  vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData );
1724  if ( pFilterData )
1725  {
1726  for ( const auto& rPropVal : *pFilterData )
1727  {
1728  if ( rPropVal.Name == "AdditionalChunks" )
1729  {
1730  css::uno::Sequence< css::beans::PropertyValue > aAdditionalChunkSequence;
1731  if ( rPropVal.Value >>= aAdditionalChunkSequence )
1732  {
1733  for ( const auto& rAdditionalChunk : std::as_const(aAdditionalChunkSequence) )
1734  {
1735  if ( rAdditionalChunk.Name.getLength() == 4 )
1736  {
1737  sal_uInt32 nChunkType = 0;
1738  for ( sal_Int32 k = 0; k < 4; k++ )
1739  {
1740  nChunkType <<= 8;
1741  nChunkType |= static_cast<sal_uInt8>(rAdditionalChunk.Name[ k ]);
1742  }
1743  css::uno::Sequence< sal_Int8 > aByteSeq;
1744  if ( rAdditionalChunk.Value >>= aByteSeq )
1745  {
1746  std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks();
1747  if ( !rChunkData.empty() )
1748  {
1749  sal_uInt32 nChunkLen = aByteSeq.getLength();
1750 
1751  vcl::PNGWriter::ChunkData aChunkData;
1752  aChunkData.nType = nChunkType;
1753  if ( nChunkLen )
1754  {
1755  aChunkData.aData.resize( nChunkLen );
1756  memcpy( aChunkData.aData.data(), aByteSeq.getConstArray(), nChunkLen );
1757  }
1758  std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1;
1759  rChunkData.insert( aIter, aChunkData );
1760  }
1761  }
1762  }
1763  }
1764  }
1765  }
1766  }
1767  }
1768  aPNGWriter.Write( rOStm );
1769 
1770  if( rOStm.GetError() )
1771  nStatus = ERRCODE_GRFILTER_IOERROR;
1772  }
1773  else if( aFilterName.equalsIgnoreAsciiCase( EXP_SVG ) )
1774  {
1775  bool bDone(false);
1776 
1777  // do we have a native Vector Graphic Data RenderGraphic, whose data can be written directly?
1778  auto const & rVectorGraphicDataPtr(rGraphic.getVectorGraphicData());
1779 
1780  if (rVectorGraphicDataPtr
1781  && rVectorGraphicDataPtr->getType() == VectorGraphicDataType::Svg
1782  && !rVectorGraphicDataPtr->getBinaryDataContainer().isEmpty())
1783  {
1784  auto & aDataContainer = rVectorGraphicDataPtr->getBinaryDataContainer();
1785  rOStm.WriteBytes(aDataContainer.getData(), aDataContainer.getSize());
1786 
1787  if( rOStm.GetError() )
1788  {
1789  nStatus = ERRCODE_GRFILTER_IOERROR;
1790  }
1791  else
1792  {
1793  bDone = true;
1794  }
1795  }
1796 
1797  if( !bDone )
1798  {
1799  // do the normal GDIMetaFile export instead
1800  try
1801  {
1802  css::uno::Reference< css::uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1803 
1804  css::uno::Reference< css::xml::sax::XDocumentHandler > xSaxWriter(
1805  css::xml::sax::Writer::create( xContext ), css::uno::UNO_QUERY_THROW);
1806  css::uno::Sequence< css::uno::Any > aArguments( 1 );
1807  aArguments[ 0 ] <<= aConfigItem.GetFilterData();
1808  css::uno::Reference< css::svg::XSVGWriter > xSVGWriter(
1809  xContext->getServiceManager()->createInstanceWithArgumentsAndContext( "com.sun.star.svg.SVGWriter", aArguments, xContext),
1810  css::uno::UNO_QUERY );
1811  if( xSaxWriter.is() && xSVGWriter.is() )
1812  {
1813  css::uno::Reference< css::io::XActiveDataSource > xActiveDataSource(
1814  xSaxWriter, css::uno::UNO_QUERY );
1815 
1816  if( xActiveDataSource.is() )
1817  {
1818  const css::uno::Reference< css::uno::XInterface > xStmIf(
1819  static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) );
1820 
1821  SvMemoryStream aMemStm( 65535, 65535 );
1822 
1823  // #i119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
1824  const_cast<GDIMetaFile&>( aGraphic.GetGDIMetaFile() ).Write( aMemStm );
1825 
1826  xActiveDataSource->setOutputStream( css::uno::Reference< css::io::XOutputStream >(
1827  xStmIf, css::uno::UNO_QUERY ) );
1828  css::uno::Sequence< sal_Int8 > aMtfSeq( static_cast<sal_Int8 const *>(aMemStm.GetData()), aMemStm.Tell() );
1829  xSVGWriter->write( xSaxWriter, aMtfSeq );
1830  }
1831  }
1832  }
1833  catch(const css::uno::Exception&)
1834  {
1835  nStatus = ERRCODE_GRFILTER_IOERROR;
1836  }
1837  }
1838  }
1839  else
1840  nStatus = ERRCODE_GRFILTER_FILTERERROR;
1841  }
1842  if( nStatus != ERRCODE_NONE )
1843  {
1844  ImplSetError( nStatus, &rOStm );
1845  }
1846  return nStatus;
1847 }
1848 
1849 
1851 {
1853 }
1854 
1856 {
1857  Link<ConvertData&,bool> aLink( LINK( const_cast<GraphicFilter*>(this), GraphicFilter, FilterCallback ) );
1858  return aLink;
1859 }
1860 
1861 IMPL_LINK( GraphicFilter, FilterCallback, ConvertData&, rData, bool )
1862 {
1863  bool bRet = false;
1864 
1865  sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
1866  OUString aShortName;
1867  css::uno::Sequence< css::beans::PropertyValue > aFilterData;
1868  switch( rData.mnFormat )
1869  {
1870  case ConvertDataFormat::BMP: aShortName = BMP_SHORTNAME; break;
1871  case ConvertDataFormat::GIF: aShortName = GIF_SHORTNAME; break;
1872  case ConvertDataFormat::JPG: aShortName = JPG_SHORTNAME; break;
1873  case ConvertDataFormat::MET: aShortName = MET_SHORTNAME; break;
1874  case ConvertDataFormat::PCT: aShortName = PCT_SHORTNAME; break;
1875  case ConvertDataFormat::PNG: aShortName = PNG_SHORTNAME; break;
1876  case ConvertDataFormat::SVM: aShortName = SVM_SHORTNAME; break;
1877  case ConvertDataFormat::TIF: aShortName = TIF_SHORTNAME; break;
1878  case ConvertDataFormat::WMF: aShortName = WMF_SHORTNAME; break;
1879  case ConvertDataFormat::EMF: aShortName = EMF_SHORTNAME; break;
1880  case ConvertDataFormat::SVG: aShortName = SVG_SHORTNAME; break;
1881 
1882  default:
1883  break;
1884  }
1885  if( GraphicType::NONE == rData.maGraphic.GetType() || rData.maGraphic.GetReaderContext() ) // Import
1886  {
1887  // Import
1888  nFormat = GetImportFormatNumberForShortName( aShortName );
1889  bRet = ImportGraphic( rData.maGraphic, OUString(), rData.mrStm, nFormat ) == ERRCODE_NONE;
1890  }
1891  else if( !aShortName.isEmpty() )
1892  {
1893  // Export
1894 #if defined(IOS) || defined(ANDROID)
1895  if (aShortName == PNG_SHORTNAME)
1896  {
1897  aFilterData.realloc(aFilterData.getLength() + 1);
1898  aFilterData[aFilterData.getLength() - 1].Name = "Compression";
1899  // We "know" that this gets passed to zlib's deflateInit2_(). 1 means best speed.
1900  aFilterData[aFilterData.getLength() - 1].Value <<= static_cast<sal_Int32>(1);
1901  }
1902 #endif
1903  nFormat = GetExportFormatNumberForShortName( aShortName );
1904  bRet = ExportGraphic( rData.maGraphic, OUString(), rData.mrStm, nFormat, &aFilterData ) == ERRCODE_NONE;
1905  }
1906 
1907  return bRet;
1908 }
1909 
1910 namespace
1911 {
1912  class StandardGraphicFilter
1913  {
1914  public:
1915  StandardGraphicFilter()
1916  {
1917  m_aFilter.GetImportFormatCount();
1918  }
1919  GraphicFilter m_aFilter;
1920  };
1921 }
1922 
1924 {
1925  static StandardGraphicFilter gStandardFilter;
1926  return gStandardFilter.m_aFilter;
1927 }
1928 
1929 ErrCode GraphicFilter::LoadGraphic( const OUString &rPath, const OUString &rFilterName,
1930  Graphic& rGraphic, GraphicFilter* pFilter,
1931  sal_uInt16* pDeterminedFormat )
1932 {
1933  if ( !pFilter )
1934  pFilter = &GetGraphicFilter();
1935 
1936  const sal_uInt16 nFilter = !rFilterName.isEmpty() && pFilter->GetImportFormatCount()
1937  ? pFilter->GetImportFormatNumber( rFilterName )
1939 
1940  INetURLObject aURL( rPath );
1941  if ( aURL.HasError() )
1942  {
1943  aURL.SetSmartProtocol( INetProtocol::File );
1944  aURL.SetSmartURL( rPath );
1945  }
1946 
1947  std::unique_ptr<SvStream> pStream;
1948  if ( INetProtocol::File != aURL.GetProtocol() )
1949  pStream = ::utl::UcbStreamHelper::CreateStream( rPath, StreamMode::READ );
1950 
1951  ErrCode nRes = ERRCODE_NONE;
1952  if ( !pStream )
1953  nRes = pFilter->ImportGraphic( rGraphic, aURL, nFilter, pDeterminedFormat );
1954  else
1955  nRes = pFilter->ImportGraphic( rGraphic, rPath, *pStream, nFilter, pDeterminedFormat );
1956 
1957 #ifdef DBG_UTIL
1958  OUString aReturnString;
1959 
1960  if (nRes == ERRCODE_GRFILTER_OPENERROR)
1961  aReturnString="open error";
1962  else if (nRes == ERRCODE_GRFILTER_IOERROR)
1963  aReturnString="IO error";
1964  else if (nRes == ERRCODE_GRFILTER_FORMATERROR)
1965  aReturnString="format error";
1966  else if (nRes == ERRCODE_GRFILTER_VERSIONERROR)
1967  aReturnString="version error";
1968  else if (nRes == ERRCODE_GRFILTER_FILTERERROR)
1969  aReturnString="filter error";
1970  else if (nRes == ERRCODE_GRFILTER_TOOBIG)
1971  aReturnString="graphic is too big";
1972 
1973  SAL_INFO_IF( nRes, "vcl.filter", "Problem importing graphic " << rPath << ". Reason: " << aReturnString );
1974 #endif
1975 
1976  return nRes;
1977 }
1978 
1979 ErrCode GraphicFilter::compressAsPNG(const Graphic& rGraphic, SvStream& rOutputStream)
1980 {
1981  css::uno::Sequence< css::beans::PropertyValue > aFilterData(1);
1982  aFilterData[0].Name = "Compression";
1983  aFilterData[0].Value <<= sal_uInt32(9);
1984 
1985  sal_uInt16 nFilterFormat = GetExportFormatNumberForShortName(u"PNG");
1986  return ExportGraphic(rGraphic, OUString(), rOutputStream, nFilterFormat, &aFilterData);
1987 }
1988 
1989 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetDummyContext(bool value)
Definition: graph.cxx:489
bool ImportEpsGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: ieps.cxx:582
OUString GetImportFormatExtension(sal_uInt16 nFormat, sal_Int32 nEntry=0)
#define IMP_MOV
VectorGraphicDataType
bool IsExportPixelFormat(sal_uInt16 nFormat)
SvStream & ReadInt16(sal_Int16 &rInt16)
static ErrCode readSVG(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType, std::unique_ptr< sal_uInt8[]> &rpGraphicContent, sal_Int32 &rGraphicContentSize)
OUString GetExportFormatName(sal_uInt16 nFormat)
Only create a bitmap, do not read pixel data.
URL aURL
Read pixel data into an existing bitmap.
ErrCode ImportGraphic(Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat=GRFILTER_FORMAT_DONTKNOW, sal_uInt16 *pDeterminedFormat=nullptr, GraphicFilterImportFlags nImportFlags=GraphicFilterImportFlags::NONE)
sal_uInt16 GetImportFormatNumberForTypeName(std::u16string_view rType)
bool ImportTiffGraphicImport(SvStream &rStream, Graphic &rGraphic)
Definition: itiff.cxx:1715
void readGraphic(Graphic &rGraphic)
OUString GetImportFilterName(sal_uInt16 nFormat)
void setPrepared(bool bAnimated, const Size *pSizeHint)
Definition: impgraph.cxx:377
static ErrCode readEPS(SvStream &rStream, Graphic &rGraphic)
void setWidth(tools::Long nWidth)
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1521
UNOTOOLS_DLLPUBLIC bool IsDocument(OUString const &url)
ErrCode CanImportGraphic(const INetURLObject &rPath, sal_uInt16 nFormat, sal_uInt16 *pDeterminedFormat)
bool BmpReader(SvStream &rStream, Graphic &rGraphic)
Definition: BmpReader.cxx:23
sal_uInt16 GetExportFormatNumberForTypeName(std::u16string_view rType)
static ErrCode readWMF(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType, WmfExternal const *pExtHeader)
sal_uIntPtr sal_uLong
#define SAL_INFO_IF(condition, area, stream)
ErrCode compressAsPNG(const Graphic &rGraphic, SvStream &rOutputStream)
long Long
void SetPrefMapMode(const MapMode &rPrefMapMode)
Definition: graph.cxx:380
OUString GetImportFormatName(sal_uInt16 nFormat)
virtual void doWork()=0
static ErrCode readGIF(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType)
#define ZCODEC_DEFAULT_COMPRESSION
static ErrCode readPSD(SvStream &rStream, Graphic &rGraphic)
bool isPCT(SvStream &rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
GraphicType
Definition: graph.hxx:34
#define STREAM_SEEK_TO_END
exports com.sun.star. graphic
bool ImportPcdGraphic(SvStream &rStream, Graphic &rGraphic, FilterConfigItem *pConfigItem)
Definition: ipcd.cxx:360
sal_uInt64 Seek(sal_uInt64 nPos)
bool read(BitmapEx &rBitmap)
OUString aFilterPath
Class to import and export graphic formats.
void Draw(OutputDevice &rOutDev, const Point &rDestPt) const
Definition: graph.cxx:429
void Flush()
tools::Long Decompress(SvStream &rIStm, SvStream &rOStm)
bool ExportTiffGraphicImport(SvStream &rStream, Graphic &rGraphic, FilterConfigItem *pFilterConfigItem)
Definition: etiff.cxx:580
This template handles BitmapAccess the RAII way.
sal_uInt16 GetImportFormatNumber(std::u16string_view rFormatName)
#define IMP_PICT
bool HasError() const
sal_uInt16 GetImportFormatNumberForExtension(std::u16string_view rExt)
get the index of the filter that matches this extension
#define ERRCODE_GRFILTER_IOERROR
OUString GetExportFormatExtension(sal_uInt16 nFormat, sal_Int32 nEntry=0)
#define IMP_EPS
void waitUntilDone(const std::shared_ptr< ThreadTaskTag > &, bool bJoin=true)
#define EXP_GIF
static ErrCode readPDF(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType)
bool Convert(BmpConversion eConversion)
Convert bitmap format.
Definition: BitmapEx.cxx:374
sal_uInt64 SeekRel(sal_Int64 nPos)
#define IMP_JPEG
bool ImportRasGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: iras.cxx:398
bool IsGfxLink() const
Definition: graph.cxx:515
OUString GetExportInternalFilterName(sal_uInt16 nFormat)
OUString GetExportInternalFilterName(sal_uInt16 nFormat)
static OutputDevice * GetDefaultDevice()
Get the default "device" (in this case the default window).
Definition: svapp.cxx:1069
#define EXP_JPEG
sal_Int32 ReadInt32(const OUString &rKey, sal_Int32 nDefault)
Graphic ImportUnloadedGraphic(SvStream &rIStream, sal_uInt64 sizeLimit=0, const Size *pSizeHint=nullptr)
constexpr tools::Long Width() const
HashMap_OWString_Interface aMap
OUString GetImportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
void Clear()
Definition: graph.cxx:288
static ErrCode readDXF(SvStream &rStream, Graphic &rGraphic)
#define TIF_SHORTNAME
sal_uInt16 GetExportFormatNumberForTypeName(std::u16string_view rType)
#define JPG_SHORTNAME
sal_uInt16 GetImportFormatNumberForShortName(std::u16string_view rShortName)
bool IsAlpha() const
Definition: BitmapEx.cxx:193
#define IMP_PCD
ErrCode GetError() const
Sequence< PropertyValue > aArguments
Reference< XInputStream > xStream
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
static ErrCode readPCX(SvStream &rStream, Graphic &rGraphic)
#define EXP_TIFF
const Reference< XComponentContext > & m_rContext
Container for the binary data, whose responsibility is to manage the make it as simple as possible to...
#define EXP_SVMETAFILE
sal_uInt8 * ImplSearchEntry(sal_uInt8 *pSource, sal_uInt8 const *pDest, sal_uLong nComp, sal_uLong nSize)
OUString GetImportFilterType(sal_uInt16 nFormat)
static bool IsFuzzing()
#define PNG_SHORTNAME
static ErrCode readTGA(SvStream &rStream, Graphic &rGraphic)
bool ConvertGDIMetaFileToEMF(const GDIMetaFile &rMTF, SvStream &rTargetStream)
Definition: wmf.cxx:113
void ImportGraphics(std::vector< std::shared_ptr< Graphic > > &rGraphics, std::vector< std::unique_ptr< SvStream > > vStreams)
Imports multiple graphics.
bool ExportJPEG(SvStream &rOutputStream, const Graphic &rGraphic, const css::uno::Sequence< css::beans::PropertyValue > *pFilterData, bool *pExportWasGrey)
Definition: jpeg.cxx:53
#define ERRCODE_GRFILTER_OPENERROR
sal_uInt16 GetExportFormatCount() const
static ErrCode readRAS(SvStream &rStream, Graphic &rGraphic)
const GDIMetaFile & GetGDIMetaFile() const
Definition: graph.cxx:340
#define BMP_SHORTNAME
#define IMP_DXF
#define ERRCODE_GRFILTER_FORMATERROR
bool ImportPNG(SvStream &rInputStream, Graphic &rGraphic, GraphicFilterImportFlags nImportFlags, BitmapScopedWriteAccess *pAccess, AlphaScopedWriteAccess *pAlphaAccess)
bool IsExportPixelFormat(sal_uInt16 nFormat)
OUString GetImportFormatShortName(sal_uInt16 nFormat)
VCL_DLLPUBLIC bool ImportGIF(SvStream &rStm, Graphic &rGraphic)
Definition: gifread.cxx:969
constexpr tools::Long getHeight() const
VCL_DLLPUBLIC bool ImportXPM(SvStream &rStm, Graphic &rGraphic)
Definition: xpmread.cxx:672
sal_uInt64 remainingSize()
sal_uInt16 GetImportFormatCount() const
sal_uInt16 GetExportFormatNumberForShortName(std::u16string_view rShortName)
OUString GetExportFormatName(sal_uInt16 nFormat)
void SetGfxLink(const std::shared_ptr< GfxLink > &rGfxLink)
Definition: graph.cxx:499
OUString GetExportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
ErrCode ImpTestOrFindFormat(const OUString &rPath, SvStream &rStream, sal_uInt16 &rFormat)
GraphicFilter(bool bUseConfig=true)
static ErrCode readPBM(SvStream &rStream, Graphic &rGraphic)
#define IMP_SVMETAFILE
static ThreadPool & getSharedOptimalPool()
DocumentType eType
#define IMP_RAS
static ErrCode LoadGraphic(const OUString &rPath, const OUString &rFilter, Graphic &rGraphic, GraphicFilter *pFilter=nullptr, sal_uInt16 *pDeterminedFormat=nullptr)
static ErrCode readJPEG(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType, GraphicFilterImportFlags nImportFlags)
#define IMP_BMP
#define EXP_SVG
static ErrCode readTIFF(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType)
OUString GetImportFormatMediaType(sal_uInt16 nFormat)
bool ImportPsdGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: ipsd.cxx:766
SAL_DLLPRIVATE ImpGraphic * ImplGetImpGraphic() const
Definition: graph.hxx:89
Cache to keep list of graphic filters + the filters themselves.
bool ConvertGraphicToWMF(const Graphic &rGraphic, SvStream &rTargetStream, FilterConfigItem const *pConfigItem, bool bPlaceable)
Definition: wmf.cxx:87
#define IMP_PBM
int i
void pushTask(std::unique_ptr< ThreadTask > pTask)
OUString GetImportFormatTypeName(sal_uInt16 nFormat)
std::vector< vcl::PNGWriter::ChunkData > & GetChunks()
Definition: pngwrite.cxx:647
GraphicType GetType() const
Definition: graph.cxx:294
#define EMF_SHORTNAME
void SetSmartProtocol(INetProtocol eTheSmartScheme)
static std::unique_ptr< sal_uInt8[]> getMicrosoftGifChunk(SvStream &rStream, sal_Int32 *chunkSize=nullptr)
#define STREAM_SEEK_TO_BEGIN
sal_uInt16 GetExportFormatNumber(std::u16string_view rFormatName)
void MakeGraphicsAvailableThreaded(std::vector< Graphic * > &rGraphics)
Tries to ensure all Graphic objects are available (Graphic::isAvailable()).
FilterConfigCache * pConfig
sal_uInt16 GetImportFormatNumberForTypeName(std::u16string_view rType)
sal_uInt16 GetExportFormatNumber(std::u16string_view rFormatName)
VCL_DLLPUBLIC bool ImportXBM(SvStream &rStm, Graphic &rGraphic)
Definition: xbmread.cxx:371
std::size_t WriteBytes(const void *pData, std::size_t nSize)
const BitmapEx & GetBitmapExRef() const
Gives direct access to the contained BitmapEx.
Definition: graph.cxx:345
sal_uInt16 GetExportFormatNumberForMediaType(std::u16string_view rShortName)
float u
void BeginCompression(int nCompressLevel=ZCODEC_DEFAULT_COMPRESSION, bool gzLib=false)
tools::Long EndCompression()
#define IMP_XBM
static ErrCode readWithTypeSerializer(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType, OUString aFilterName)
#define IMP_SVG
#define GRFILTER_FORMAT_DONTKNOW
static ErrCode readEMF(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType, WmfExternal const *pExtHeader)
static ErrCode readPNG(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType, std::unique_ptr< sal_uInt8[]> &rpGraphicContent, sal_Int32 &rGraphicContentSize)
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
Definition: graph.cxx:330
OUString GetImportFilterTypeName(sal_uInt16 nFormat)
void SetVersion(sal_Int32 n)
sal_Int16 nVersion
GfxLink GetGfxLink() const
Definition: graph.cxx:510
bool ExportEpsGraphic(SvStream &rStream, Graphic &rGraphic, FilterConfigItem *pFilterConfigItem)
Definition: eps.cxx:2665
Link< ConvertData &, bool > GetFilterCallback() const
ErrCode ExportGraphic(const Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat, const css::uno::Sequence< css::beans::PropertyValue > *pFilterData=nullptr)
#define IMP_PSD
#define IMP_TIFF
sal_uInt16 GetImportFormatNumber(std::u16string_view rFormatName)
static ErrCode readXBM(SvStream &rStream, Graphic &rGraphic)
oslInterlockedCount m_nStatus
IMPL_LINK(GraphicFilter, FilterCallback, ConvertData &, rData, bool)
OUString GetImportFormatName(sal_uInt16 nFormat)
OUString GetImportFormatShortName(sal_uInt16 nFormat)
std::size_t ReadBytes(void *pData, std::size_t nSize)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:203
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1066
Size GetPrefSize() const
Definition: graph.cxx:364
bool ExportGifGraphic(SvStream &rStream, Graphic &rGraphic, FilterConfigItem *pConfigItem)
Definition: egif.cxx:543
#define IMP_MET
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString GetExportFormatShortName(sal_uInt16 nFormat)
#define ERRCODE_GRFILTER_TOOBIG
bool ImportDxfGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: idxf.cxx:28
SvStreamEndian GetEndian() const
#define ERRCODE_GRFILTER_FILTERERROR
#define ERRCODE_GRFILTER_VERSIONERROR
#define IMP_WMF
css::uno::Sequence< sal_Int8 > VectorGraphicDataArray
std::optional< ErrCode > mxErrorEx
Information about errors during the GraphicFilter operation.
#define EXP_EPS
OUString GetExportFormatMediaType(sal_uInt16 nFormat)
static OUString ImpGetExtension(const OUString &rPath)
const css::uno::Sequence< css::beans::PropertyValue > & GetFilterData() const
static ErrCode readXPM(SvStream &rStream, Graphic &rGraphic)
AlphaMask GetAlpha() const
Definition: BitmapEx.cxx:215
#define SAL_WARN_IF(condition, area, stream)
#define ERRCODE_NONE
Definition: errcode.hxx:196
MapMode GetPrefMapMode() const
Definition: graph.cxx:375
constexpr tools::Long Height() const
unsigned char sal_uInt8
#define EXP_WMF
sal_uInt16 GetImportFormatCount() const
#define IMP_PNG
bool ImportMetGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: ios2met.cxx:2790
static std::mutex & getListMutex()
void SetEndian(SvStreamEndian SvStreamEndian)
#define SAL_INFO(area, stream)
#define IMP_PCX
std::shared_ptr< GraphicReader > & GetReaderContext()
Definition: graph.cxx:479
INetProtocol GetProtocol() const
OUString GetFileExtension() const
#define IMP_GIF
sal_uInt64 Tell() const
Reference< XComponentContext > getProcessComponentContext()
VCL_DLLPUBLIC bool ImportJPEG(SvStream &rInputStream, Graphic &rGraphic, GraphicFilterImportFlags nImportFlags, BitmapScopedWriteAccess *ppAccess)
Definition: jpeg.cxx:26
static std::shared_ptr< ThreadTaskTag > createThreadTaskTag()
OUString GetExportWildcard(sal_uInt16 nFormat)
bool peekGraphicFormat(SvStream &rStream, OUString &rFormatExtension, bool bTest)
#define IMP_PDF
#define EXP_EMF
OUString GetExportFilterName(sal_uInt16 nFormat)
void SetPrefSize(const Size &rPrefSize)
Definition: graph.cxx:369
void WriteInt32(const OUString &rKey, sal_Int32 nValue)
ErrCode ImplSetError(ErrCode nError, const SvStream *pStm=nullptr)
#define IMP_XPM
sal_uInt16 GetExportFormatNumberForMediaType(std::u16string_view rMediaType)
void setHeight(tools::Long nHeight)
#define EXP_BMP
#define ERRCODE_IO_PENDING
Definition: errcode.hxx:225
bool ImportPcxGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: ipcx.cxx:402
OUString GetExportFormatShortName(sal_uInt16 nFormat)
static GraphicFilter & GetGraphicFilter()
#define MET_SHORTNAME
SvStreamEndian
#define SVM_SHORTNAME
static ErrCode readMET(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType)
virtual void ResetError()
constexpr tools::Long getWidth() const
bool ImportPictGraphic(SvStream &rIStm, Graphic &rGraphic)
Definition: ipict.cxx:1999
static Graphic ImpGetScaledGraphic(const Graphic &rGraphic, FilterConfigItem &rConfigItem)
void SetDefaultType()
Definition: graph.cxx:299
static ErrCode readPICT(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType)
bool BmpWriter(SvStream &rStream, Graphic &rGraphic, FilterConfigItem *pFilterConfigItem)
Definition: BmpWriter.cxx:23
static ErrCode readBMP(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType)
static ErrCode readWMF_EMF(SvStream &rStream, Graphic &rGraphic, GfxLinkType &rLinkType, WmfExternal const *pExtHeader, VectorGraphicDataType eType)
const std::shared_ptr< VectorGraphicData > & getVectorGraphicData() const
Definition: graph.cxx:525
GraphicFilterImportFlags
#define IMP_EMF
#define SVG_SHORTNAME
UNOTOOLS_DLLPUBLIC bool Kill(OUString const &url)
#define IMP_TGA
bool ImportPDF(SvStream &rStream, Graphic &rGraphic)
Imports a PDF stream into rGraphic.
Definition: pdfread.cxx:245
std::vector< sal_uInt8 > aData
Definition: pngwrite.hxx:52
#define GIF_SHORTNAME
sal_uInt16 GetExportFormatCount() const
sal_uInt16 GetExportFormatNumberForShortName(std::u16string_view rShortName)
bool ImportPbmGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: ipbm.cxx:534
OUString GetExportFormatMediaType(sal_uInt16 nFormat)
#define PCT_SHORTNAME
sal_uInt16 GetImportFormatNumberForShortName(std::u16string_view rShortName)
#define WMF_SHORTNAME
bool IsDummyContext() const
Definition: graph.cxx:494
static ErrCode readPCD(SvStream &rStream, Graphic &rGraphic)
SvStream & Write(SvStream &rOStm)
Definition: gdimtf.cxx:2740
OUString GetImportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
bool SetSmartURL(OUString const &rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
const void * GetData()
bool ImportTgaGraphic(SvStream &rStream, Graphic &rGraphic)
Definition: itga.cxx:784
#define EXP_PNG
bool IsGIFAnimated(SvStream &rStm, Size &rLogicSize)
Definition: gifread.cxx:956
static std::vector< GraphicFilter * > gaFilterHdlList