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 
31 namespace com { namespace sun { namespace star { namespace beans { struct PropertyValue; } } } }
32 namespace com { namespace sun { namespace star { namespace uno { template <class E> class Sequence; } } } }
33 
34 class INetURLObject;
35 
36 class FilterConfigCache;
37 class SvStream;
38 struct WmfExternal;
39 struct ConvertData;
40 
41 #define ERRCODE_GRFILTER_OPENERROR    ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 1)
42 #define ERRCODE_GRFILTER_IOERROR      ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 2)
43 #define ERRCODE_GRFILTER_FORMATERROR  ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 3)
44 #define ERRCODE_GRFILTER_VERSIONERROR ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 4)
45 #define ERRCODE_GRFILTER_FILTERERROR  ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 5)
46 #define ERRCODE_GRFILTER_TOOBIG       ErrCode(ErrCodeArea::Vcl, ErrCodeClass::General, 7)
47 
48 #define GRFILTER_OUTHINT_GREY       1
49 
50 #define GRFILTER_FORMAT_NOTFOUND    (sal_uInt16(0xFFFF))
51 #define GRFILTER_FORMAT_DONTKNOW    (sal_uInt16(0xFFFF))
52 
53 enum class GraphicFilterImportFlags
54 {
55     NONE                   = 0x000,
56     SetLogsizeForJpeg      = 0x001,
57     DontSetLogsizeForJpeg  = 0x002,
58     ForPreview             = 0x004,
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, 0x0067> {};
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 EXP_BMP                 "SVBMP"
82 #define EXP_SVMETAFILE          "SVMETAFILE"
83 #define EXP_WMF                 "SVWMF"
84 #define EXP_EMF                 "SVEMF"
85 #define EXP_JPEG                "SVEJPEG"
86 #define EXP_SVG                 "SVESVG"
87 #define EXP_PDF                 "SVEPDF"
88 #define EXP_PNG                 "SVEPNG"
89 
90 #define BMP_SHORTNAME           "BMP"
91 #define GIF_SHORTNAME           "GIF"
92 #define JPG_SHORTNAME           "JPG"
93 #define MET_SHORTNAME           "MET"
94 #define PCT_SHORTNAME           "PCT"
95 #define PNG_SHORTNAME           "PNG"
96 #define SVM_SHORTNAME           "SVM"
97 #define TIF_SHORTNAME           "TIF"
98 #define WMF_SHORTNAME           "WMF"
99 #define EMF_SHORTNAME           "EMF"
100 #define SVG_SHORTNAME           "SVG"
101 #define PDF_SHORTNAME           "PDF"
102 
103 //  Info class for all supported file formats
104 
105 enum class GraphicFileFormat
106 {
107     NOT = 0x0000,
108     BMP = 0x0001,
109     GIF = 0x0002,
110     JPG = 0x0003,
111     PCD = 0x0004,
112     PCX = 0x0005,
113     PNG = 0x0006,
114     TIF = 0x0007,
115     XBM = 0x0008,
116     XPM = 0x0009,
117     PBM = 0x000a,
118     PGM = 0x000b,
119     PPM = 0x000c,
120     RAS = 0x000d,
121     TGA = 0x000e,
122     PSD = 0x000f,
123     EPS = 0x0010,
124     DXF = 0x00f1,
125     MET = 0x00f2,
126     PCT = 0x00f3,
127     // retired SGF = 0x00f4,
128     SVM = 0x00f5,
129     WMF = 0x00f6,
130     // retired SGV = 0x00f7,
131     EMF = 0x00f8,
132     SVG = 0x00f9
133 };
134 
135 
136 class VCL_DLLPUBLIC GraphicDescriptor final
137 {
138     SvStream*           pFileStm;
139 
140     OUString            aPathExt;
141     Size                aPixSize;
142     Size                aLogSize;
143     sal_uInt16          nBitsPerPixel;
144     sal_uInt16          nPlanes;
145     GraphicFileFormat   nFormat;
146     bool const          bOwnStream;
147     sal_uInt8 mnNumberOfImageComponents;
148     bool                bIsTransparent;
149     bool                bIsAlpha;
150 
151     void                ImpConstruct();
152 
153     bool            ImpDetectBMP( SvStream& rStm, bool bExtendedInfo );
154     bool            ImpDetectGIF( SvStream& rStm, bool bExtendedInfo );
155     bool            ImpDetectJPG( SvStream& rStm, bool bExtendedInfo );
156     bool            ImpDetectPCD( SvStream& rStm, bool bExtendedInfo );
157     bool            ImpDetectPCX( SvStream& rStm );
158     bool            ImpDetectPNG( SvStream& rStm, bool bExtendedInfo );
159     bool            ImpDetectTIF( SvStream& rStm, bool bExtendedInfo );
160     bool            ImpDetectXBM( SvStream& rStm, bool bExtendedInfo );
161     bool            ImpDetectXPM( SvStream& rStm, bool bExtendedInfo );
162     bool            ImpDetectPBM( SvStream& rStm, bool bExtendedInfo );
163     bool            ImpDetectPGM( SvStream& rStm, bool bExtendedInfo );
164     bool            ImpDetectPPM( SvStream& rStm, bool bExtendedInfo );
165     bool            ImpDetectRAS( SvStream& rStm, bool bExtendedInfo );
166     bool            ImpDetectTGA( SvStream& rStm, bool bExtendedInfo );
167     bool            ImpDetectPSD( SvStream& rStm, bool bExtendedInfo );
168     bool            ImpDetectEPS( SvStream& rStm, bool bExtendedInfo );
169     bool            ImpDetectDXF( SvStream& rStm, bool bExtendedInfo );
170     bool            ImpDetectMET( SvStream& rStm, bool bExtendedInfo );
171     bool            ImpDetectPCT( SvStream& rStm, bool bExtendedInfo );
172     bool            ImpDetectSVM( SvStream& rStm, bool bExtendedInfo );
173     bool            ImpDetectWMF( SvStream& rStm, bool bExtendedInfo );
174     bool            ImpDetectEMF( SvStream& rStm, bool bExtendedInfo );
175     bool            ImpDetectSVG( SvStream& rStm, bool bExtendedInfo );
176     GraphicDescriptor( const GraphicDescriptor& ) = delete;
177     GraphicDescriptor& operator=( const GraphicDescriptor& ) = delete;
178 
179 public:
180 
181     /** Ctor to set a filename
182 
183         Detect() must be called to identify the file
184         If the file has no unique header (Mtf's), the format
185         is determined from the extension */
186     GraphicDescriptor( const INetURLObject& rPath );
187 
188     /** Ctor using a stream
189 
190         Detect() must be called to identify the file
191         As some formats (Mtf's) do not have a unique header, it makes sense
192         to supply the file name (incl. ext.), so that the format can be
193         derived from the extension */
194     GraphicDescriptor( SvStream& rInStream, const OUString* pPath );
195 
196     ~GraphicDescriptor();
197 
198     /** starts the detection
199 
200         if bExtendedInfo == true the file header is used to derive
201         as many properties as possible (size, color, etc.) */
202     bool    Detect( bool bExtendedInfo = false );
203 
204     /** @return the file format, GraphicFileFormat::NOT if no format was recognized */
GetFileFormat() const205     GraphicFileFormat  GetFileFormat() const { return nFormat; }
206 
207     /** @return graphic size in pixels or 0 size */
GetSizePixel() const208     const Size&     GetSizePixel() const { return aPixSize; }
209 
210     /** @return the logical graphic size in 1/100mm or 0 size */
GetSize_100TH_MM() const211     const Size&     GetSize_100TH_MM() const { return aLogSize; }
212 
213     /** @return bits/pixel or 0 **/
GetBitsPerPixel() const214     sal_uInt16          GetBitsPerPixel() const { return nBitsPerPixel; }
215 
216     /** @return number of color channels */
GetNumberOfImageComponents() const217     sal_uInt8 GetNumberOfImageComponents() const { return mnNumberOfImageComponents; }
218 
219     /** @return whether image supports transparency */
IsTransparent() const220     bool IsTransparent() const { return bIsTransparent; }
221 
222     /** @return whether image supports alpha values for translucent colours */
IsAlpha() const223     bool IsAlpha() const { return bIsAlpha; }
224 
225     /** @return filter number that is needed by the GraphFilter to read this format */
226     static OUString GetImportFormatShortName( GraphicFileFormat nFormat );
227 };
228 
229 /** Information about errors during the GraphicFilter operation. */
230 struct FilterErrorEx
231 {
232     ErrCode   nStreamError;
233 
FilterErrorExFilterErrorEx234     FilterErrorEx() : nStreamError( ERRCODE_NONE ) {}
235 };
236 
237 /** Class to import and export graphic formats. */
238 class VCL_DLLPUBLIC GraphicFilter
239 {
240 public:
241                     GraphicFilter( bool bUseConfig = true );
242                     ~GraphicFilter();
243 
244     sal_uInt16      GetImportFormatCount() const;
245     sal_uInt16      GetImportFormatNumber( const OUString& rFormatName );
246     sal_uInt16      GetImportFormatNumberForShortName( const OUString& rShortName );
247     sal_uInt16      GetImportFormatNumberForTypeName( const OUString& rType );
248     OUString        GetImportFormatName( sal_uInt16 nFormat );
249     OUString        GetImportFormatTypeName( sal_uInt16 nFormat );
250 #ifdef _WIN32
251     OUString        GetImportFormatMediaType( sal_uInt16 nFormat );
252 #endif
253     OUString        GetImportFormatShortName( sal_uInt16 nFormat );
254     OUString        GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry );
255 
256     sal_uInt16      GetExportFormatCount() const;
257     sal_uInt16      GetExportFormatNumber( const OUString& rFormatName );
258     sal_uInt16      GetExportFormatNumberForMediaType( const OUString& rShortName );
259     sal_uInt16      GetExportFormatNumberForShortName( const OUString& rShortName );
260     OUString        GetExportInternalFilterName( sal_uInt16 nFormat );
261     sal_uInt16      GetExportFormatNumberForTypeName( const OUString& rType );
262     OUString        GetExportFormatName( sal_uInt16 nFormat );
263     OUString        GetExportFormatMediaType( sal_uInt16 nFormat );
264     OUString        GetExportFormatShortName( sal_uInt16 nFormat );
265     OUString        GetExportWildcard( sal_uInt16 nFormat );
266     bool            IsExportPixelFormat( sal_uInt16 nFormat );
267 
268     ErrCode             ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
269                                        sal_uInt16 nFormat,
270                                        const css::uno::Sequence< css::beans::PropertyValue >* pFilterData = nullptr );
271     ErrCode             ExportGraphic( const Graphic& rGraphic, const OUString& rPath,
272                                        SvStream& rOStm, sal_uInt16 nFormat,
273                                        const css::uno::Sequence< css::beans::PropertyValue >* pFilterData = nullptr );
274 
275     ErrCode             CanImportGraphic( const INetURLObject& rPath,
276                                       sal_uInt16 nFormat,
277                                       sal_uInt16 * pDeterminedFormat);
278 
279     ErrCode             ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
280                                    sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW,
281                                    sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE );
282 
283     ErrCode             CanImportGraphic( const OUString& rPath, SvStream& rStream,
284                                       sal_uInt16 nFormat,
285                                       sal_uInt16 * pDeterminedFormat);
286 
287     ErrCode             ImportGraphic( Graphic& rGraphic, const OUString& rPath,
288                                    SvStream& rStream,
289                                    sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW,
290                                    sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE,
291                                    WmfExternal const *pExtHeader = nullptr );
292 
293     /// Imports multiple graphics.
294     ///
295     /// The resulting graphic is added to rGraphics on success, nullptr is added on failure.
296     void ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGraphics, std::vector< std::unique_ptr<SvStream> > vStreams);
297 
298     ErrCode             ImportGraphic( Graphic& rGraphic, const OUString& rPath,
299                                    SvStream& rStream,
300                                    sal_uInt16 nFormat,
301                                    sal_uInt16 * pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
302                                    const css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
303                                    WmfExternal const *pExtHeader = nullptr );
304 
305     // Setting sizeLimit limits how much will be read from the stream.
306     Graphic ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 sizeLimit = 0, const Size* pSizeHint = nullptr);
307 
GetLastError() const308     const FilterErrorEx&    GetLastError() const { return *pErrorEx;}
309     void                    ResetLastError();
310 
311     Link<ConvertData&,bool> GetFilterCallback() const;
312     static GraphicFilter& GetGraphicFilter();
313     static ErrCode  LoadGraphic( const OUString& rPath, const OUString& rFilter,
314                      Graphic& rGraphic,
315                      GraphicFilter* pFilter = nullptr,
316                      sal_uInt16* pDeterminedFormat = nullptr );
317 
318     ErrCode         compressAsPNG(const Graphic& rGraphic, SvStream& rOutputStream);
319 
320     void preload();
321 
322 private:
323     OUString        aFilterPath;
324     FilterConfigCache*  pConfig;
325 
326     void            ImplInit();
327     ErrCode         ImplSetError( ErrCode nError, const SvStream* pStm = nullptr );
328     ErrCode         ImpTestOrFindFormat( const OUString& rPath, SvStream& rStream, sal_uInt16& rFormat );
329 
330                     DECL_LINK( FilterCallback, ConvertData&, bool );
331 
332     std::unique_ptr<FilterErrorEx> pErrorEx;
333     bool const                     bUseConfig;
334 };
335 
336 #endif // INCLUDED_VCL_GRAPHICFILTER_HXX
337 
338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
339