Branch data Line data Source code
1 : : /* ************************************************************************** 2 : : qgscontrastenhancement.h - description 3 : : ------------------- 4 : : begin : Mon Oct 22 2007 5 : : copyright : (C) 2007 by Peter J. Ersts 6 : : email : ersts@amnh.org 7 : : 8 : : This class contains code that was originally part of the larger QgsRasterLayer 9 : : class originally created circa 2004 by T.Sutton, Gary E.Sherman, Steve Halasz 10 : : ****************************************************************************/ 11 : : 12 : : /* ************************************************************************** 13 : : * * 14 : : * This program is free software; you can redistribute it and/or modify * 15 : : * it under the terms of the GNU General Public License as published by * 16 : : * the Free Software Foundation; either version 2 of the License, or * 17 : : * (at your option) any later version. * 18 : : * * 19 : : ***************************************************************************/ 20 : : 21 : : #ifndef QGSCONTRASTENHANCEMENT_H 22 : : #define QGSCONTRASTENHANCEMENT_H 23 : : 24 : : #include "qgis_core.h" 25 : : #include <limits> 26 : : 27 : : #include "qgis_sip.h" 28 : : #include "qgsraster.h" 29 : : #include <memory> 30 : : 31 : : class QgsContrastEnhancementFunction; 32 : : class QDomDocument; 33 : : class QDomElement; 34 : : class QString; 35 : : 36 : : /** 37 : : * \ingroup core 38 : : * \brief Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a 39 : : * specified numerical range according to the specified 40 : : * ContrastEnhancementAlgorithm. 41 : : */ 42 : : class CORE_EXPORT QgsContrastEnhancement 43 : : { 44 : : 45 : : public: 46 : : 47 : : //! \brief This enumerator describes the types of contrast enhancement algorithms that can be used. 48 : : enum ContrastEnhancementAlgorithm 49 : : { 50 : : NoEnhancement, //!< Default color scaling algorithm, no scaling is applied 51 : : StretchToMinimumMaximum, //!< Linear histogram 52 : : StretchAndClipToMinimumMaximum, 53 : : ClipToMinimumMaximum, 54 : : UserDefinedEnhancement 55 : : }; 56 : : 57 : : QgsContrastEnhancement( Qgis::DataType datatype = Qgis::Byte ); 58 : : QgsContrastEnhancement( const QgsContrastEnhancement &ce ); 59 : : ~QgsContrastEnhancement(); 60 : : 61 : : const QgsContrastEnhancement &operator=( const QgsContrastEnhancement & ) = delete; 62 : : 63 : : /** 64 : : * Helper function that returns the maximum possible value for a data type. 65 : : */ 66 : 0 : static double maximumValuePossible( Qgis::DataType dataType ) 67 : : { 68 : 0 : switch ( dataType ) 69 : : { 70 : : case Qgis::Byte: 71 : 0 : return std::numeric_limits<unsigned char>::max(); 72 : : case Qgis::UInt16: 73 : 0 : return std::numeric_limits<unsigned short>::max(); 74 : : case Qgis::Int16: 75 : 0 : return std::numeric_limits<short>::max(); 76 : : case Qgis::UInt32: 77 : 0 : return std::numeric_limits<unsigned int>::max(); 78 : : case Qgis::Int32: 79 : 0 : return std::numeric_limits<int>::max(); 80 : : case Qgis::Float32: 81 : 0 : return std::numeric_limits<float>::max(); 82 : : case Qgis::Float64: 83 : 0 : return std::numeric_limits<double>::max(); 84 : : case Qgis::CInt16: 85 : 0 : return std::numeric_limits<short>::max(); 86 : : case Qgis::CInt32: 87 : 0 : return std::numeric_limits<int>::max(); 88 : : case Qgis::CFloat32: 89 : 0 : return std::numeric_limits<float>::max(); 90 : : case Qgis::CFloat64: 91 : 0 : return std::numeric_limits<double>::max(); 92 : : case Qgis::ARGB32: 93 : : case Qgis::ARGB32_Premultiplied: 94 : : case Qgis::UnknownDataType: 95 : : // XXX - mloskot: not handled? 96 : 0 : break; 97 : : } 98 : : 99 : 0 : return std::numeric_limits<double>::max(); 100 : 0 : } 101 : : 102 : : /** 103 : : * Helper function that returns the minimum possible value for a data type. 104 : : */ 105 : 0 : static double minimumValuePossible( Qgis::DataType dataType ) 106 : : { 107 : 0 : switch ( dataType ) 108 : : { 109 : : case Qgis::Byte: 110 : 0 : return std::numeric_limits<unsigned char>::min(); 111 : : case Qgis::UInt16: 112 : 0 : return std::numeric_limits<unsigned short>::min(); 113 : : case Qgis::Int16: 114 : 0 : return std::numeric_limits<short>::min(); 115 : : case Qgis::UInt32: 116 : 0 : return std::numeric_limits<unsigned int>::min(); 117 : : case Qgis::Int32: 118 : 0 : return std::numeric_limits<int>::min(); 119 : : case Qgis::Float32: 120 : 0 : return std::numeric_limits<float>::max() * -1.0; 121 : : case Qgis::Float64: 122 : 0 : return std::numeric_limits<double>::max() * -1.0; 123 : : case Qgis::CInt16: 124 : 0 : return std::numeric_limits<short>::min(); 125 : : case Qgis::CInt32: 126 : 0 : return std::numeric_limits<int>::min(); 127 : : case Qgis::CFloat32: 128 : 0 : return std::numeric_limits<float>::max() * -1.0; 129 : : case Qgis::CFloat64: 130 : 0 : return std::numeric_limits<double>::max() * -1.0; 131 : : case Qgis::ARGB32: 132 : : case Qgis::ARGB32_Premultiplied: 133 : : case Qgis::UnknownDataType: 134 : : // XXX - mloskot: not handled? 135 : 0 : break; 136 : : } 137 : : 138 : 0 : return std::numeric_limits<double>::max() * -1.0; 139 : 0 : } 140 : : 141 : : /** 142 : : * Returns a string to serialize ContrastEnhancementAlgorithm. 143 : : */ 144 : : static QString contrastEnhancementAlgorithmString( ContrastEnhancementAlgorithm algorithm ); 145 : : 146 : : /** 147 : : * Deserialize ContrastEnhancementAlgorithm. 148 : : */ 149 : : static ContrastEnhancementAlgorithm contrastEnhancementAlgorithmFromString( const QString &contrastEnhancementString ); 150 : : 151 : : //! Returns the maximum value for the contrast enhancement range. 152 : 0 : double maximumValue() const { return mMaximumValue; } 153 : : 154 : : //! Returns the minimum value for the contrast enhancement range. 155 : 0 : double minimumValue() const { return mMinimumValue; } 156 : : 157 : 0 : ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const { return mContrastEnhancementAlgorithm; } 158 : : 159 : : /** 160 : : * Applies the contrast enhancement to a \a value. Return values are 0 - 254, -1 means the pixel was clipped and should not be displayed. 161 : : */ 162 : : int enhanceContrast( double value ); 163 : : 164 : : /** 165 : : * Returns TRUE if a pixel \a value is in displayable range, FALSE if pixel 166 : : * is outside of range (i.e. clipped). 167 : : */ 168 : : bool isValueInDisplayableRange( double value ); 169 : : 170 : : /** 171 : : * Sets the contrast enhancement \a algorithm. 172 : : * 173 : : * The \a generateTable parameter is optional and is for performance improvements. 174 : : * If you know you are immediately going to set the Minimum or Maximum value, you 175 : : * can elect to not generate the lookup tale. By default it will be generated. 176 : : */ 177 : : void setContrastEnhancementAlgorithm( ContrastEnhancementAlgorithm algorithm, bool generateTable = true ); 178 : : 179 : : /** 180 : : * Allows the user to set their own custom contrast enhancement \a function. Ownership of 181 : : * \a function is transferred. 182 : : */ 183 : : void setContrastEnhancementFunction( QgsContrastEnhancementFunction *function SIP_TRANSFER ); 184 : : 185 : : /** 186 : : * Sets the maximum \a value for the contrast enhancement range. 187 : : * 188 : : * The \a generateTable parameter is optional and is for performance improvements. 189 : : * If you know you are immediately going to set the minimum value or the contrast 190 : : * enhancement algorithm, you can elect to not generate the lookup table. 191 : : * By default it will be generated. 192 : : * 193 : : * \see setMinimumValue() 194 : : */ 195 : : void setMaximumValue( double value, bool generateTable = true ); 196 : : 197 : : /** 198 : : * Sets the minimum \a value for the contrast enhancement range. 199 : : * 200 : : * The \a generateTable parameter is optional and is for performance improvements. 201 : : * If you know you are immediately going to set the maximum value or the contrast 202 : : * enhancement algorithm, you can elect to not generate the lookup table. 203 : : * By default it will be generated. 204 : : * 205 : : * \see setMaximumValue() 206 : : */ 207 : : void setMinimumValue( double value, bool generateTable = true ); 208 : : 209 : : void writeXml( QDomDocument &doc, QDomElement &parentElem ) const; 210 : : 211 : : void readXml( const QDomElement &elem ); 212 : : 213 : : /** 214 : : * Write ContrastEnhancement tags following SLD v1.0 specs 215 : : * SLD1.0 is limited to the parameters listed in: 216 : : * https://docs.geoserver.org/stable/en/user/styling/sld/reference/rastersymbolizer.html#contrastenhancement 217 : : * Btw only sld:Normalize + vendor options are supported because there is no clear mapping 218 : : * of ContrastEnhancement parameters to support sld:Histogram or sld:GammaValue 219 : : * \since QGIS 3.6 220 : : */ 221 : : void toSld( QDomDocument &doc, QDomElement &element ) const; 222 : : 223 : : private: 224 : : #ifdef SIP_RUN 225 : : const QgsContrastEnhancement &operator=( const QgsContrastEnhancement & ); 226 : : #endif 227 : : 228 : : //! \brief Current contrast enhancement algorithm 229 : : ContrastEnhancementAlgorithm mContrastEnhancementAlgorithm = NoEnhancement; 230 : : 231 : : //! \brief Pointer to the contrast enhancement function 232 : : std::unique_ptr< QgsContrastEnhancementFunction > mContrastEnhancementFunction; 233 : : 234 : : //! \brief Flag indicating if the lookup table needs to be regenerated 235 : : bool mEnhancementDirty = false; 236 : : 237 : : //! \brief Pointer to the lookup table 238 : : int *mLookupTable = nullptr; 239 : : 240 : : //! \brief User defineable minimum value for the band, used for enhanceContrasting 241 : : double mMinimumValue; 242 : : 243 : : //! \brief user defineable maximum value for the band, used for enhanceContrasting 244 : : double mMaximumValue; 245 : : 246 : : //! \brief Data type of the band 247 : : Qgis::DataType mRasterDataType; 248 : : 249 : : //! \brief Maximum range of values for a given data type 250 : : double mRasterDataTypeRange; 251 : : 252 : : //! \brief Scalar so that values can be used as array indices 253 : : double mLookupTableOffset; 254 : : 255 : : //! Generates a new lookup table 256 : : bool generateLookupTable(); 257 : : 258 : : //! \brief Method to calculate the actual enhanceContrasted value(s) 259 : : int calculateContrastEnhancementValue( double ); 260 : : 261 : : }; 262 : : 263 : : #endif