Fixed bug 3340 - SDL_BlitScaled causes access violation in some cases.
authorSam Lantinga <slouken@libsdl.org>
Wed, 30 Nov 2016 22:06:05 -0800
changeset 106681889c850fafc
parent 10667 dc4629395bea
child 10669 70a77b67e8e2
Fixed bug 3340 - SDL_BlitScaled causes access violation in some cases.

Simon Hug

The SDL_BlitScaled function runs into an access violation for specific blit coordinates and surface sizes. The attached testcase blits a 800x600 surface to a 1280x720 surface at the coordinates -640,-345 scaled to 1280x720. The blit function that moves the data then runs over and reads after the pixel data from the src surface causing an access violation.

I can't say where exactly it goes wrong, but I think it could have something to do with the rounding in SDL_UpperBlitScaled. final_src.y is 288 and final_src.h is 313. Together that's 601, which I believe is one too much, but I just don't know the code enough to make sure that's the problem.

Sylvain

I think this patch fix the issue, but maybe it's worth re-writing "SDL_UpperBlitScaled" using SDL_FRect.
src/video/SDL_surface.c
     1.1 --- a/src/video/SDL_surface.c	Wed Nov 30 12:58:03 2016 -0800
     1.2 +++ b/src/video/SDL_surface.c	Wed Nov 30 22:06:05 2016 -0800
     1.3 @@ -778,8 +778,8 @@
     1.4  
     1.5      final_src.x = (int)SDL_floor(src_x0 + 0.5);
     1.6      final_src.y = (int)SDL_floor(src_y0 + 0.5);
     1.7 -    final_src.w = (int)SDL_floor(src_x1 - src_x0 + 1.5);
     1.8 -    final_src.h = (int)SDL_floor(src_y1 - src_y0 + 1.5);
     1.9 +    final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
    1.10 +    final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
    1.11  
    1.12      final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
    1.13      final_dst.y = (int)SDL_floor(dst_y0 + 0.5);