@@ -85,20 +85,16 @@ void GDALdllImageFilledPolygon(int nRasterXSize, int nRasterYSize,
8585 {
8686 dminy = padfY[i];
8787 }
88- if (padfY[i] > dmaxy)
88+ else if (padfY[i] > dmaxy)
8989 {
9090 dmaxy = padfY[i];
9191 }
9292 }
93- int miny = static_cast <int >(dminy);
94- int maxy = static_cast <int >(dmaxy);
93+ const int miny = static_cast <int >(std::max (0.0 , dminy));
94+ const int maxy =
95+ static_cast <int >(std::min<double >(dmaxy, nRasterYSize - 1 ));
9596
96- if (miny < 0 )
97- miny = 0 ;
98- if (maxy >= nRasterYSize)
99- maxy = nRasterYSize - 1 ;
100-
101- int minx = 0 ;
97+ constexpr int minx = 0 ;
10298 const int maxx = nRasterXSize - 1 ;
10399
104100 // Fix in 1.3: count a vertex only once.
@@ -159,13 +155,16 @@ void GDALdllImageFilledPolygon(int nRasterXSize, int nRasterYSize,
159155 // -Fill them separately-
160156 if (padfX[ind1] > padfX[ind2])
161157 {
162- const int horizontal_x1 =
163- static_cast <int >(floor (padfX[ind2] + 0.5 ));
164- const int horizontal_x2 =
165- static_cast <int >(floor (padfX[ind1] + 0.5 ));
158+ const double dhorizontal_x1 = floor (padfX[ind2] + 0.5 );
159+ const double dhorizontal_x2 = floor (padfX[ind1] + 0.5 );
166160
167- if ((horizontal_x1 > maxx) || (horizontal_x2 <= minx))
161+ if ((dhorizontal_x1 > static_cast <double >(maxx)) ||
162+ (dhorizontal_x2 <= 0 ))
168163 continue ;
164+ const int horizontal_x1 =
165+ static_cast <int >(std::max (dhorizontal_x1, 0.0 ));
166+ const int horizontal_x2 = static_cast <int >(
167+ std::min<double >(dhorizontal_x2, nRasterXSize));
169168
170169 // Fill the horizontal segment (separately from the rest).
171170 if (bAvoidBurningSamePoints)
@@ -187,8 +186,9 @@ void GDALdllImageFilledPolygon(int nRasterXSize, int nRasterYSize,
187186
188187 if (dy < dy2 && dy >= dy1)
189188 {
190- const double intersect =
191- (dy - dy1) * (dx2 - dx1) / (dy2 - dy1) + dx1;
189+ const double intersect = std::clamp<double >(
190+ (dy - dy1) * (dx2 - dx1) / (dy2 - dy1) + dx1, INT_MIN,
191+ INT_MAX);
192192
193193 polyInts[ints++] = static_cast <int >(floor (intersect + 0.5 ));
194194 }
@@ -237,14 +237,15 @@ void GDALdllImagePoint(int nRasterXSize, int nRasterYSize, int nPartCount,
237237{
238238 for (int i = 0 ; i < nPartCount; i++)
239239 {
240- const int nX = static_cast < int >( floor ( padfX[i])) ;
241- const int nY = static_cast < int >( floor ( padfY[i])) ;
240+ const double dfX = padfX[i];
241+ const double dfY = padfY[i];
242242 double dfVariant = 0.0 ;
243243 if (padfVariant != nullptr )
244244 dfVariant = padfVariant[i];
245245
246- if (0 <= nX && nX < nRasterXSize && 0 <= nY && nY < nRasterYSize)
247- pfnPointFunc (pCBData, nY, nX, dfVariant);
246+ if (0 <= dfX && dfX < nRasterXSize && 0 <= dfY && dfY < nRasterYSize)
247+ pfnPointFunc (pCBData, static_cast <int >(dfY), static_cast <int >(dfX),
248+ dfVariant);
248249 }
249250}
250251
@@ -264,11 +265,34 @@ void GDALdllImageLine(int nRasterXSize, int nRasterYSize, int nPartCount,
264265 {
265266 for (int j = 1 ; j < panPartSize[i]; j++)
266267 {
267- int iX = static_cast <int >(floor (padfX[n + j - 1 ]));
268- int iY = static_cast <int >(floor (padfY[n + j - 1 ]));
268+ double dfX = padfX[n + j - 1 ];
269+ double dfY = padfY[n + j - 1 ];
270+ double dfXEnd = padfX[n + j];
271+ double dfYEnd = padfY[n + j];
272+
273+ // Skip segments that are off the target region.
274+ if ((dfY < 0.0 && dfYEnd < 0.0 ) ||
275+ (dfY > nRasterYSize && dfYEnd > nRasterYSize) ||
276+ (dfX < 0.0 && dfXEnd < 0.0 ) ||
277+ (dfX > nRasterXSize && dfXEnd > nRasterXSize))
278+ continue ;
279+
280+ // TODO: clamp coordinates to [0, nRasterXSize] * [0, nRasterYSize]
281+ if (!(dfX >= INT_MIN && dfX <= INT_MAX && dfY >= INT_MIN &&
282+ dfY <= INT_MAX && dfXEnd >= INT_MIN && dfXEnd <= INT_MAX &&
283+ dfYEnd >= INT_MIN && dfYEnd <= INT_MAX))
284+ {
285+ CPLErrorOnce (
286+ CE_Warning, CPLE_AppDefined,
287+ " GDALdllImageLine(): coordinates outside of int range" );
288+ continue ;
289+ }
290+
291+ int iX = static_cast <int >(floor (dfX));
292+ int iY = static_cast <int >(floor (dfY));
269293
270- const int iX1 = static_cast <int >(floor (padfX[n + j] ));
271- const int iY1 = static_cast <int >(floor (padfY[n + j] ));
294+ const int iX1 = static_cast <int >(floor (dfXEnd ));
295+ const int iY1 = static_cast <int >(floor (dfYEnd ));
272296
273297 double dfVariant = 0.0 ;
274298 double dfVariant1 = 0.0 ;
@@ -412,6 +436,24 @@ void GDALdllImageLineAllTouched(
412436 double dfXEnd = padfX[n + j];
413437 double dfYEnd = padfY[n + j];
414438
439+ // Skip segments that are off the target region.
440+ if ((dfY < 0.0 && dfYEnd < 0.0 ) ||
441+ (dfY > nRasterYSize && dfYEnd > nRasterYSize) ||
442+ (dfX < 0.0 && dfXEnd < 0.0 ) ||
443+ (dfX > nRasterXSize && dfXEnd > nRasterXSize))
444+ continue ;
445+
446+ // TODO: clamp coordinates to [0, nRasterXSize] * [0, nRasterYSize]
447+ if (!(dfX >= INT_MIN && dfX <= INT_MAX && dfY >= INT_MIN &&
448+ dfY <= INT_MAX && dfXEnd >= INT_MIN && dfXEnd <= INT_MAX &&
449+ dfYEnd >= INT_MIN && dfYEnd <= INT_MAX))
450+ {
451+ CPLErrorOnce (CE_Warning, CPLE_AppDefined,
452+ " GDALdllImageLineAllTouched(): coordinates "
453+ " outside of int range" );
454+ continue ;
455+ }
456+
415457 double dfVariant = 0.0 ;
416458 double dfVariantEnd = 0.0 ;
417459 if (padfVariant != nullptr &&
@@ -422,13 +464,6 @@ void GDALdllImageLineAllTouched(
422464 dfVariantEnd = padfVariant[n + j];
423465 }
424466
425- // Skip segments that are off the target region.
426- if ((dfY < 0.0 && dfYEnd < 0.0 ) ||
427- (dfY > nRasterYSize && dfYEnd > nRasterYSize) ||
428- (dfX < 0.0 && dfXEnd < 0.0 ) ||
429- (dfX > nRasterXSize && dfXEnd > nRasterXSize))
430- continue ;
431-
432467 // Swap if needed so we can proceed from left2right (X increasing)
433468 if (dfX > dfXEnd)
434469 {
0 commit comments