imgproc: fix indexing issue in pyramids

UBSAN violation expression: 'tab = tabR - x;'
This commit is contained in:
Alexander Alekhin 2019-09-26 17:56:24 +03:00
parent 7ce9428e96
commit f81e401cd0

View File

@ -741,13 +741,13 @@ pyrDown_( const Mat& _src, Mat& _dst, int borderType )
CV_Assert( ssize.width > 0 && ssize.height > 0 && CV_Assert( ssize.width > 0 && ssize.height > 0 &&
std::abs(dsize.width*2 - ssize.width) <= 2 && std::abs(dsize.width*2 - ssize.width) <= 2 &&
std::abs(dsize.height*2 - ssize.height) <= 2 ); std::abs(dsize.height*2 - ssize.height) <= 2 );
int k, x, sy0 = -PD_SZ/2, sy = sy0, width0 = std::min((ssize.width-PD_SZ/2-1)/2 + 1, dsize.width); int sy0 = -PD_SZ/2, sy = sy0, width0 = std::min((ssize.width-PD_SZ/2-1)/2 + 1, dsize.width);
for( x = 0; x <= PD_SZ+1; x++ ) for (int x = 0; x <= PD_SZ+1; x++)
{ {
int sx0 = borderInterpolate(x - PD_SZ/2, ssize.width, borderType)*cn; int sx0 = borderInterpolate(x - PD_SZ/2, ssize.width, borderType)*cn;
int sx1 = borderInterpolate(x + width0*2 - PD_SZ/2, ssize.width, borderType)*cn; int sx1 = borderInterpolate(x + width0*2 - PD_SZ/2, ssize.width, borderType)*cn;
for( k = 0; k < cn; k++ ) for (int k = 0; k < cn; k++)
{ {
tabL[x*cn + k] = sx0 + k; tabL[x*cn + k] = sx0 + k;
tabR[x*cn + k] = sx1 + k; tabR[x*cn + k] = sx1 + k;
@ -758,10 +758,10 @@ pyrDown_( const Mat& _src, Mat& _dst, int borderType )
dsize.width *= cn; dsize.width *= cn;
width0 *= cn; width0 *= cn;
for( x = 0; x < dsize.width; x++ ) for (int x = 0; x < dsize.width; x++)
tabM[x] = (x/cn)*2*cn + x % cn; tabM[x] = (x/cn)*2*cn + x % cn;
for( int y = 0; y < dsize.height; y++ ) for (int y = 0; y < dsize.height; y++)
{ {
T* dst = _dst.ptr<T>(y); T* dst = _dst.ptr<T>(y);
WT *row0, *row1, *row2, *row3, *row4; WT *row0, *row1, *row2, *row3, *row4;
@ -772,15 +772,13 @@ pyrDown_( const Mat& _src, Mat& _dst, int borderType )
WT* row = buf + ((sy - sy0) % PD_SZ)*bufstep; WT* row = buf + ((sy - sy0) % PD_SZ)*bufstep;
int _sy = borderInterpolate(sy, ssize.height, borderType); int _sy = borderInterpolate(sy, ssize.height, borderType);
const T* src = _src.ptr<T>(_sy); const T* src = _src.ptr<T>(_sy);
int limit = cn;
const int* tab = tabL;
for( x = 0;;) do {
{ int x = 0;
for( ; x < limit; x++ ) for( ; x < cn; x++ )
{ {
row[x] = src[tab[x+cn*2]]*6 + (src[tab[x+cn]] + src[tab[x+cn*3]])*4 + row[x] = src[tabL[x+cn*2]]*6 + (src[tabL[x+cn]] + src[tabL[x+cn*3]])*4 +
src[tab[x]] + src[tab[x+cn*4]]; src[tabL[x]] + src[tabL[x+cn*4]];
} }
if( x == dsize.width ) if( x == dsize.width )
@ -840,18 +838,22 @@ pyrDown_( const Mat& _src, Mat& _dst, int borderType )
} }
} }
limit = dsize.width; // tabR
tab = tabR - x; for (int x_ = 0; x < dsize.width; x++, x_++)
} {
row[x] = src[tabR[x_+cn*2]]*6 + (src[tabR[x_+cn]] + src[tabR[x_+cn*3]])*4 +
src[tabR[x_]] + src[tabR[x_+cn*4]];
}
} while (0);
} }
// do vertical convolution and decimation and write the result to the destination image // do vertical convolution and decimation and write the result to the destination image
for( k = 0; k < PD_SZ; k++ ) for (int k = 0; k < PD_SZ; k++)
rows[k] = buf + ((y*2 - PD_SZ/2 + k - sy0) % PD_SZ)*bufstep; rows[k] = buf + ((y*2 - PD_SZ/2 + k - sy0) % PD_SZ)*bufstep;
row0 = rows[0]; row1 = rows[1]; row2 = rows[2]; row3 = rows[3]; row4 = rows[4]; row0 = rows[0]; row1 = rows[1]; row2 = rows[2]; row3 = rows[3]; row4 = rows[4];
x = PyrDownVecV<WT, T>(rows, dst, dsize.width); int x = PyrDownVecV<WT, T>(rows, dst, dsize.width);
for( ; x < dsize.width; x++ ) for (; x < dsize.width; x++ )
dst[x] = castOp(row2[x]*6 + (row1[x] + row3[x])*4 + row0[x] + row4[x]); dst[x] = castOp(row2[x]*6 + (row1[x] + row3[x])*4 + row0[x] + row4[x]);
} }
} }