Skip to content

Commit bccba1d

Browse files
committed
Better handling of edge-cases for bilinear resampler
1 parent cb7b812 commit bccba1d

File tree

1 file changed

+57
-25
lines changed

1 file changed

+57
-25
lines changed

src/core/raster/qgsbilinearrasterresampler.cpp

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "qgsbilinearrasterresampler.h"
1919
#include <QImage>
20+
#include <cmath>
2021

2122
QgsBilinearRasterResampler::QgsBilinearRasterResampler()
2223
{
@@ -33,43 +34,74 @@ void QgsBilinearRasterResampler::resample( const QImage& srcImage, QImage& dstIm
3334

3435
double currentSrcRow = nSrcPerDstY / 2.0 - 0.5;
3536
double currentSrcCol;
37+
int currentSrcRowInt, currentSrcColInt;
38+
double u, v;
3639

3740
QRgb px1, px2, px3, px4;
3841

3942
for ( int i = 0; i < dstImage.height(); ++i )
4043
{
41-
//avoid access to invalid rows
42-
if ( currentSrcRow < 0 )
43-
{
44-
currentSrcRow += nSrcPerDstY;
45-
}
46-
4744
currentSrcCol = nSrcPerDstX / 2.0 - 0.5;
45+
currentSrcRowInt = floor( currentSrcRow );
46+
v = currentSrcRow - currentSrcRowInt;
47+
4848
for ( int j = 0; j < dstImage.width(); ++j )
4949
{
50-
double u = currentSrcCol - ( int )currentSrcCol;
51-
double v = currentSrcRow - ( int )currentSrcRow;
52-
if ( currentSrcCol > srcImage.width() - 2 )
53-
{
54-
//resample in one direction only
55-
px1 = srcImage.pixel( currentSrcCol, currentSrcRow );
56-
px2 = srcImage.pixel( currentSrcCol, currentSrcRow + 1 );
57-
dstImage.setPixel( j, i, resampleColorValue( v, px1, px2 ) );
58-
currentSrcCol += nSrcPerDstX;
59-
continue;
60-
}
61-
else if ( currentSrcRow > srcImage.height() - 2 )
50+
currentSrcColInt = floor( currentSrcCol );
51+
u = currentSrcCol - currentSrcColInt;
52+
53+
//handle eight edge-cases
54+
if( currentSrcRowInt < 0 || currentSrcRowInt >= (srcImage.height() - 1) || currentSrcColInt < 0 || currentSrcColInt >= (srcImage.width() - 1) )
6255
{
63-
px1 = srcImage.pixel( currentSrcCol, currentSrcRow );
64-
px2 = srcImage.pixel( currentSrcCol + 1, currentSrcRow );
65-
dstImage.setPixel( j, i, resampleColorValue( u, px1, px2 ) );
56+
//pixels at the border of the source image needs to be handled in a special way
57+
if( currentSrcRowInt < 0 && currentSrcColInt < 0 )
58+
{
59+
dstImage.setPixel( j, i, srcImage.pixel(0, 0) );
60+
}
61+
else if( currentSrcRowInt < 0 && currentSrcColInt >= ( srcImage.width() - 1 ) )
62+
{
63+
dstImage.setPixel( j, i, srcImage.pixel( srcImage.width() - 1, 0 ) );
64+
}
65+
else if( currentSrcRowInt >= (srcImage.height() - 1) && currentSrcColInt >= ( srcImage.width() - 1 ) )
66+
{
67+
dstImage.setPixel( j, i, srcImage.pixel( srcImage.width() - 1, srcImage.height() - 1 ) );
68+
}
69+
else if( currentSrcRowInt >= (srcImage.height() - 1) && currentSrcColInt < 0 )
70+
{
71+
dstImage.setPixel( j, i, srcImage.pixel( 0, srcImage.height() - 1 ) );
72+
}
73+
else if( currentSrcRowInt < 0 )
74+
{
75+
px1 = srcImage.pixel( currentSrcColInt, 0 );
76+
px2 = srcImage.pixel( currentSrcColInt + 1, 0 );
77+
dstImage.setPixel( j, i, resampleColorValue( u, px1, px2 ) );
78+
}
79+
else if( currentSrcRowInt >= (srcImage.height() - 1) )
80+
{
81+
px1 = srcImage.pixel( currentSrcColInt, srcImage.height() - 1 );
82+
px2 = srcImage.pixel( currentSrcColInt + 1, srcImage.height() - 1 );
83+
dstImage.setPixel( j, i, resampleColorValue( u, px1, px2 ) );
84+
}
85+
else if( currentSrcColInt < 0 )
86+
{
87+
px1 = srcImage.pixel( 0, currentSrcRowInt );
88+
px2 = srcImage.pixel( 0, currentSrcRowInt + 1);
89+
dstImage.setPixel( j, i, resampleColorValue( v, px1, px2 ) );
90+
}
91+
else if( currentSrcColInt >= ( srcImage.width() - 1 ) )
92+
{
93+
px1 = srcImage.pixel( srcImage.width() - 1, currentSrcRowInt );
94+
px2 = srcImage.pixel( srcImage.width() - 1, currentSrcRowInt + 1);
95+
dstImage.setPixel( j, i, resampleColorValue( v, px1, px2 ) );
96+
}
6697
currentSrcCol += nSrcPerDstX;
6798
continue;
6899
}
69-
px1 = srcImage.pixel( currentSrcCol, currentSrcRow );
70-
px2 = srcImage.pixel( currentSrcCol + 1, currentSrcRow );
71-
px3 = srcImage.pixel( currentSrcCol + 1, currentSrcRow + 1 );
72-
px4 = srcImage.pixel( currentSrcCol, currentSrcRow + 1 );
100+
101+
px1 = srcImage.pixel( currentSrcColInt, currentSrcRowInt );
102+
px2 = srcImage.pixel( currentSrcColInt + 1, currentSrcRowInt );
103+
px3 = srcImage.pixel( currentSrcColInt + 1, currentSrcRowInt + 1 );
104+
px4 = srcImage.pixel( currentSrcColInt, currentSrcRowInt + 1 );
73105
dstImage.setPixel( j, i, resampleColorValue( u, v, px1, px2, px3, px4 ) );
74106
currentSrcCol += nSrcPerDstX;
75107
}

0 commit comments

Comments
 (0)