summaryrefslogtreecommitdiff
path: root/src/video/SDL_pixels.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video/SDL_pixels.c')
-rw-r--r--src/video/SDL_pixels.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/src/video/SDL_pixels.c b/src/video/SDL_pixels.c
index 1a7fd518f1..44626b7494 100644
--- a/src/video/SDL_pixels.c
+++ b/src/video/SDL_pixels.c
@@ -286,26 +286,53 @@ void SDL_DitherColors(SDL_Color *colors, int bpp)
}
}
/*
- * Calculate the pad-aligned scanline width of a surface
+ * Calculate the pad-aligned scanline width of a surface. Return 0 in case of
+ * an error.
*/
Uint16 SDL_CalculatePitch(SDL_Surface *surface)
{
- Uint16 pitch;
+ unsigned int pitch = 0;
/* Surface should be 4-byte aligned for speed */
- pitch = surface->w*surface->format->BytesPerPixel;
+ /* The code tries to prevent from an Uint16 overflow. */;
+ for (Uint8 byte = surface->format->BytesPerPixel; byte; byte--) {
+ pitch += (unsigned int)surface->w;
+ if (pitch < surface->w) {
+ SDL_SetError("A scanline is too wide");
+ return(0);
+ }
+ }
switch (surface->format->BitsPerPixel) {
case 1:
- pitch = (pitch+7)/8;
+ if (pitch % 8) {
+ pitch = pitch / 8 + 1;
+ } else {
+ pitch = pitch / 8;
+ }
break;
case 4:
- pitch = (pitch+1)/2;
+ if (pitch % 2) {
+ pitch = pitch / 2 + 1;
+ } else {
+ pitch = pitch / 2;
+ }
break;
default:
break;
}
- pitch = (pitch + 3) & ~3; /* 4-byte aligning */
- return(pitch);
+ /* 4-byte aligning */
+ if (pitch & 3) {
+ if (pitch + 3 < pitch) {
+ SDL_SetError("A scanline is too wide");
+ return(0);
+ }
+ pitch = (pitch + 3) & ~3;
+ }
+ if (pitch > 0xFFFF) {
+ SDL_SetError("A scanline is too wide");
+ return(0);
+ }
+ return((Uint16)pitch);
}
/*
* Match an RGB value to a particular palette index