64 changes: 64 additions & 0 deletions src/core/raster/qgsbrightnesscontrastfilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/***************************************************************************
qgsbrightnesscontrastfilter.h
-------------------
begin : February 2013
copyright : (C) 2013 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSBRIGHTNESSCONTRASTFILTER_H
#define QGSBRIGHTNESSCONTRASTFILTER_H

#include "qgsrasterdataprovider.h"
#include "qgsrasterinterface.h"

class QDomElement;

/** \ingroup core
* Brightness/contrast filter pipe for rasters.
*/
class CORE_EXPORT QgsBrightnessContrastFilter : public QgsRasterInterface
{
public:
QgsBrightnessContrastFilter( QgsRasterInterface *input = 0 );
~QgsBrightnessContrastFilter();

QgsRasterInterface * clone() const;

int bandCount() const;

QGis::DataType dataType( int bandNo ) const;

bool setInput( QgsRasterInterface* input );

QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height );

void setBrightness( int brightness ) { mBrightness = qBound( -255, brightness, 255 ); }
int brightness() const { return mBrightness; }

void setContrast( int contrast ) { mContrast = qBound( -255, contrast, 255 ); }
int contrast() const { return mContrast; }

void writeXML( QDomDocument& doc, QDomElement& parentElem );

/**Sets base class members from xml. Usually called from create() methods of subclasses*/
void readXML( const QDomElement& resamplefilterElem );

private:
/**Current brightness coefficient value. Default: 0. Range: -255...255*/
int mBrightness;

/**Current contrast coefficient value. Default: 0. Range: -255...255*/
int mContrast;
};

#endif // QGSBRIGHTNESSCONTRASTFILTER_H
22 changes: 22 additions & 0 deletions src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,10 @@ void QgsRasterLayer::setDataProvider( QString const & provider )
}
}

// brightness filter
QgsBrightnessContrastFilter * brightnessFilter = new QgsBrightnessContrastFilter();
mPipe.set( brightnessFilter );

//resampler (must be after renderer)
QgsRasterResampleFilter * resampleFilter = new QgsRasterResampleFilter();
mPipe.set( resampleFilter );
Expand Down Expand Up @@ -2286,6 +2290,17 @@ bool QgsRasterLayer::readSymbology( const QDomNode& layer_node, QString& errorMe
}
}

//brightness
QgsBrightnessContrastFilter * brightnessFilter = new QgsBrightnessContrastFilter();
mPipe.set( brightnessFilter );

//brightness coefficient
QDomElement brightnessElem = layer_node.firstChildElement( "brightnesscontrast" );
if ( !brightnessElem.isNull() )
{
brightnessFilter->readXML( brightnessElem );
}

//resampler
QgsRasterResampleFilter * resampleFilter = new QgsRasterResampleFilter();
mPipe.set( resampleFilter );
Expand Down Expand Up @@ -2470,6 +2485,13 @@ bool QgsRasterLayer::writeSymbology( QDomNode & layer_node, QDomDocument & docum
renderer->writeXML( document, layerElem );
}

QgsBrightnessContrastFilter *brightnessFilter = mPipe.brightnessFilter();
if ( brightnessFilter )
{
QDomElement layerElem = layer_node.toElement();
brightnessFilter->writeXML( document, layerElem );
}

QgsRasterResampleFilter *resampleFilter = mPipe.resampleFilter();
if ( resampleFilter )
{
Expand Down
3 changes: 3 additions & 0 deletions src/core/raster/qgsrasterlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "qgsrastershaderfunction.h"
#include "qgsrasterinterface.h"
#include "qgsrasterresamplefilter.h"
#include "qgsbrightnesscontrastfilter.h"
#include "qgsrasterdataprovider.h"
#include "qgsrasterpipe.h"

Expand Down Expand Up @@ -362,6 +363,8 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
//void setResampleFilter( QgsRasterResampleFilter* resampleFilter );
QgsRasterResampleFilter * resampleFilter() const { return mPipe.resampleFilter(); }

QgsBrightnessContrastFilter * brightnessFilter() const { return mPipe.brightnessFilter(); }

/** Get raster pipe */
QgsRasterPipe * pipe() { return &mPipe; }

Expand Down
15 changes: 13 additions & 2 deletions src/core/raster/qgsrasterpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ QgsRasterPipe::Role QgsRasterPipe::interfaceRole( QgsRasterInterface * interface
if ( dynamic_cast<QgsRasterDataProvider *>( interface ) ) role = ProviderRole;
else if ( dynamic_cast<QgsRasterRenderer *>( interface ) ) role = RendererRole;
else if ( dynamic_cast<QgsRasterResampleFilter *>( interface ) ) role = ResamplerRole;
else if ( dynamic_cast<QgsBrightnessContrastFilter *>( interface ) ) role = BrightnessRole;
else if ( dynamic_cast<QgsRasterProjector *>( interface ) ) role = ProjectorRole;
else if ( dynamic_cast<QgsRasterNuller *>( interface ) ) role = NullerRole;

Expand Down Expand Up @@ -178,6 +179,7 @@ bool QgsRasterPipe::set( QgsRasterInterface* theInterface )
int providerIdx = mRoleMap.value( ProviderRole, -1 );
int rendererIdx = mRoleMap.value( RendererRole, -1 );
int resamplerIdx = mRoleMap.value( ResamplerRole, -1 );
int brightnessIdx = mRoleMap.value( BrightnessRole, -1 );

if ( role == ProviderRole )
{
Expand All @@ -187,13 +189,17 @@ bool QgsRasterPipe::set( QgsRasterInterface* theInterface )
{
idx = providerIdx + 1;
}
else if ( role == ResamplerRole )
else if ( role == BrightnessRole )
{
idx = qMax( providerIdx, rendererIdx ) + 1;
}
else if ( role == ResamplerRole )
{
idx = qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ) + 1;
}
else if ( role == ProjectorRole )
{
idx = qMax( qMax( providerIdx, rendererIdx ), resamplerIdx ) + 1;
idx = qMax( qMax( qMax( providerIdx, rendererIdx ), brightnessIdx ), resamplerIdx ) + 1;
}

return insert( idx, theInterface ); // insert may still fail and return false
Expand Down Expand Up @@ -224,6 +230,11 @@ QgsRasterResampleFilter * QgsRasterPipe::resampleFilter() const
return dynamic_cast<QgsRasterResampleFilter *>( interface( ResamplerRole ) );
}

QgsBrightnessContrastFilter * QgsRasterPipe::brightnessFilter() const
{
return dynamic_cast<QgsBrightnessContrastFilter *>( interface( BrightnessRole ) );
}

QgsRasterProjector * QgsRasterPipe::projector() const
{
return dynamic_cast<QgsRasterProjector*>( interface( ProjectorRole ) );
Expand Down
9 changes: 6 additions & 3 deletions src/core/raster/qgsrasterpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "qgsrectangle.h"
#include "qgsrasterinterface.h"
#include "qgsrasterresamplefilter.h"
#include "qgsbrightnesscontrastfilter.h"
#include "qgsrasterdataprovider.h"
#include "qgsrasternuller.h"
#include "qgsrasterrenderer.h"
Expand All @@ -45,9 +46,10 @@ class CORE_EXPORT QgsRasterPipe
UnknownRole = 0,
ProviderRole = 1,
RendererRole = 2,
ResamplerRole = 3,
ProjectorRole = 4,
NullerRole = 5,
BrightnessRole = 3,
ResamplerRole = 4,
ProjectorRole = 5,
NullerRole = 6,
};

QgsRasterPipe();
Expand Down Expand Up @@ -92,6 +94,7 @@ class CORE_EXPORT QgsRasterPipe
QgsRasterDataProvider * provider() const;
QgsRasterRenderer * renderer() const;
QgsRasterResampleFilter * resampleFilter() const;
QgsBrightnessContrastFilter * brightnessFilter() const;
QgsRasterProjector * projector() const;
QgsRasterNuller * nuller() const;

Expand Down
24 changes: 24 additions & 0 deletions src/ui/qgisapp.ui
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@
<addaction name="mActionFullCumulativeCutStretch"/>
<addaction name="mActionLocalHistogramStretch"/>
<addaction name="mActionFullHistogramStretch"/>
<addaction name="mActionIncreaseBrightness"/>
<addaction name="mActionDecreaseBrightness"/>
<addaction name="mActionIncreaseContrast"/>
<addaction name="mActionDecreaseContrast"/>
</widget>
<widget class="QToolBar" name="mLabelToolBar">
<property name="windowTitle">
Expand Down Expand Up @@ -2015,6 +2019,26 @@ Acts on currently active editable layer</string>
<string>&amp;Export topology to SpatiaLite</string>
</property>
</action>
<action name="mActionIncreaseBrightness">
<property name="text">
<string>Increase brightness</string>
</property>
</action>
<action name="mActionDecreaseBrightness">
<property name="text">
<string>Decrease brightness</string>
</property>
</action>
<action name="mActionIncreaseContrast">
<property name="text">
<string>Increase contrast</string>
</property>
</action>
<action name="mActionDecreaseContrast">
<property name="text">
<string>Decrease contrast</string>
</property>
</action>
</widget>
<resources>
<include location="../../images/images.qrc"/>
Expand Down