@@ -4225,6 +4225,116 @@ surf_invert(PyObject *self, PyObject *args, PyObject *kwargs)
42254225 return (PyObject * )pgSurface_New (newsurf );
42264226}
42274227
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 (newsurf -> w != src -> w || newsurf -> h != src -> h ) {
4244+ return (SDL_Surface * )(RAISE (
4245+ PyExc_ValueError ,
4246+ "Destination surface must be the same size as source surface." ));
4247+ }
4248+
4249+ if (src -> format -> BytesPerPixel != newsurf -> format -> BytesPerPixel ) {
4250+ return (SDL_Surface * )(RAISE (
4251+ PyExc_ValueError ,
4252+ "Source and destination surfaces need the same format." ));
4253+ }
4254+
4255+ int x , y ;
4256+ for (y = 0 ; y < src -> h ; y += pixel_size ) {
4257+ for (x = 0 ; x < src -> w ; x += pixel_size ) {
4258+ unsigned char r , g , b , a ; // current
4259+ Uint64 ra , ga , ba , aa ; // averages
4260+ Uint64 size ;
4261+ Uint32 color , average ;
4262+ Uint8 * pix ;
4263+ int width = min (pixel_size , src -> w - x );
4264+ int height = min (pixel_size , src -> h - y );
4265+
4266+ ra = 0 ;
4267+ ga = 0 ;
4268+ ba = 0 ;
4269+ aa = 0 ;
4270+ for (int w = 0 ; w < width ; w ++ ) {
4271+ for (int h = 0 ; h < height ; h ++ ) {
4272+ SURF_GET_AT (color , src , x + w , y + h , (Uint8 * )src -> pixels ,
4273+ src -> format , pix );
4274+ SDL_GetRGBA (color , src -> format , & r , & g , & b , & a );
4275+ ra += r ;
4276+ ga += g ;
4277+ ba += b ;
4278+ aa += a ;
4279+ }
4280+ }
4281+ size = width * height ;
4282+ ra /= size ;
4283+ ga /= size ;
4284+ ba /= size ;
4285+ aa /= size ;
4286+
4287+ average = SDL_MapRGBA (newsurf -> format , ra , ga , ba , aa );
4288+
4289+ printf ("%u\n" , average );
4290+ for (int w = 0 ; w < width ; w ++ ) {
4291+ for (int h = 0 ; h < height ; h ++ ) {
4292+ SURF_SET_AT (average , newsurf , x + w , y + h ,
4293+ (Uint8 * )newsurf -> pixels , newsurf -> format ,
4294+ pix );
4295+ }
4296+ }
4297+ }
4298+ }
4299+
4300+ SDL_UnlockSurface (newsurf );
4301+
4302+ return newsurf ;
4303+ }
4304+
4305+ /*
4306+ * anticipated API: pygame.transform.pixelate(surface, pixel_size, dest_surface
4307+ * = None)
4308+ */
4309+ static PyObject *
4310+ surf_pixelate (PyObject * self , PyObject * args , PyObject * kwargs )
4311+ {
4312+ pgSurfaceObject * src ;
4313+ pgSurfaceObject * dst = NULL ;
4314+ int pixel_size ;
4315+ SDL_Surface * new_surf ;
4316+
4317+ static char * kwds [] = {"surface" , "pixel_size" , "dest_surface" , NULL };
4318+
4319+ if (!PyArg_ParseTupleAndKeywords (args , kwargs , "O!i|O!" , kwds ,
4320+ & pgSurface_Type , & src , & pixel_size ,
4321+ & pgSurface_Type , & dst )) {
4322+ return NULL ;
4323+ }
4324+
4325+ new_surf = pixelate (src , dst , pixel_size );
4326+
4327+ if (!new_surf ) {
4328+ return NULL ;
4329+ }
4330+
4331+ if (dst ) {
4332+ Py_INCREF (dst );
4333+ return (PyObject * )dst ;
4334+ }
4335+ return (PyObject * )pgSurface_New (new_surf );
4336+ }
4337+
42284338static PyMethodDef _transform_methods [] = {
42294339 {"scale" , (PyCFunction )surf_scale , METH_VARARGS | METH_KEYWORDS ,
42304340 DOC_TRANSFORM_SCALE },
@@ -4268,6 +4378,8 @@ static PyMethodDef _transform_methods[] = {
42684378 METH_VARARGS | METH_KEYWORDS , DOC_TRANSFORM_SOLIDOVERLAY },
42694379 {"hsl" , (PyCFunction )surf_hsl , METH_VARARGS | METH_KEYWORDS ,
42704380 DOC_TRANSFORM_HSL },
4381+ {"pixelate" , (PyCFunction )surf_pixelate , METH_VARARGS | METH_KEYWORDS ,
4382+ DOC_TRANSFORM_PIXELATE },
42714383 {NULL , NULL , 0 , NULL }};
42724384
42734385MODINIT_DEFINE (transform )
0 commit comments