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 #ifndef INCLUDED_VCL_GRAPHICFILTER_HXX 21 #define INCLUDED_VCL_GRAPHICFILTER_HXX 22 23 #include <tools/gen.hxx> 24 #include <vcl/dllapi.h> 25 #include <vcl/graph.hxx> 26 #include <vcl/errcode.hxx> 27 #include <o3tl/typed_flags_set.hxx> 28 29 #include <memory> 30 #include <optional> 31 32 namespace com::sun::star::beans { struct PropertyValue; } 33 namespace com::sun::star::uno { template <class E> class Sequence; } 34 35 class INetURLObject; 36 37 class FilterConfigCache; 38 class SvStream; 39 struct WmfExternal; 40 struct ConvertData; 41 42 #define ERRCODE_GRFILTER_OPENERROR ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 1) 43 #define ERRCODE_GRFILTER_IOERROR ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 2) 44 #define ERRCODE_GRFILTER_FORMATERROR ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 3) 45 #define ERRCODE_GRFILTER_VERSIONERROR ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 4) 46 #define ERRCODE_GRFILTER_FILTERERROR ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 5) 47 #define ERRCODE_GRFILTER_TOOBIG ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 7) 48 49 #define GRFILTER_OUTHINT_GREY 1 50 51 #define GRFILTER_FORMAT_NOTFOUND (sal_uInt16(0xFFFF)) 52 #define GRFILTER_FORMAT_DONTKNOW (sal_uInt16(0xFFFF)) 53 54 enum class GraphicFilterImportFlags 55 { 56 NONE = 0x000, 57 SetLogsizeForJpeg = 0x001, 58 DontSetLogsizeForJpeg = 0x002, 59 /// Only create a bitmap, do not read pixel data. 60 OnlyCreateBitmap = 0x020, 61 /// Read pixel data into an existing bitmap. 62 UseExistingBitmap = 0x040, 63 }; 64 namespace o3tl 65 { 66 template<> struct typed_flags<GraphicFilterImportFlags> : is_typed_flags<GraphicFilterImportFlags, 0x0063> {}; 67 } 68 69 #define IMP_BMP "SVBMP" 70 #define IMP_MOV "SVMOV" 71 #define IMP_SVMETAFILE "SVMETAFILE" 72 #define IMP_WMF "SVWMF" 73 #define IMP_EMF "SVEMF" 74 #define IMP_GIF "SVIGIF" 75 #define IMP_PNG "SVIPNG" 76 #define IMP_JPEG "SVIJPEG" 77 #define IMP_XBM "SVIXBM" 78 #define IMP_XPM "SVIXPM" 79 #define IMP_SVG "SVISVG" 80 #define IMP_PDF "SVIPDF" 81 #define IMP_TIFF "SVTIFF" 82 #define IMP_TGA "SVTGA" 83 #define IMP_PICT "SVPICT" 84 #define IMP_MET "SVMET" 85 #define IMP_RAS "SVRAS" 86 #define IMP_PCX "SVPCX" 87 #define IMP_EPS "SVIEPS" 88 #define IMP_PSD "SVPSD" 89 #define IMP_PCD "SVPCD" 90 #define IMP_PBM "SVPBM" 91 #define IMP_DXF "SVDXF" 92 93 #define EXP_BMP "SVBMP" 94 #define EXP_SVMETAFILE "SVMETAFILE" 95 #define EXP_WMF "SVWMF" 96 #define EXP_EMF "SVEMF" 97 #define EXP_JPEG "SVEJPEG" 98 #define EXP_SVG "SVESVG" 99 #define EXP_PDF "SVEPDF" 100 #define EXP_PNG "SVEPNG" 101 #define EXP_TIFF "SVTIFF" 102 #define EXP_EPS "SVEEPS" 103 #define EXP_GIF "SVEGIF" 104 105 106 #define BMP_SHORTNAME u"BMP" 107 #define GIF_SHORTNAME u"GIF" 108 #define JPG_SHORTNAME u"JPG" 109 #define MET_SHORTNAME u"MET" 110 #define PCT_SHORTNAME u"PCT" 111 #define PNG_SHORTNAME u"PNG" 112 #define SVM_SHORTNAME u"SVM" 113 #define TIF_SHORTNAME u"TIF" 114 #define WMF_SHORTNAME u"WMF" 115 #define EMF_SHORTNAME u"EMF" 116 #define SVG_SHORTNAME u"SVG" 117 #define PDF_SHORTNAME u"PDF" 118 119 // Info class for all supported file formats 120 121 enum class GraphicFileFormat 122 { 123 NOT = 0x0000, 124 BMP = 0x0001, 125 GIF = 0x0002, 126 JPG = 0x0003, 127 PCD = 0x0004, 128 PCX = 0x0005, 129 PNG = 0x0006, 130 TIF = 0x0007, 131 XBM = 0x0008, 132 XPM = 0x0009, 133 PBM = 0x000a, 134 PGM = 0x000b, 135 PPM = 0x000c, 136 RAS = 0x000d, 137 TGA = 0x000e, 138 PSD = 0x000f, 139 EPS = 0x0010, 140 DXF = 0x00f1, 141 MET = 0x00f2, 142 PCT = 0x00f3, 143 // retired SGF = 0x00f4, 144 SVM = 0x00f5, 145 WMF = 0x00f6, 146 // retired SGV = 0x00f7, 147 EMF = 0x00f8, 148 SVG = 0x00f9 149 }; 150 151 152 class VCL_DLLPUBLIC GraphicDescriptor final 153 { 154 SvStream* pFileStm; 155 156 OUString aPathExt; 157 Size aPixSize; 158 Size aLogSize; 159 std::optional<Size> maPreferredLogSize; 160 std::optional<MapMode> maPreferredMapMode; 161 sal_uInt16 nBitsPerPixel; 162 sal_uInt16 nPlanes; 163 GraphicFileFormat nFormat; 164 bool bOwnStream; 165 sal_uInt8 mnNumberOfImageComponents; 166 bool bIsTransparent; 167 bool bIsAlpha; 168 169 void ImpConstruct(); 170 171 bool ImpDetectBMP( SvStream& rStm, bool bExtendedInfo ); 172 bool ImpDetectGIF( SvStream& rStm, bool bExtendedInfo ); 173 bool ImpDetectJPG( SvStream& rStm, bool bExtendedInfo ); 174 bool ImpDetectPCD( SvStream& rStm, bool bExtendedInfo ); 175 bool ImpDetectPCX( SvStream& rStm ); 176 bool ImpDetectPNG( SvStream& rStm, bool bExtendedInfo ); 177 bool ImpDetectTIF( SvStream& rStm, bool bExtendedInfo ); 178 bool ImpDetectXBM( SvStream& rStm, bool bExtendedInfo ); 179 bool ImpDetectXPM( SvStream& rStm, bool bExtendedInfo ); 180 bool ImpDetectPBM( SvStream& rStm, bool bExtendedInfo ); 181 bool ImpDetectPGM( SvStream& rStm, bool bExtendedInfo ); 182 bool ImpDetectPPM( SvStream& rStm, bool bExtendedInfo ); 183 bool ImpDetectRAS( SvStream& rStm, bool bExtendedInfo ); 184 bool ImpDetectTGA( SvStream& rStm, bool bExtendedInfo ); 185 bool ImpDetectPSD( SvStream& rStm, bool bExtendedInfo ); 186 bool ImpDetectEPS( SvStream& rStm, bool bExtendedInfo ); 187 bool ImpDetectDXF( SvStream& rStm, bool bExtendedInfo ); 188 bool ImpDetectMET( SvStream& rStm, bool bExtendedInfo ); 189 bool ImpDetectPCT( SvStream& rStm, bool bExtendedInfo ); 190 bool ImpDetectSVM( SvStream& rStm, bool bExtendedInfo ); 191 bool ImpDetectWMF( SvStream& rStm, bool bExtendedInfo ); 192 bool ImpDetectEMF( SvStream& rStm, bool bExtendedInfo ); 193 bool ImpDetectSVG( SvStream& rStm, bool bExtendedInfo ); 194 GraphicDescriptor( const GraphicDescriptor& ) = delete; 195 GraphicDescriptor& operator=( const GraphicDescriptor& ) = delete; 196 197 public: 198 199 /** Ctor to set a filename 200 201 Detect() must be called to identify the file 202 If the file has no unique header (Mtf's), the format 203 is determined from the extension */ 204 GraphicDescriptor( const INetURLObject& rPath ); 205 206 /** Ctor using a stream 207 208 Detect() must be called to identify the file 209 As some formats (Mtf's) do not have a unique header, it makes sense 210 to supply the file name (incl. ext.), so that the format can be 211 derived from the extension */ 212 GraphicDescriptor( SvStream& rInStream, const OUString* pPath ); 213 214 ~GraphicDescriptor(); 215 216 /** starts the detection 217 218 if bExtendedInfo == true the file header is used to derive 219 as many properties as possible (size, color, etc.) */ 220 bool Detect( bool bExtendedInfo = false ); 221 222 /** @return the file format, GraphicFileFormat::NOT if no format was recognized */ GetFileFormat() const223 GraphicFileFormat GetFileFormat() const { return nFormat; } 224 225 /** @return graphic size in pixels or 0 size */ GetSizePixel() const226 const Size& GetSizePixel() const { return aPixSize; } 227 228 /** @return the logical graphic size in 1/100mm or 0 size */ GetSize_100TH_MM() const229 const Size& GetSize_100TH_MM() const { return aLogSize; } 230 231 /** 232 * Returns the logic size, according to the map mode available via GetPreferredMapMode(). Prefer 233 * this size over GetSize_100TH_MM(). 234 */ GetPreferredLogSize() const235 std::optional<Size> GetPreferredLogSize() const { return maPreferredLogSize; } 236 237 /** 238 * If available, this returns the map mode the graphic prefers, which may be other than pixel or 239 * 100th mm. Prefer this map mode over just assuming MapUnit::Map100thMM. 240 */ GetPreferredMapMode() const241 std::optional<MapMode> GetPreferredMapMode() const { return maPreferredMapMode; } 242 243 /** @return bits/pixel or 0 **/ GetBitsPerPixel() const244 sal_uInt16 GetBitsPerPixel() const { return nBitsPerPixel; } 245 246 /** @return number of color channels */ GetNumberOfImageComponents() const247 sal_uInt8 GetNumberOfImageComponents() const { return mnNumberOfImageComponents; } 248 249 /** @return whether image supports transparency */ IsTransparent() const250 bool IsTransparent() const { return bIsTransparent; } 251 252 /** @return whether image supports alpha values for translucent colours */ IsAlpha() const253 bool IsAlpha() const { return bIsAlpha; } 254 255 /** @return filter number that is needed by the GraphFilter to read this format */ 256 static OUString GetImportFormatShortName( GraphicFileFormat nFormat ); 257 }; 258 259 /** Information about errors during the GraphicFilter operation. */ 260 struct FilterErrorEx 261 { 262 ErrCode nStreamError; 263 FilterErrorExFilterErrorEx264 FilterErrorEx() : nStreamError( ERRCODE_NONE ) {} 265 }; 266 267 /** Class to import and export graphic formats. */ 268 class VCL_DLLPUBLIC GraphicFilter 269 { 270 public: 271 GraphicFilter( bool bUseConfig = true ); 272 ~GraphicFilter(); 273 274 sal_uInt16 GetImportFormatCount() const; 275 sal_uInt16 GetImportFormatNumber( std::u16string_view rFormatName ); 276 sal_uInt16 GetImportFormatNumberForShortName( std::u16string_view rShortName ); 277 sal_uInt16 GetImportFormatNumberForTypeName( std::u16string_view rType ); 278 OUString GetImportFormatName( sal_uInt16 nFormat ); 279 OUString GetImportFormatTypeName( sal_uInt16 nFormat ); 280 #ifdef _WIN32 281 OUString GetImportFormatMediaType( sal_uInt16 nFormat ); 282 #endif 283 OUString GetImportFormatShortName( sal_uInt16 nFormat ); 284 OUString GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry ); 285 286 sal_uInt16 GetExportFormatCount() const; 287 sal_uInt16 GetExportFormatNumber( std::u16string_view rFormatName ); 288 sal_uInt16 GetExportFormatNumberForMediaType( std::u16string_view rShortName ); 289 sal_uInt16 GetExportFormatNumberForShortName( std::u16string_view rShortName ); 290 OUString GetExportInternalFilterName( sal_uInt16 nFormat ); 291 sal_uInt16 GetExportFormatNumberForTypeName( std::u16string_view rType ); 292 OUString GetExportFormatName( sal_uInt16 nFormat ); 293 OUString GetExportFormatMediaType( sal_uInt16 nFormat ); 294 OUString GetExportFormatShortName( sal_uInt16 nFormat ); 295 OUString GetExportWildcard( sal_uInt16 nFormat ); 296 bool IsExportPixelFormat( sal_uInt16 nFormat ); 297 298 ErrCode ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath, 299 sal_uInt16 nFormat, 300 const css::uno::Sequence< css::beans::PropertyValue >* pFilterData = nullptr ); 301 ErrCode ExportGraphic( const Graphic& rGraphic, const OUString& rPath, 302 SvStream& rOStm, sal_uInt16 nFormat, 303 const css::uno::Sequence< css::beans::PropertyValue >* pFilterData = nullptr ); 304 305 ErrCode CanImportGraphic( const INetURLObject& rPath, 306 sal_uInt16 nFormat, 307 sal_uInt16 * pDeterminedFormat); 308 309 ErrCode ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath, 310 sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW, 311 sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE ); 312 313 ErrCode CanImportGraphic( const OUString& rPath, SvStream& rStream, 314 sal_uInt16 nFormat, 315 sal_uInt16 * pDeterminedFormat); 316 317 ErrCode ImportGraphic( Graphic& rGraphic, const OUString& rPath, 318 SvStream& rStream, 319 sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW, 320 sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE, 321 WmfExternal const *pExtHeader = nullptr ); 322 323 /// Imports multiple graphics. 324 /// 325 /// The resulting graphic is added to rGraphics on success, nullptr is added on failure. 326 void ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGraphics, std::vector< std::unique_ptr<SvStream> > vStreams); 327 328 /** 329 Tries to ensure all Graphic objects are available (Graphic::isAvailable()). Only an optimization, may 330 not process all items. 331 */ 332 void MakeGraphicsAvailableThreaded(std::vector< Graphic* >& rGraphics); 333 334 ErrCode ImportGraphic( Graphic& rGraphic, const OUString& rPath, 335 SvStream& rStream, 336 sal_uInt16 nFormat, 337 sal_uInt16 * pDeterminedFormat, GraphicFilterImportFlags nImportFlags, 338 const css::uno::Sequence< css::beans::PropertyValue >* pFilterData, 339 WmfExternal const *pExtHeader = nullptr ); 340 341 // Setting sizeLimit limits how much will be read from the stream. 342 Graphic ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 sizeLimit = 0, const Size* pSizeHint = nullptr); 343 GetLastError() const344 const FilterErrorEx& GetLastError() const { return *pErrorEx;} 345 void ResetLastError(); 346 347 Link<ConvertData&,bool> GetFilterCallback() const; 348 static GraphicFilter& GetGraphicFilter(); 349 static ErrCode LoadGraphic( const OUString& rPath, const OUString& rFilter, 350 Graphic& rGraphic, 351 GraphicFilter* pFilter = nullptr, 352 sal_uInt16* pDeterminedFormat = nullptr ); 353 354 ErrCode compressAsPNG(const Graphic& rGraphic, SvStream& rOutputStream); 355 356 static ErrCode readGIF(SvStream& rStream, Graphic& rGraphic, GfxLinkType& rLinkType); 357 static ErrCode readPNG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, 358 std::unique_ptr<sal_uInt8[]> & rpGraphicContent, sal_Int32& rGraphicContentSize); 359 static ErrCode readJPEG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, 360 GraphicFilterImportFlags nImportFlags); 361 static ErrCode readSVG(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, 362 std::unique_ptr<sal_uInt8[]> & rpGraphicContent, sal_Int32& rGraphicContentSize); 363 static ErrCode readXBM(SvStream & rStream, Graphic & rGraphic); 364 static ErrCode readXPM(SvStream & rStream, Graphic & rGraphic); 365 366 static ErrCode readWMF_EMF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, 367 WmfExternal const* pExtHeader, VectorGraphicDataType eType); 368 static ErrCode readWMF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, WmfExternal const* pExtHeader); 369 static ErrCode readEMF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, WmfExternal const* pExtHeader); 370 371 static ErrCode readPDF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType); 372 static ErrCode readTIFF(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType); 373 static ErrCode readWithTypeSerializer(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType, OUString aFilterName); 374 static ErrCode readBMP(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType); 375 static ErrCode readTGA(SvStream & rStream, Graphic & rGraphic); 376 static ErrCode readPICT(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType); 377 static ErrCode readMET(SvStream & rStream, Graphic & rGraphic, GfxLinkType & rLinkType); 378 static ErrCode readRAS(SvStream & rStream, Graphic & rGraphic); 379 static ErrCode readPCX(SvStream & rStream, Graphic & rGraphic); 380 static ErrCode readEPS(SvStream & rStream, Graphic & rGraphic); 381 static ErrCode readPSD(SvStream & rStream, Graphic & rGraphic); 382 static ErrCode readPCD(SvStream & rStream, Graphic & rGraphic); 383 static ErrCode readPBM(SvStream & rStream, Graphic & rGraphic); 384 static ErrCode readDXF(SvStream & rStream, Graphic & rGraphic); 385 386 private: 387 OUString aFilterPath; 388 FilterConfigCache* pConfig; 389 390 void ImplInit(); 391 ErrCode ImplSetError( ErrCode nError, const SvStream* pStm = nullptr ); 392 ErrCode ImpTestOrFindFormat( const OUString& rPath, SvStream& rStream, sal_uInt16& rFormat ); 393 394 DECL_LINK( FilterCallback, ConvertData&, bool ); 395 396 std::unique_ptr<FilterErrorEx> pErrorEx; 397 bool bUseConfig; 398 }; 399 400 #endif // INCLUDED_VCL_GRAPHICFILTER_HXX 401 402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 403