00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "qgslogger.h"
00022
00023 #include "qgscontrastenhancement.h"
00024 #include "qgscontrastenhancementfunction.h"
00025 #include "qgslinearminmaxenhancement.h"
00026 #include "qgslinearminmaxenhancementwithclip.h"
00027 #include "qgscliptominmaxenhancement.h"
00028
00029 QgsContrastEnhancement::QgsContrastEnhancement( QgsRasterDataType theDataType )
00030 {
00031 mLookupTable = 0;
00032 mContrastEnhancementFunction = 0;
00033 mEnhancementDirty = false;
00034 mContrastEnhancementAlgorithm = NoEnhancement;
00035 mRasterDataType = theDataType;
00036
00037 mMinimumValue = minimumValuePossible( mRasterDataType );
00038 mMaximumValue = maximumValuePossible( mRasterDataType );
00039 mRasterDataTypeRange = mMaximumValue - mMinimumValue;
00040
00041 mLookupTableOffset = mMinimumValue * -1;
00042
00043 mContrastEnhancementFunction = new QgsContrastEnhancementFunction( mRasterDataType, mMinimumValue, mMaximumValue );
00044
00045
00046 if ( mRasterDataTypeRange <= 65535.0 )
00047 {
00048 mLookupTable = new int[static_cast <int>( mRasterDataTypeRange+1 )];
00049 }
00050
00051 }
00052
00053 QgsContrastEnhancement::~QgsContrastEnhancement()
00054 {
00055 }
00056
00057
00058
00059
00060
00061
00065 double QgsContrastEnhancement::maximumValuePossible( QgsRasterDataType theDataType )
00066 {
00067 switch ( theDataType )
00068 {
00069 case QGS_Byte:
00070 return std::numeric_limits<unsigned char>::max();
00071 break;
00072 case QGS_UInt16:
00073 return std::numeric_limits<unsigned short>::max();
00074 break;
00075 case QGS_Int16:
00076 return std::numeric_limits<short>::max();
00077 break;
00078 case QGS_UInt32:
00079 return std::numeric_limits<unsigned int>::max();
00080 break;
00081 case QGS_Int32:
00082 return std::numeric_limits<int>::max();
00083 break;
00084 case QGS_Float32:
00085 return std::numeric_limits<float>::max();
00086 break;
00087 case QGS_Float64:
00088 return std::numeric_limits<double>::max();
00089 break;
00090 case QGS_CInt16:
00091 return std::numeric_limits<short>::max();
00092 break;
00093 case QGS_CInt32:
00094 return std::numeric_limits<int>::max();
00095 break;
00096 case QGS_CFloat32:
00097 return std::numeric_limits<float>::max();
00098 break;
00099 case QGS_CFloat64:
00100 return std::numeric_limits<double>::max();
00101 break;
00102 case QGS_Unknown:
00103 case QGS_TypeCount:
00104
00105 break;
00106 }
00107
00108 return std::numeric_limits<double>::max();
00109 }
00113 double QgsContrastEnhancement::minimumValuePossible( QgsRasterDataType theDataType )
00114 {
00115 switch ( theDataType )
00116 {
00117 case QGS_Byte:
00118 return std::numeric_limits<unsigned char>::min();
00119 break;
00120 case QGS_UInt16:
00121 return std::numeric_limits<unsigned short>::min();
00122 break;
00123 case QGS_Int16:
00124 return std::numeric_limits<short>::min();
00125 break;
00126 case QGS_UInt32:
00127 return std::numeric_limits<unsigned int>::min();
00128 break;
00129 case QGS_Int32:
00130 return std::numeric_limits<int>::min();
00131 break;
00132 case QGS_Float32:
00133 return std::numeric_limits<float>::max() * -1.0;
00134 break;
00135 case QGS_Float64:
00136 return std::numeric_limits<double>::max() * -1.0;
00137 break;
00138 case QGS_CInt16:
00139 return std::numeric_limits<short>::min();
00140 break;
00141 case QGS_CInt32:
00142 return std::numeric_limits<int>::min();
00143 break;
00144 case QGS_CFloat32:
00145 return std::numeric_limits<float>::max() * -1.0;
00146 break;
00147 case QGS_CFloat64:
00148 return std::numeric_limits<double>::max() * -1.0;
00149 break;
00150 case QGS_Unknown:
00151 case QGS_TypeCount:
00152
00153 break;
00154 }
00155
00156 return std::numeric_limits<double>::max() * -1.0;
00157 }
00158
00159
00160
00161
00162
00163
00169 int QgsContrastEnhancement::enhanceContrast( double theValue )
00170 {
00171 if ( mEnhancementDirty )
00172 {
00173 generateLookupTable();
00174 }
00175
00176 if ( mLookupTable && NoEnhancement != mContrastEnhancementAlgorithm )
00177 {
00178 return mLookupTable[static_cast <int>( theValue + mLookupTableOffset )];
00179 }
00180 else
00181 {
00182
00183
00184
00185 return mContrastEnhancementFunction->enhance( theValue );
00186 }
00187 }
00188
00192 bool QgsContrastEnhancement::generateLookupTable()
00193 {
00194 mEnhancementDirty = false;
00195
00196 if ( 0 == mContrastEnhancementFunction ) { return false; }
00197 if ( NoEnhancement == mContrastEnhancementAlgorithm ) { return false; }
00198 if ( QGS_Byte != mRasterDataType && QGS_UInt16 != mRasterDataType && QGS_Int16 != mRasterDataType ) { return false; }
00199 if ( !mLookupTable ) { return false; }
00200
00201 QgsDebugMsg( "building lookup table" );
00202 QgsDebugMsg( "***MinimumValue : " + QString::number( mMinimumValue ) );
00203 QgsDebugMsg( "***MaximumValue : " + QString::number( mMaximumValue ) );
00204 QgsDebugMsg( "***mLookupTableOffset : " + QString::number( mLookupTableOffset ) );
00205 QgsDebugMsg( "***mRasterDataTypeRange : " + QString::number( mRasterDataTypeRange ) );
00206
00207 for ( int myIterator = 0; myIterator <= mRasterDataTypeRange; myIterator++ )
00208 {
00209 mLookupTable[myIterator] = mContrastEnhancementFunction->enhance(( double )myIterator - mLookupTableOffset );
00210 }
00211
00212 return true;
00213 }
00214
00220 bool QgsContrastEnhancement::isValueInDisplayableRange( double theValue )
00221 {
00222
00223 if ( 0 != mContrastEnhancementFunction )
00224 {
00225 return mContrastEnhancementFunction->isValueInDisplayableRange( theValue );
00226 }
00227
00228 return false;
00229 }
00230
00237 void QgsContrastEnhancement::setContrastEnhancementAlgorithm( ContrastEnhancementAlgorithm theAlgorithm, bool generateTable )
00238 {
00239 QgsDebugMsg( "called algorithm: " + QString::number(( int )theAlgorithm ) + " generate lookup table: " + QString::number(( int )generateTable ) );
00240
00241 if ( theAlgorithm != mContrastEnhancementAlgorithm )
00242 {
00243 switch ( theAlgorithm )
00244 {
00245 case StretchToMinimumMaximum :
00246 mContrastEnhancementFunction = new QgsLinearMinMaxEnhancement( mRasterDataType, mMinimumValue, mMaximumValue );
00247 break;
00248 case StretchAndClipToMinimumMaximum :
00249 mContrastEnhancementFunction = new QgsLinearMinMaxEnhancementWithClip( mRasterDataType, mMinimumValue, mMaximumValue );
00250 break;
00251 case ClipToMinimumMaximum :
00252 mContrastEnhancementFunction = new QgsClipToMinMaxEnhancement( mRasterDataType, mMinimumValue, mMaximumValue );
00253 break;
00254 case UserDefinedEnhancement :
00255
00256 break;
00257 default:
00258 mContrastEnhancementFunction = new QgsContrastEnhancementFunction( mRasterDataType, mMinimumValue, mMaximumValue );
00259 break;
00260 }
00261
00262 mEnhancementDirty = true;
00263 mContrastEnhancementAlgorithm = theAlgorithm;
00264
00265 if ( generateTable )
00266 {
00267 generateLookupTable();
00268 }
00269 }
00270 }
00271
00277 void QgsContrastEnhancement::setContrastEnhancementFunction( QgsContrastEnhancementFunction* theFunction )
00278 {
00279 QgsDebugMsg( "called" );
00280
00281 if ( 0 != theFunction )
00282 {
00283 mContrastEnhancementFunction = theFunction;
00284 mContrastEnhancementAlgorithm = UserDefinedEnhancement;
00285 generateLookupTable();
00286 }
00287 }
00288
00295 void QgsContrastEnhancement::setMaximumValue( double theValue, bool generateTable )
00296 {
00297 QgsDebugMsg( "called value: " + QString::number( theValue ) + " generate lookup table: " + QString::number(( int )generateTable ) );
00298
00299 if ( theValue > maximumValuePossible( mRasterDataType ) )
00300 {
00301 mMaximumValue = maximumValuePossible( mRasterDataType );
00302 }
00303 else
00304 {
00305 mMaximumValue = theValue;
00306 }
00307
00308 if ( 0 != mContrastEnhancementFunction )
00309 {
00310 mContrastEnhancementFunction->setMaximumValue( theValue );
00311 }
00312
00313 mEnhancementDirty = true;
00314
00315 if ( generateTable )
00316 {
00317 generateLookupTable();
00318 }
00319 }
00320
00327 void QgsContrastEnhancement::setMinimumValue( double theValue, bool generateTable )
00328 {
00329 QgsDebugMsg( "called value: " + QString::number( theValue ) + " generate lookup table: " + QString::number(( int )generateTable ) );
00330
00331 if ( theValue < minimumValuePossible( mRasterDataType ) )
00332 {
00333 mMinimumValue = minimumValuePossible( mRasterDataType );
00334 }
00335 else
00336 {
00337 mMinimumValue = theValue;
00338 }
00339
00340 if ( 0 != mContrastEnhancementFunction )
00341 {
00342 mContrastEnhancementFunction->setMinimumValue( theValue );
00343 }
00344
00345 mEnhancementDirty = true;
00346
00347 if ( generateTable )
00348 {
00349 generateLookupTable();
00350 }
00351 }