3232
3333#include <math.h>
3434#include <string.h>
35+ #include <limits.h>
3536
3637#include "simd_shared.h"
3738#include "simd_transform.h"
@@ -4225,96 +4226,14 @@ surf_invert(PyObject *self, PyObject *args, PyObject *kwargs)
42254226 return (PyObject * )pgSurface_New (newsurf );
42264227}
42274228
4228- SDL_Surface *
4229- pixelate (pgSurfaceObject * srcobj , pgSurfaceObject * dstobj , int pixel_size )
4230- {
4231- SDL_Surface * src = pgSurface_AsSurface (srcobj );
4232- SDL_Surface * newsurf ;
4233-
4234- if (!dstobj ) {
4235- newsurf = newsurf_fromsurf (src , srcobj -> surf -> w , srcobj -> surf -> h );
4236- if (!newsurf )
4237- return NULL ;
4238- }
4239- else {
4240- newsurf = pgSurface_AsSurface (dstobj );
4241- }
4242-
4243- if (pixel_size < 1 ) {
4244- return (SDL_Surface * )(RAISE (PyExc_ValueError ,
4245- "pixel_size must be greater than 0." ));
4246- }
4247-
4248- if (newsurf -> w != src -> w || newsurf -> h != src -> h ) {
4249- return (SDL_Surface * )(RAISE (
4250- PyExc_ValueError ,
4251- "Destination surface must be the same size as source surface." ));
4252- }
4253-
4254- if (src -> format -> BytesPerPixel != newsurf -> format -> BytesPerPixel ) {
4255- return (SDL_Surface * )(RAISE (
4256- PyExc_ValueError ,
4257- "Source and destination surfaces need the same format." ));
4258- }
4259-
4260- int x , y ;
4261- for (y = 0 ; y < src -> h ; y += pixel_size ) {
4262- for (x = 0 ; x < src -> w ; x += pixel_size ) {
4263- unsigned char r , g , b , a ; // current
4264- Uint32 ra , ga , ba , aa ; // averages
4265- Uint16 size ;
4266- Uint32 color , average ;
4267- Uint8 * pix ;
4268- int width = (pixel_size > (src -> w - x )) ? src -> w - x : pixel_size ;
4269- int height = (pixel_size > (src -> h - y )) ? src -> h - y : pixel_size ;
4270-
4271- ra = 0 ;
4272- ga = 0 ;
4273- ba = 0 ;
4274- aa = 0 ;
4275- for (int w = 0 ; w < width ; w ++ ) {
4276- for (int h = 0 ; h < height ; h ++ ) {
4277- SURF_GET_AT (color , src , x + w , y + h , (Uint8 * )src -> pixels ,
4278- src -> format , pix );
4279- SDL_GetRGBA (color , src -> format , & r , & g , & b , & a );
4280- ra += r ;
4281- ga += g ;
4282- ba += b ;
4283- aa += a ;
4284- }
4285- }
4286- size = width * height ;
4287-
4288- average = SDL_MapRGBA (newsurf -> format , (Uint8 )(ra / size ),
4289- (Uint8 )(ga / size ), (Uint8 )(ba / size ),
4290- (Uint8 )(aa / size ));
4291-
4292- for (int w = 0 ; w < width ; w ++ ) {
4293- for (int h = 0 ; h < height ; h ++ ) {
4294- SURF_SET_AT (average , newsurf , x + w , y + h ,
4295- (Uint8 * )newsurf -> pixels , newsurf -> format ,
4296- pix );
4297- }
4298- }
4299- }
4300- }
4301-
4302- SDL_UnlockSurface (newsurf );
4303-
4304- return newsurf ;
4305- }
4306-
4307- /*
4308- * anticipated API: pygame.transform.pixelate(surface, pixel_size, dest_surface
4309- * = None)
4310- */
43114229static PyObject *
43124230surf_pixelate (PyObject * self , PyObject * args , PyObject * kwargs )
43134231{
43144232 pgSurfaceObject * src ;
43154233 pgSurfaceObject * dst = NULL ;
43164234 int pixel_size ;
43174235 SDL_Surface * new_surf ;
4236+ pgSurfaceObject * intermediate ;
43184237
43194238 static char * kwds [] = {"surface" , "pixel_size" , "dest_surface" , NULL };
43204239
@@ -4324,12 +4243,36 @@ surf_pixelate(PyObject *self, PyObject *args, PyObject *kwargs)
43244243 return NULL ;
43254244 }
43264245
4327- new_surf = pixelate (src , dst , pixel_size );
4246+ double testWidth = round ((double )src -> surf -> w / pixel_size );
4247+ double testHeight = round ((double )src -> surf -> h / pixel_size );
43284248
4329- if (!new_surf ) {
4249+ if (testWidth > INT_MAX || testWidth <= 0 )
4250+ {
4251+ PyErr_SetString (PyExc_OverflowError , "Cannot scale width outside the range [0, INT_MAX]" );
4252+ return NULL ;
4253+ }
4254+
4255+ if (testHeight > INT_MAX || testHeight <= 0 )
4256+ {
4257+ PyErr_SetString (PyExc_OverflowError , "Cannot scale height outside the range [0, INT_MAX]" );
43304258 return NULL ;
43314259 }
43324260
4261+ int width = (int )testWidth ;
4262+ int height = (int )testHeight ;
4263+
4264+ SDL_Surface * temp = scale_to (src , NULL , width , height );
4265+ intermediate = pgSurface_New (temp );
4266+ if (intermediate == NULL )
4267+ {
4268+ return NULL ; /* Exception already set in scale_to */
4269+ }
4270+ new_surf = scale_to (intermediate , dst , src -> surf -> w , src -> surf -> h );
4271+ if (new_surf == NULL )
4272+ {
4273+ return NULL ; /* Exception already set in scale_to */
4274+ }
4275+
43334276 if (dst ) {
43344277 Py_INCREF (dst );
43354278 return (PyObject * )dst ;
0 commit comments