Skip to content
Permalink
Browse files

raster resampler fixes, use zoom in resampler also for oversampling 1

  • Loading branch information
blazek committed May 16, 2013
1 parent 596e1f1 commit 36bf93c0d22cde653b5c6c37002bc0747eed4c55
@@ -112,7 +112,7 @@ bool QgsBrightnessContrastFilter::setInput( QgsRasterInterface* input )
QgsRasterBlock * QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle const & extent, int width, int height )
{
Q_UNUSED( bandNo );
QgsDebugMsg( "Entered" );
QgsDebugMsg( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ) );

QgsRasterBlock *outputBlock = new QgsRasterBlock();
if ( !mInput )
@@ -118,7 +118,7 @@ bool QgsHueSaturationFilter::setInput( QgsRasterInterface* input )
QgsRasterBlock * QgsHueSaturationFilter::block( int bandNo, QgsRectangle const & extent, int width, int height )
{
Q_UNUSED( bandNo );
QgsDebugMsg( "Entered hue/saturation filter block" );
QgsDebugMsg( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ) );

QgsRasterBlock *outputBlock = new QgsRasterBlock();
if ( !mInput )
@@ -138,7 +138,7 @@ void QgsRasterProjector::calc()
delete[] pHelperBottom;
pHelperBottom = 0;

// Get max source resolution if possible
// Get max source resolution and extent if possible
mMaxSrcXRes = 0;
mMaxSrcYRes = 0;
if ( mInput )
@@ -149,6 +149,11 @@ void QgsRasterProjector::calc()
mMaxSrcXRes = provider->extent().width() / provider->xSize();
mMaxSrcYRes = provider->extent().height() / provider->ySize();
}
// Get source extent
if ( mExtent.isEmpty() )
{
mExtent = provider->extent();
}
}

mDestXRes = mDestExtent.width() / ( mDestCols );
@@ -254,35 +259,38 @@ void QgsRasterProjector::calcSrcExtent()
// Expand a bit to avoid possible approx coords falling out because of representation error?

// If mMaxSrcXRes, mMaxSrcYRes are defined (fixed src resolution)
// align extent to src resolution to avoid jumping reprojected pixels
// because of shifting resampled grid
// align extent to src resolution to avoid jumping of reprojected pixels
// when shifting resampled grid.
// Important especially if we are over mMaxSrcXRes, mMaxSrcYRes limits
// Note however, that preceeding filters (like resampler) may read data
// on different resolution.

QgsDebugMsg( "mSrcExtent = " + mSrcExtent.toString() );

if ( mMaxSrcXRes > 0 )
{
// with floor/ceil it should work correctly also for mSrcExtent.xMinimum() < mExtent.xMinimum()
double col = floor(( mSrcExtent.xMinimum() - mExtent.xMinimum() ) / mMaxSrcXRes );
double x = mExtent.xMinimum() + col * mMaxSrcXRes;
mSrcExtent.setXMinimum( x );

col = ceil(( mSrcExtent.xMaximum() - mExtent.xMinimum() ) / mMaxSrcXRes );
x = mExtent.xMinimum() + col * mMaxSrcXRes;
mSrcExtent.setXMaximum( x );
}
if ( mMaxSrcYRes > 0 )
QgsDebugMsg( "mExtent = " + mExtent.toString() );
if ( !mExtent.isEmpty() )
{
double row = floor(( mExtent.yMaximum() - mSrcExtent.yMaximum() ) / mMaxSrcYRes );
double y = mExtent.yMaximum() - row * mMaxSrcYRes;
mSrcExtent.setYMaximum( y );
if ( mMaxSrcXRes > 0 )
{
// with floor/ceil it should work correctly also for mSrcExtent.xMinimum() < mExtent.xMinimum()
double col = floor(( mSrcExtent.xMinimum() - mExtent.xMinimum() ) / mMaxSrcXRes );
double x = mExtent.xMinimum() + col * mMaxSrcXRes;
mSrcExtent.setXMinimum( x );

col = ceil(( mSrcExtent.xMaximum() - mExtent.xMinimum() ) / mMaxSrcXRes );
x = mExtent.xMinimum() + col * mMaxSrcXRes;
mSrcExtent.setXMaximum( x );
}
if ( mMaxSrcYRes > 0 )
{
double row = floor(( mExtent.yMaximum() - mSrcExtent.yMaximum() ) / mMaxSrcYRes );
double y = mExtent.yMaximum() - row * mMaxSrcYRes;
mSrcExtent.setYMaximum( y );

row = ceil(( mExtent.yMaximum() - mSrcExtent.yMinimum() ) / mMaxSrcYRes );
y = mExtent.yMaximum() - row * mMaxSrcYRes;
mSrcExtent.setYMinimum( y );
row = ceil(( mExtent.yMaximum() - mSrcExtent.yMinimum() ) / mMaxSrcYRes );
y = mExtent.yMaximum() - row * mMaxSrcYRes;
mSrcExtent.setYMinimum( y );
}
}


QgsDebugMsg( "mSrcExtent = " + mSrcExtent.toString() );
}

@@ -427,8 +435,13 @@ void QgsRasterProjector::nextHelper()
void QgsRasterProjector::srcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol )
{
if ( mApproximate )
{
approximateSrcRowCol( theDestRow, theDestCol, theSrcRow, theSrcCol );
else preciseSrcRowCol( theDestRow, theDestCol, theSrcRow, theSrcCol );
}
else
{
preciseSrcRowCol( theDestRow, theDestCol, theSrcRow, theSrcCol );
}
}

void QgsRasterProjector::preciseSrcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol )
@@ -588,7 +601,7 @@ void QgsRasterProjector::calcCP( int theRow, int theCol )
{
Q_UNUSED( e );
// Caught an error in transform
mCPLegalMatrix[theRow][theCol] = true;
mCPLegalMatrix[theRow][theCol] = false;
}
}

@@ -725,7 +738,6 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex
return new QgsRasterBlock();
}

//void * inputData = mInput->block( bandNo, srcExtent(), srcCols(), srcRows() );
QgsRasterBlock *inputBlock = mInput->block( bandNo, srcExtent(), srcCols(), srcRows() );
if ( !inputBlock || inputBlock->isEmpty() )
{
@@ -769,7 +781,7 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex
for ( int j = 0; j < width; ++j )
{
srcRowCol( i, j, &srcRow, &srcCol );
size_t srcIndex = srcRow * mSrcCols + srcCol;
size_t srcIndex = ( size_t )srcRow * mSrcCols + srcCol;
QgsDebugMsgLevel( QString( "row = %1 col = %2 srcRow = %3 srcCol = %4" ).arg( i ).arg( j ).arg( srcRow ).arg( srcCol ), 5 );

// isNoData() may be slow so we check doNoData first
@@ -779,17 +791,17 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex
continue ;
}

size_t destIndex = i * width + j;
size_t destIndex = ( size_t )i * width + j;
char *srcBits = inputBlock->bits( srcIndex );
char *destBits = outputBlock->bits( destIndex );
if ( !srcBits )
{
QgsDebugMsg( "Cannot get input block data." );
QgsDebugMsg( QString( "Cannot get input block data: row = %1 col = %2" ).arg( i ).arg( j ) );
continue;
}
if ( !destBits )
{
QgsDebugMsg( "Cannot set output block data." );
QgsDebugMsg( QString( "Cannot set output block data: srcRow = %1 srcCol = %2" ).arg( srcRow ).arg( srcCol ) );
continue;
}
memcpy( destBits, srcBits, pixelSize );
@@ -131,7 +131,7 @@ void QgsRasterResampleFilter::setZoomedOutResampler( QgsRasterResampler* r )
QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const & extent, int width, int height )
{
Q_UNUSED( bandNo );
QgsDebugMsg( "Entered" );
QgsDebugMsg( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ) );
QgsRasterBlock *outputBlock = new QgsRasterBlock();
if ( !mInput ) return outputBlock;

@@ -140,7 +140,6 @@ QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const
if ( mZoomedInResampler || mZoomedOutResampler )
{
QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() );
// Do not oversample if data source does not have fixed resolution (WMS)
if ( provider && ( provider->capabilities() & QgsRasterDataProvider::Size ) )
{
double xRes = extent.width() / width;
@@ -158,14 +157,19 @@ QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const
}
}

//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 ) )
QgsDebugMsg( QString( "oversampling %1" ).arg( oversampling ) );

int bandNumber = 1;

// Do no oversampling if no resampler for zoomed in / zoomed out (nearest neighbour)
// We do mZoomedInResampler if oversampling == 1 (otherwise for example reprojected
// zoom in rasters are never resampled because projector limits resolution.
if (( (oversampling < 1.0 || qgsDoubleNear( oversampling, 1.0) ) && !mZoomedInResampler ) || ( oversampling > 1.0 && !mZoomedOutResampler ) )
{
oversampling = 1.0;
QgsDebugMsg( "No oversampling." );
return mInput->block( bandNumber, extent, width, height );
}

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;
@@ -175,9 +179,6 @@ QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const
int resWidth = width * oversamplingX;
int resHeight = height * oversamplingY;

// At moment we know that we read rendered image
int bandNumber = 1;
//void *rasterData = mInput->block( bandNumber, extent, resWidth, resHeight );
QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, resWidth, resHeight );
if ( !inputBlock || inputBlock->isEmpty() )
{
@@ -186,13 +187,6 @@ QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const
return outputBlock;
}

if ( qgsDoubleNear( oversamplingX, 1.0 ) || qgsDoubleNear( oversamplingY, 1.0 ) )
{
QgsDebugMsg( "No oversampling." );
delete outputBlock;
return inputBlock;
}

if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) )
{
delete inputBlock;
@@ -204,7 +198,7 @@ QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const

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

if ( mZoomedInResampler && oversamplingX < 1.0 )
if ( mZoomedInResampler && (oversamplingX < 1.0 || qgsDoubleNear( oversampling, 1.0) ) )
{
QgsDebugMsg( "zoomed in resampling" );
mZoomedInResampler->resample( img, dstImg );

0 comments on commit 36bf93c

Please sign in to comment.
You can’t perform that action at this time.