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