1 /***************************************************************************
2     qgsrasterpipe.h - Internal raster processing modules interface
3      --------------------------------------
4     Date                 : Jun 21, 2012
5     Copyright            : (C) 2012 by Radim Blazek
6     email                : radim dot blazek at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef QGSRASTERPIPE_H
19 #define QGSRASTERPIPE_H
20 
21 #include "qgis_core.h"
22 #include "qgis_sip.h"
23 #include <QImage>
24 #include <QMap>
25 #include <QObject>
26 
27 class QgsRasterInterface;
28 class QgsRasterRenderer;
29 class QgsRasterResampleFilter;
30 class QgsBrightnessContrastFilter;
31 class QgsHueSaturationFilter;
32 class QgsRasterProjector;
33 class QgsRasterNuller;
34 class QgsRasterResampleFilter;
35 class QgsContrastEnhancement;
36 class QgsRasterDataProvider;
37 
38 #if defined(Q_OS_WIN)
39 #undef interface
40 #endif
41 
42 /**
43  * \ingroup core
44  * \brief Base class for processing modules.
45  */
46 class CORE_EXPORT QgsRasterPipe
47 {
48   public:
49     // Role of known interfaces
50     enum Role
51     {
52       UnknownRole   = 0,
53       ProviderRole  = 1,
54       RendererRole  = 2,
55       BrightnessRole = 3,
56       ResamplerRole = 4,
57       ProjectorRole = 5,
58       NullerRole = 6,
59       HueSaturationRole = 7,
60     };
61 
62     /**
63      * Constructor for QgsRasterPipe.
64      */
65     QgsRasterPipe() = default;
66 
67     QgsRasterPipe( const QgsRasterPipe &pipe ) SIP_SKIP;
68 
69     ~QgsRasterPipe();
70 
71     QgsRasterPipe &operator=( const QgsRasterPipe &rh ) = delete;
72 
73     /**
74      * Try to insert interface at specified index and connect
75      * if connection would fail, the interface is not inserted and FALSE is returned
76     */
77     bool insert( int idx, QgsRasterInterface *interface SIP_TRANSFER );
78 #ifdef SIP_RUN
79     % MethodCode
80     sipRes = sipCpp->insert( a0, a1 );
81     if ( !sipRes )
82     {
83       // if insertion failed transfer ownership back to python
84       PyObject *o = sipGetPyObject( a1, sipType_QgsRasterInterface );
85       if ( o )
86         sipTransferTo( o, NULL );
87     }
88     % End
89 #endif
90 
91     /**
92      * Try to replace interface at specified index and connect
93      * if connection would fail, the interface is not inserted and FALSE is returned
94     */
95     bool replace( int idx, QgsRasterInterface *interface SIP_TRANSFER );
96 
97     /**
98      * Insert a new known interface in default place or replace interface of the same
99      * role if it already exists. Known interfaces are: QgsRasterDataProvider,
100      * QgsRasterRenderer, QgsRasterResampleFilter, QgsRasterProjector and their
101      * subclasses. For unknown interfaces it mus be explicitly specified position
102      * where it should be inserted using insert() method.
103      */
104     bool set( QgsRasterInterface *interface SIP_TRANSFER );
105 
106     //! Remove and delete interface at given index if possible
107     bool remove( int idx );
108 
109     //! Remove and delete interface from pipe if possible
110     bool remove( QgsRasterInterface *interface );
111 
size()112     int size() const { return mInterfaces.size(); }
at(int idx)113     QgsRasterInterface *at( int idx ) const { return mInterfaces.at( idx ); }
last()114     QgsRasterInterface *last() const { return mInterfaces.last(); }
115 
116     /**
117      * Set interface at index on/off
118      *  Returns TRUE on success
119     */
120     bool setOn( int idx, bool on );
121 
122     //! Test if interface at index may be switched on/off
123     bool canSetOn( int idx, bool on );
124 
125     // Getters for special types of interfaces
126     QgsRasterDataProvider *provider() const;
127     QgsRasterRenderer *renderer() const;
128     QgsRasterResampleFilter *resampleFilter() const;
129     QgsBrightnessContrastFilter *brightnessFilter() const;
130     QgsHueSaturationFilter *hueSaturationFilter() const;
131     QgsRasterProjector *projector() const;
132     QgsRasterNuller *nuller() const;
133 
134     /**
135      * Stage at which resampling occurs.
136      * \since QGIS 3.16
137      */
138     enum class ResamplingStage
139     {
140       //! Resampling occurs in ResamplingFilter
141       ResampleFilter,
142       //! Resampling occurs in Provider
143       Provider
144     };
145 
146     /**
147      * Select which stage of the pipe should apply resampling.
148      *
149      * Provider resampling is only supported if provider sets
150      * ProviderHintCanPerformProviderResampling in providerCapabilities().
151      *
152      * \since QGIS 3.16
153      */
154     void setResamplingStage( ResamplingStage stage );
155 
156     /**
157      * Returns which stage of the pipe should apply resampling
158      * \since QGIS 3.16
159      */
resamplingStage()160     ResamplingStage resamplingStage() const { return mResamplingStage; }
161 
162   private:
163 #ifdef SIP_RUN
164     QgsRasterPipe( const QgsRasterPipe &pipe );
165 #endif
166 
167     //! Gets known parent type_info of interface parent
168     Role interfaceRole( QgsRasterInterface *iface ) const;
169 
170     // Interfaces in pipe, the first is always provider
171     QVector<QgsRasterInterface *> mInterfaces;
172 
173     QMap<Role, int> mRoleMap;
174 
175     // Set role in mRoleMap
176     void setRole( QgsRasterInterface *interface, int idx );
177 
178     // Unset role in mRoleMap
179     void unsetRole( QgsRasterInterface *interface );
180 
181     // Check if index is in bounds
182     bool checkBounds( int idx ) const;
183 
184     //! Gets known interface by role
185     QgsRasterInterface *interface( Role role ) const;
186 
187     /**
188      * \brief Try to connect interfaces in pipe and to the provider at beginning.
189         Returns true if connected or false if connection failed
190     */
191     bool connect( QVector<QgsRasterInterface *> interfaces );
192 
193     ResamplingStage mResamplingStage = ResamplingStage::ResampleFilter;
194 };
195 
196 #endif
197 
198 
199