1 /******************************************************************************
2  * $Id: gdalpansharpen.h 8ca42e1b9c2e54b75d35e49885df9789a2643aa4 2020-05-17 21:43:40 +0200 Even Rouault $
3  *
4  * Project:  GDAL Pansharpening module
5  * Purpose:  Prototypes, and definitions for pansharpening related work.
6  * Author:   Even Rouault <even.rouault at spatialys.com>
7  *
8  ******************************************************************************
9  * Copyright (c) 2015, Even Rouault <even.rouault at spatialys.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #ifndef GDALPANSHARPEN_H_INCLUDED
31 #define GDALPANSHARPEN_H_INCLUDED
32 
33 #include "gdal.h"
34 
35 CPL_C_START
36 
37 /**
38  * \file gdalpansharpen.h
39  *
40  * GDAL pansharpening related entry points and definitions.
41  *
42  * @since GDAL 2.1
43  */
44 
45 /** Pansharpening algorithms.
46  */
47 typedef enum
48 {
49     /*! Weighted Brovery. */
50     GDAL_PSH_WEIGHTED_BROVEY
51 } GDALPansharpenAlg;
52 
53 /** Pansharpening options.
54   */
55 typedef struct
56 {
57     /*! Pan sharpening algorithm/method. Only weighed Brovey for now. */
58     GDALPansharpenAlg    ePansharpenAlg;
59 
60     /*! Resampling algorithm to upsample spectral bands to pan band resolution. */
61     GDALRIOResampleAlg   eResampleAlg;
62 
63     /*! Bit depth of the spectral bands. Can be let to 0 for default behavior. */
64     int                  nBitDepth;
65 
66     /*! Number of weight coefficients in padfWeights. */
67     int                  nWeightCount;
68 
69     /*! Array of nWeightCount weights used by weighted Brovey. */
70     double              *padfWeights;
71 
72     /*! Panchromatic band. */
73     GDALRasterBandH      hPanchroBand;
74 
75     /*! Number of input spectral bands. */
76     int                  nInputSpectralBands;
77 
78     /** Array of nInputSpectralBands input spectral bands. The spectral band have
79      *  generally a coarser resolution than the panchromatic band, but they
80      *  are assumed to have the same spatial extent (and projection) at that point.
81      *  Necessary spatial adjustments must be done beforehand, for example by wrapping
82      *  inside a VRT dataset.
83      */
84     GDALRasterBandH     *pahInputSpectralBands;
85 
86     /*! Number of output pansharpened spectral bands. */
87     int                  nOutPansharpenedBands;
88 
89     /*! Array of nOutPansharpendBands values such as panOutPansharpenedBands[k] is a value in the range [0,nInputSpectralBands-1] . */
90     int                 *panOutPansharpenedBands;
91 
92     /*! Whether the panchromatic and spectral bands have a noData value. */
93     int                  bHasNoData;
94 
95     /** NoData value of the panchromatic and spectral bands (only taken into account if bHasNoData = TRUE).
96         This will also be use has the output nodata value. */
97     double               dfNoData;
98 
99     /** Number of threads or -1 to mean ALL_CPUS. By default (0), single threaded mode is enabled
100       * unless the GDAL_NUM_THREADS configuration option is set to an integer or ALL_CPUS. */
101     int                  nThreads;
102 
103     /** Shift in pixels of multispectral bands w.r.t panchromatic band, in X direction */
104     double               dfMSShiftX;
105 
106     /** Shift in pixels of multispectral bands w.r.t panchromatic band, in Y direction */
107     double               dfMSShiftY;
108 
109 } GDALPansharpenOptions;
110 
111 GDALPansharpenOptions CPL_DLL * GDALCreatePansharpenOptions(void);
112 void CPL_DLL GDALDestroyPansharpenOptions( GDALPansharpenOptions * );
113 GDALPansharpenOptions CPL_DLL * GDALClonePansharpenOptions(
114                                         const GDALPansharpenOptions* psOptions);
115 
116 /*! Pansharpening operation handle. */
117 typedef void* GDALPansharpenOperationH;
118 
119 GDALPansharpenOperationH CPL_DLL GDALCreatePansharpenOperation(const GDALPansharpenOptions* );
120 void CPL_DLL GDALDestroyPansharpenOperation( GDALPansharpenOperationH );
121 CPLErr CPL_DLL GDALPansharpenProcessRegion( GDALPansharpenOperationH hOperation,
122                                             int nXOff, int nYOff,
123                                             int nXSize, int nYSize,
124                                             void *pDataBuf,
125                                             GDALDataType eBufDataType);
126 
127 CPL_C_END
128 
129 #ifdef __cplusplus
130 
131 #include <vector>
132 #include "gdal_priv.h"
133 #include "cpl_worker_thread_pool.h"
134 
135 #ifdef DEBUG_TIMING
136 #include <sys/time.h>
137 #endif
138 
139 class GDALPansharpenOperation;
140 
141 //! @cond Doxygen_Suppress
142 typedef struct
143 {
144     GDALPansharpenOperation* poPansharpenOperation;
145     GDALDataType eWorkDataType;
146     GDALDataType eBufDataType;
147     const void* pPanBuffer;
148     const void* pUpsampledSpectralBuffer;
149     void* pDataBuf;
150     size_t nValues;
151     size_t nBandValues;
152     GUInt32 nMaxValue;
153 
154 #ifdef DEBUG_TIMING
155     struct timeval* ptv;
156 #endif
157 
158     CPLErr eErr;
159 } GDALPansharpenJob;
160 
161 typedef struct
162 {
163     GDALDataset* poMEMDS;
164     int          nXOff;
165     int          nYOff;
166     int          nXSize;
167     int          nYSize;
168     double       dfXOff;
169     double       dfYOff;
170     double       dfXSize;
171     double       dfYSize;
172     void        *pBuffer;
173     GDALDataType eDT;
174     int          nBufXSize;
175     int          nBufYSize;
176     int          nBandCount;
177     GDALRIOResampleAlg eResampleAlg;
178     GSpacing     nBandSpace;
179 
180 #ifdef DEBUG_TIMING
181     struct timeval* ptv;
182 #endif
183 } GDALPansharpenResampleJob;
184 //! @endcond
185 
186 /** Pansharpening operation class.
187  */
188 class GDALPansharpenOperation
189 {
190         CPL_DISALLOW_COPY_ASSIGN(GDALPansharpenOperation)
191 
192         GDALPansharpenOptions* psOptions = nullptr;
193         std::vector<int> anInputBands{};
194         std::vector<GDALDataset*> aVDS{}; // to destroy
195         std::vector<GDALRasterBand*> aMSBands{}; // original multispectral bands potentially warped into a VRT
196         int bPositiveWeights = TRUE;
197         CPLWorkerThreadPool* poThreadPool = nullptr;
198         int nKernelRadius = 0;
199 
200         static void PansharpenJobThreadFunc(void* pUserData);
201         static void PansharpenResampleJobThreadFunc(void* pUserData);
202 
203         template<class WorkDataType, class OutDataType> void WeightedBroveyWithNoData(
204                                                      const WorkDataType* pPanBuffer,
205                                                      const WorkDataType* pUpsampledSpectralBuffer,
206                                                      OutDataType* pDataBuf,
207                                                      size_t nValues,
208                                                      size_t nBandValues,
209                                                      WorkDataType nMaxValue) const;
210         template<class WorkDataType, class OutDataType, int bHasBitDepth> void WeightedBrovey3(
211                                                      const WorkDataType* pPanBuffer,
212                                                      const WorkDataType* pUpsampledSpectralBuffer,
213                                                      OutDataType* pDataBuf,
214                                                      size_t nValues,
215                                                      size_t nBandValues,
216                                                      WorkDataType nMaxValue) const;
217 
218         // cppcheck-suppress functionStatic
219         template<class WorkDataType, class OutDataType> void WeightedBrovey(
220                                                      const WorkDataType* pPanBuffer,
221                                                      const WorkDataType* pUpsampledSpectralBuffer,
222                                                      OutDataType* pDataBuf,
223                                                      size_t nValues,
224                                                      size_t nBandValues,
225                                                      WorkDataType nMaxValue) const;
226         template<class WorkDataType> CPLErr WeightedBrovey(
227                                                      const WorkDataType* pPanBuffer,
228                                                      const WorkDataType* pUpsampledSpectralBuffer,
229                                                      void *pDataBuf,
230                                                      GDALDataType eBufDataType,
231                                                      size_t nValues,
232                                                      size_t nBandValues,
233                                                      WorkDataType nMaxValue) const;
234 
235         // cppcheck-suppress functionStatic
236         template<class WorkDataType> CPLErr WeightedBrovey(
237                                                      const WorkDataType* pPanBuffer,
238                                                      const WorkDataType* pUpsampledSpectralBuffer,
239                                                      void *pDataBuf,
240                                                      GDALDataType eBufDataType,
241                                                      size_t nValues,
242                                                      size_t nBandValues) const;
243         template<class T> void WeightedBroveyPositiveWeights(
244                                                      const T* pPanBuffer,
245                                                      const T* pUpsampledSpectralBuffer,
246                                                      T* pDataBuf,
247                                                      size_t nValues,
248                                                      size_t nBandValues,
249                                                      T nMaxValue) const;
250 
251         template<class T, int NINPUT, int NOUTPUT> size_t WeightedBroveyPositiveWeightsInternal(
252                                                      const T* pPanBuffer,
253                                                      const T* pUpsampledSpectralBuffer,
254                                                      T* pDataBuf,
255                                                      size_t nValues,
256                                                      size_t nBandValues,
257                                                      T nMaxValue) const;
258 
259         // cppcheck-suppress unusedPrivateFunction
260         template<class T> void WeightedBroveyGByteOrUInt16(
261                                                      const T* pPanBuffer,
262                                                      const T* pUpsampledSpectralBuffer,
263                                                      T* pDataBuf,
264                                                      size_t nValues,
265                                                      size_t nBandValues,
266                                                      T nMaxValue ) const;
267 
268         // cppcheck-suppress functionStatic
269         CPLErr PansharpenChunk( GDALDataType eWorkDataType, GDALDataType eBufDataType,
270                                                      const void* pPanBuffer,
271                                                      const void* pUpsampledSpectralBuffer,
272                                                      void* pDataBuf,
273                                                      size_t nValues,
274                                                      size_t nBandValues,
275                                                      GUInt32 nMaxValue) const;
276     public:
277                              GDALPansharpenOperation();
278                             ~GDALPansharpenOperation();
279 
280         CPLErr               Initialize(const GDALPansharpenOptions* psOptions);
281         CPLErr               ProcessRegion(int nXOff, int nYOff,
282                                            int nXSize, int nYSize,
283                                            void *pDataBuf,
284                                            GDALDataType eBufDataType);
285         GDALPansharpenOptions* GetOptions();
286 };
287 
288 #endif /* __cplusplus */
289 
290 #endif /* GDALPANSHARPEN_H_INCLUDED */
291