48 changes: 0 additions & 48 deletions src/core/raster/qgsrasterrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,6 @@ QgsRasterRenderer::QgsRasterRenderer( QgsRasterFace* input, const QString& type

QgsRasterRenderer::~QgsRasterRenderer()
{
//remove remaining memory in partinfos
//QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.begin();
//for ( ; partIt != mRasterPartInfos.end(); ++partIt )
//{
//CPLFree( partIt.value().data );
//}

delete mZoomedInResampler;
delete mZoomedOutResampler;
delete mRasterTransparency;
}

void QgsRasterRenderer::setZoomedInResampler( QgsRasterResampler* r )
{
delete mZoomedInResampler;
mZoomedInResampler = r;
}

void QgsRasterRenderer::setZoomedOutResampler( QgsRasterResampler* r )
{
delete mZoomedOutResampler;
mZoomedOutResampler = r;
}

/*
Expand Down Expand Up @@ -335,16 +313,7 @@ void QgsRasterRenderer::_writeXML( QDomDocument& doc, QDomElement& rasterRendere
rasterRendererElem.setAttribute( "type", mType );
rasterRendererElem.setAttribute( "opacity", QString::number( mOpacity ) );
rasterRendererElem.setAttribute( "alphaBand", mAlphaBand );
rasterRendererElem.setAttribute( "maxOversampling", QString::number( mMaxOversampling ) );
rasterRendererElem.setAttribute( "invertColor", mInvertColor );
if ( mZoomedInResampler )
{
rasterRendererElem.setAttribute( "zoomedInResampler", mZoomedInResampler->type() );
}
if ( mZoomedOutResampler )
{
rasterRendererElem.setAttribute( "zoomedOutResampler", mZoomedOutResampler->type() );
}

if ( mRasterTransparency )
{
Expand All @@ -362,25 +331,8 @@ void QgsRasterRenderer::readXML( const QDomElement& rendererElem )
mType = rendererElem.attribute( "type" );
mOpacity = rendererElem.attribute( "opacity", "1.0" ).toDouble();
mAlphaBand = rendererElem.attribute( "alphaBand", "-1" ).toInt();
mMaxOversampling = rendererElem.attribute( "maxOversampling", "2.0" ).toDouble();
mInvertColor = rendererElem.attribute( "invertColor", "0" ).toInt();

QString zoomedInResamplerType = rendererElem.attribute( "zoomedInResampler" );
if ( zoomedInResamplerType == "bilinear" )
{
mZoomedInResampler = new QgsBilinearRasterResampler();
}
else if ( zoomedInResamplerType == "cubic" )
{
mZoomedInResampler = new QgsCubicRasterResampler();
}

QString zoomedOutResamplerType = rendererElem.attribute( "zoomedOutResampler" );
if ( zoomedOutResamplerType == "bilinear" )
{
mZoomedOutResampler = new QgsBilinearRasterResampler();
}

//todo: read mRasterTransparency
QDomElement rasterTransparencyElem = rendererElem.firstChildElement( "rasterTransparency" );
if ( !rasterTransparencyElem.isNull() )
Expand Down
14 changes: 0 additions & 14 deletions src/core/raster/qgsrasterrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,6 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterFace
void setInvertColor( bool invert ) { mInvertColor = invert; }
bool invertColor() const { return mInvertColor; }

/**Set resampler for zoomed in scales. Takes ownership of the object*/
void setZoomedInResampler( QgsRasterResampler* r );
const QgsRasterResampler* zoomedInResampler() const { return mZoomedInResampler; }

/**Set resampler for zoomed out scales. Takes ownership of the object*/
void setZoomedOutResampler( QgsRasterResampler* r );
const QgsRasterResampler* zoomedOutResampler() const { return mZoomedOutResampler; }

void setMaxOversampling( double os ) { mMaxOversampling = os; }
double maxOversampling() const { return mMaxOversampling; }

/**Get symbology items if provided by renderer*/
virtual void legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const { Q_UNUSED( symbolItems ); }

virtual void writeXML( QDomDocument& doc, QDomElement& parentElem ) const = 0;

/**Sets base class members from xml. Usually called from create() methods of subclasses*/
Expand Down
178 changes: 178 additions & 0 deletions src/core/raster/qgsrasterresamplefilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/***************************************************************************
qgsrasterresamplefilter.cpp
---------------------
begin : December 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/

#include "qgsrasterresamplefilter.h"
#include "qgsrasterresampler.h"
#include "qgsrasterprojector.h"
#include "qgsrastertransparency.h"
#include "qgsrasterviewport.h"
#include "qgsmaptopixel.h"

//resamplers
#include "qgsbilinearrasterresampler.h"
#include "qgscubicrasterresampler.h"

#include <QDomDocument>
#include <QDomElement>
#include <QImage>
#include <QPainter>

QgsRasterResampleFilter::QgsRasterResampleFilter( QgsRasterFace* input ): QgsRasterFace( input ),
mZoomedInResampler( 0 ), mZoomedOutResampler( 0 ),
mMaxOversampling( 2.0 )
{
}

QgsRasterResampleFilter::~QgsRasterResampleFilter()
{
// TODO: currently we are using pointer to renderer, enable once moved here
//delete mZoomedInResampler;
//delete mZoomedOutResampler;
//delete mRasterTransparency;
}

void QgsRasterResampleFilter::setZoomedInResampler( QgsRasterResampler* r )
{
//delete mZoomedInResampler;
mZoomedInResampler = r;
}

void QgsRasterResampleFilter::setZoomedOutResampler( QgsRasterResampler* r )
{
//delete mZoomedOutResampler;
mZoomedOutResampler = r;
}

void * QgsRasterResampleFilter::readBlock( int bandNo, QgsRectangle const & extent, int width, int height )
{
QgsDebugMsg( "Entered" );
if ( !mInput ) return 0;

double oversampling = 1.0; // approximate global oversampling factor

if ( mZoomedInResampler || mZoomedOutResampler )
{
// TODO: we must get it somehow from pipe (via projector), for now
oversampling = 2.;
/*
QgsRectangle providerExtent = mInput->extent();
if ( viewPort->mSrcCRS.isValid() && viewPort->mDestCRS.isValid() && viewPort->mSrcCRS != viewPort->mDestCRS )
{
QgsCoordinateTransform t( viewPort->mSrcCRS, viewPort->mDestCRS );
providerExtent = t.transformBoundingBox( providerExtent );
}
double pixelRatio = mapToPixel->mapUnitsPerPixel() / ( providerExtent.width() / mInput->xSize() );
oversampling = ( pixelRatio > mMaxOversampling ) ? mMaxOversampling : pixelRatio;
*/
}

//set oversampling back to 1.0 if no resampler for zoomed in / zoomed out (nearest neighbour)
if (( oversampling < 1.0 && !mZoomedInResampler ) || ( oversampling > 1.0 && !mZoomedOutResampler ) )
{
oversampling = 1.0;
}

QgsDebugMsg( QString( "oversampling %1" ).arg( oversampling ) );

//effective oversampling factors are different to global one because of rounding
double oversamplingX = (( double )width * oversampling ) / width;
double oversamplingY = (( double )height * oversampling ) / height;

// TODO: we must also increase the extent to get correct result on borders of parts


int resWidth = width*oversamplingX;
int resHeight = height*oversamplingY;

// At moment we know that we read rendered image
int bandNumber = 0;
void *rasterData = mInput->readBlock( bandNumber, extent, resWidth, resHeight );

//resample image
if (( mZoomedInResampler || mZoomedOutResampler ) && !doubleNear( oversamplingX, 1.0 ) && !doubleNear( oversamplingY, 1.0 ) )
{
QImage img(( uchar * ) rasterData, resWidth, resHeight, QImage::Format_ARGB32_Premultiplied );

QImage dstImg = QImage( width, height, QImage::Format_ARGB32_Premultiplied );

if ( mZoomedInResampler && oversamplingX < 1.0 )
{
QgsDebugMsg( "zoomed in resampling" );
mZoomedInResampler->resample( img, dstImg );
}
else if ( mZoomedOutResampler && oversamplingX > 1.0 )
{
QgsDebugMsg( "zoomed out resampling" );
mZoomedOutResampler->resample( img, dstImg );
}

// QImage does not delete data block passed to constructor
free( rasterData );

void * data = VSIMalloc( dstImg.byteCount() );
return memcpy( data, dstImg.bits(), dstImg.byteCount() );
}

return rasterData; // No resampling
}

void QgsRasterResampleFilter::writeXML( QDomDocument& doc, QDomElement& parentElem )
{
if ( parentElem.isNull() )
{
return;
}

QDomElement rasterRendererElem = doc.createElement( "rasterresampler" );

rasterRendererElem.setAttribute( "maxOversampling", mMaxOversampling );
if ( mZoomedInResampler )
{
rasterRendererElem.setAttribute( "zoomedInResampler", mZoomedInResampler->type() );
}
if ( mZoomedOutResampler )
{
rasterRendererElem.setAttribute( "zoomedOutResampler", mZoomedOutResampler->type() );
}
parentElem.appendChild( rasterRendererElem );
}

void QgsRasterResampleFilter::readXML( const QDomElement& rendererElem )
{
if ( rendererElem.isNull() )
{
return;
}

mMaxOversampling = rendererElem.attribute( "maxOversampling", "2.0" ).toDouble();

QString zoomedInResamplerType = rendererElem.attribute( "zoomedInResampler" );
if ( zoomedInResamplerType == "bilinear" )
{
mZoomedInResampler = new QgsBilinearRasterResampler();
}
else if ( zoomedInResamplerType == "cubic" )
{
mZoomedInResampler = new QgsCubicRasterResampler();
}

QString zoomedOutResamplerType = rendererElem.attribute( "zoomedOutResampler" );
if ( zoomedOutResamplerType == "bilinear" )
{
mZoomedOutResampler = new QgsBilinearRasterResampler();
}
}
75 changes: 75 additions & 0 deletions src/core/raster/qgsrasterresamplefilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/***************************************************************************
qgsrasterresamplefilter.h
-------------------
begin : December 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/

/***************************************************************************
* *
* 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 QGSRASTERRESAMPLEFILTER_H
#define QGSRASTERRESAMPLEFILTER_H

#include "qgsrasterdataprovider.h"
#include "qgsrasterface.h"

class QPainter;
class QgsMapToPixel;
class QgsRasterResampler;
class QgsRasterProjector;
class QgsRasterTransparency;
class QgsRasterViewPort;

class QDomElement;

class QgsRasterResampleFilter : public QgsRasterFace
{
public:
QgsRasterResampleFilter( QgsRasterFace* input = 0 );
~QgsRasterResampleFilter();

void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height );

/**Set resampler for zoomed in scales. Takes ownership of the object*/
void setZoomedInResampler( QgsRasterResampler* r );
const QgsRasterResampler* zoomedInResampler() const { return mZoomedInResampler; }

/**Set resampler for zoomed out scales. Takes ownership of the object*/
void setZoomedOutResampler( QgsRasterResampler* r );
const QgsRasterResampler* zoomedOutResampler() const { return mZoomedOutResampler; }

void setMaxOversampling( double os ) { mMaxOversampling = os; }
double maxOversampling() const { return mMaxOversampling; }

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

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

protected:

/**Write upper class info into <rasterresamplefilter> element (called by writeXML method of subclasses)*/
//void _writeXML( QDomDocument& doc, QDomElement& rasterRendererElem ) const;


/**Resampler used if screen resolution is higher than raster resolution (zoomed in). 0 means no resampling (nearest neighbour)*/
QgsRasterResampler* mZoomedInResampler;
/**Resampler used if raster resolution is higher than raster resolution (zoomed out). 0 mean no resampling (nearest neighbour)*/
QgsRasterResampler* mZoomedOutResampler;
//QMap<int, RasterPartInfo> mRasterPartInfos;

/**Maximum boundary for oversampling (to avoid too much data traffic). Default: 2.0*/
double mMaxOversampling;

private:
};

#endif // QGSRASTERRESAMPLEFILTER_H
17 changes: 2 additions & 15 deletions src/core/raster/qgssinglebandcolordatarenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,13 @@ void * QgsSingleBandColorDataRenderer::readBlock( int bandNo, QgsRectangle cons
return 0;
}

double oversamplingX, oversamplingY;
//startRasterRead( mBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY );

//number of cols/rows in output pixels
int nCols = 0;
int nRows = 0;
//number of raster cols/rows with oversampling
int nRasterCols = 0;
int nRasterRows = 0;
//shift to top left point for the raster part
int topLeftCol = 0;
int topLeftRow = 0;
int currentRasterPos;

//bool hasTransparency = usesTransparency( viewPort->mSrcCRS, viewPort->mDestCRS );
bool hasTransparency = false;

QgsRasterFace::DataType rasterType = ( QgsRasterFace::DataType )mInput->dataType( mBand );


void* rasterData = mInput->readBlock( bandNo, extent, width, height );

currentRasterPos = 0;
Expand All @@ -81,8 +68,8 @@ void * QgsSingleBandColorDataRenderer::readBlock( int bandNo, QgsRectangle cons
scanLine = img.scanLine( i );
if ( !hasTransparency )
{
memcpy( scanLine, &((( uint* )rasterData )[currentRasterPos] ), nCols * 4 );
currentRasterPos += nRasterCols;
memcpy( scanLine, &((( uint* )rasterData )[currentRasterPos] ), width * 4 );
currentRasterPos += width;
}
else
{
Expand Down
51 changes: 16 additions & 35 deletions src/core/raster/qgssinglebandgrayrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,51 +63,32 @@ void QgsSingleBandGrayRenderer::setContrastEnhancement( QgsContrastEnhancement*
//void QgsSingleBandGrayRenderer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel )
void * QgsSingleBandGrayRenderer::readBlock( int bandNo, QgsRectangle const & extent, int width, int height )
{
//if ( !mInput || !viewPort || !theQgsMapToPixel )
if ( !mInput )
{
return 0;
}

//double oversamplingX, oversamplingY;
//startRasterRead( mGrayBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY );
//if ( mAlphaBand > 0 && mGrayBand != mAlphaBand )
//{
//startRasterRead( mAlphaBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY );
//}

//number of cols/rows in output pixels
//int nCols = 0;
//int nRows = 0;
////number of raster cols/rows with oversampling
//int nRasterCols = 0;
//int nRasterRows = 0;
////shift to top left point for the raster part
//int topLeftCol = 0;
//int topLeftRow = 0;

QgsRasterFace::DataType rasterType = ( QgsRasterFace::DataType )mInput->dataType( mGrayBand );
//QgsRasterFace::DataType alphaType = QgsRasterFace::UnknownDataType;
//if ( mAlphaBand > 0 )
//{
//alphaType = ( QgsRasterFace::DataType )mInput->dataType( mAlphaBand );
//}
QgsRasterFace::DataType alphaType = QgsRasterFace::UnknownDataType;
if ( mAlphaBand > 0 )
{
alphaType = ( QgsRasterFace::DataType )mInput->dataType( mAlphaBand );
}

void* rasterData = mInput->readBlock( mGrayBand, extent, width, height );
//void* alphaData;
void* alphaData;
double currentAlpha = mOpacity;
int grayVal;
int grayVal, grayValOrig;
QRgb myDefaultColor = qRgba( 0, 0, 0, 0 );

//if ( mAlphaBand > 0 && mGrayBand != mAlphaBand )
//{
//readNextRasterPart( mAlphaBand, oversamplingX, oversamplingY, viewPort, nCols, nRows, nRasterCols, nRasterRows,
//&alphaData, topLeftCol, topLeftRow );
//}
//else if ( mAlphaBand > 0 )
//{
//alphaData = rasterData;
//}
if ( mAlphaBand > 0 && mGrayBand != mAlphaBand )
{
alphaData = mInput->readBlock( mAlphaBand, extent, width, height );
}
else if ( mAlphaBand > 0 )
{
alphaData = rasterData;
}

//create image
QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
Expand All @@ -119,7 +100,7 @@ void * QgsSingleBandGrayRenderer::readBlock( int bandNo, QgsRectangle const & e
imageScanLine = ( QRgb* )( img.scanLine( i ) );
for ( int j = 0; j < width; ++j )
{
grayVal = readValue( rasterData, rasterType, currentRasterPos );
grayValOrig = grayVal = readValue( rasterData, rasterType, currentRasterPos );

//alpha
currentAlpha = mOpacity;
Expand Down
54 changes: 19 additions & 35 deletions src/core/raster/qgssinglebandpseudocolorrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,28 +66,13 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co
return 0;
}

//double oversamplingX, oversamplingY;
//QgsRasterFace::DataType transparencyType = QgsRasterFace::UnknownDataType;
//if ( mAlphaBand > 0 )
//{
//transparencyType = ( QgsRasterFace::DataType )mInput->dataType( mAlphaBand );
//}
//startRasterRead( mBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY );
////Read alpha band if necessary
//if ( mAlphaBand > 0 && mAlphaBand != mBand )
//{
//startRasterRead( mAlphaBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY );
//}

//number of cols/rows in output pixels
int nCols = 0;
int nRows = 0;
//number of raster cols/rows with oversampling
int nRasterCols = 0;
int nRasterRows = 0;
//shift to top left point for the raster part
int topLeftCol = 0;
int topLeftRow = 0;
QgsRasterFace::DataType transparencyType = QgsRasterFace::UnknownDataType;
if ( mAlphaBand > 0 )
{
transparencyType = ( QgsRasterFace::DataType )mInput->dataType( mAlphaBand );
}

void* transparencyData;
void* transparencyData = 0;
double currentOpacity = mOpacity;
QgsRasterFace::DataType rasterType = ( QgsRasterFace::DataType )mInput->dataType( mBand );
Expand All @@ -101,15 +86,14 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co
//bool hasTransparency = usesTransparency( viewPort->mSrcCRS, viewPort->mDestCRS );
bool hasTransparency = false;

//if ( mAlphaBand > 0 && mAlphaBand != mBand )
//{
//readNextRasterPart( mAlphaBand, oversamplingX, oversamplingY, viewPort, nCols, nRows, nRasterCols, nRasterRows,
//&transparencyData, topLeftCol, topLeftRow );
//}
//else if ( mAlphaBand == mBand )
//{
//transparencyData = rasterData;
//}
if ( mAlphaBand > 0 && mAlphaBand != mBand )
{
transparencyData = mInput->readBlock( mAlphaBand, extent, width, height );
}
else if ( mAlphaBand == mBand )
{
transparencyData = rasterData;
}

//create image
QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
Expand Down Expand Up @@ -142,10 +126,10 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co
{
currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0;
}
//if ( mAlphaBand > 0 )
//{
//currentOpacity *= ( readValue( transparencyData, transparencyType, currentRasterPos ) / 255.0 );
//}
if ( mAlphaBand > 0 )
{
currentOpacity *= ( readValue( transparencyData, transparencyType, currentRasterPos ) / 255.0 );
}

imageScanLine[j] = qRgba( currentOpacity * red, currentOpacity * green, currentOpacity * blue, currentOpacity * 255 );
}
Expand Down