diff -r 9fcb7abf3185 src/transform.c
--- a/src/transform.c	Tue Apr 23 19:53:36 2013 -0700
+++ b/src/transform.c	Wed Jun 05 08:34:50 2013 +0200
@@ -31,6 +31,9 @@
 #include <string.h>
 #include "scale.h"
 
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
 
 typedef void (* SMOOTHSCALE_FILTER_P)(Uint8 *, Uint8 *, int, int, int, int, int);
 struct _module_state {
@@ -2624,10 +2627,10 @@
 }
 
 
-void average_color(SDL_Surface* surf, int x, int y, int width, int height, Uint8* r, Uint8* g, Uint8* b, Uint8* a) {
+void average_color(SDL_Surface* surf, int left, int right, int top, int bottom, int size, Uint8* r, Uint8* g, Uint8* b, Uint8* a) {
     Uint32 color, rmask, gmask, bmask, amask;
     Uint8 *pixels, *pix;
-    unsigned int rtot, gtot, btot, atot, size, rshift, gshift, bshift, ashift;
+    unsigned int rtot, gtot, btot, atot, rshift, gshift, bshift, ashift;
     unsigned int rloss, gloss, bloss, aloss;
     int row, col;
     
@@ -2647,30 +2650,12 @@
     bloss = format->Bloss;
     aloss = format->Aloss;
     rtot = gtot = btot = atot = 0;
-    
-    /* make sure the area specified is within the Surface */
-    if ((x + width) > surf->w)
-        width = surf->w - x;
-    if ((y + height) > surf->h)
-        height = surf->h - y;
-    if (x < 0)
-    {
-        width -= (-x);
-        x = 0;
-    }
-    if (y < 0)
-    {
-        height -= (-y);
-        y = 0;
-    }
-    
-    size = width*height;
 
     switch (format->BytesPerPixel) {
         case 1:
-            for (row = y; row < y+height; row++) {
-                pixels = (Uint8 *) surf->pixels + row*surf->pitch + x;
-                for (col = x; col < x+width; col++) {
+            for (row = top; row < bottom; row++) {
+                pixels = (Uint8 *) surf->pixels + row*surf->pitch + left;
+                for (col = left; col < right; col++) {
                     color = (Uint32)*((Uint8 *) pixels);
                     rtot += ((color & rmask) >> rshift) << rloss;
                     gtot += ((color & gmask) >> gshift) << gloss;
@@ -2681,9 +2666,9 @@
             }
             break;    
         case 2:
-            for (row = y; row < y+height; row++) {
-                pixels = (Uint8 *) surf->pixels + row*surf->pitch + x*2;
-                for (col = x; col < x+width; col++) {
+            for (row = top; row < bottom; row++) {
+                pixels = (Uint8 *) surf->pixels + row*surf->pitch + left*2;
+                for (col = left; col < right; col++) {
                     color = (Uint32)*((Uint16 *) pixels);
                     rtot += ((color & rmask) >> rshift) << rloss;
                     gtot += ((color & gmask) >> gshift) << gloss;
@@ -2694,9 +2679,9 @@
             }
             break;    
         case 3:
-            for (row = y; row < y+height; row++) {
-                pixels = (Uint8 *) surf->pixels + row*surf->pitch + x*3;
-                for (col = x; col < x+width; col++) {
+            for (row = top; row < bottom; row++) {
+                pixels = (Uint8 *) surf->pixels + row*surf->pitch + left*3;
+                for (col = left; col < right; col++) {
                     pix = pixels;
 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
                     color = (pix[0]) + (pix[1] << 8) + (pix[2] << 16);
@@ -2712,9 +2697,9 @@
             }                    
             break;
         default:                  /* case 4: */
-            for (row = y; row < y+height; row++) {
-                pixels = (Uint8 *) surf->pixels + row*surf->pitch + x*4;
-                for (col = x; col < x+width; col++) {
+            for (row = top; row < bottom; row++) {
+                pixels = (Uint8 *) surf->pixels + row*surf->pitch + left*4;
+                for (col = left; col < right; col++) {
                     color = *(Uint32 *)pixels;
                     rtot += ((color & rmask) >> rshift) << rloss;
                     gtot += ((color & gmask) >> gshift) << gloss;
@@ -2737,7 +2722,7 @@
     SDL_Surface* surf;
     GAME_Rect* rect, temp;
     Uint8 r, g, b, a;
-    int x, y, w, h;
+    int left, right, top, bottom, size;
 
     if (!PyArg_ParseTuple (arg, "O!|O", &PySurface_Type, &surfobj, &rectobj))
         return NULL;
@@ -2746,21 +2731,26 @@
     PySurface_Lock (surfobj);
 
     if (!rectobj) {
-        x = 0;
-        y = 0;
-        w = surf->w;
-        h = surf->h;
+        left   = 0;
+        top    = 0;
+        right  = surf->w;
+        bottom = surf->h;
     } else {
         if (!(rect = GameRect_FromObject (rectobj, &temp)))
             return RAISE (PyExc_TypeError, "Rect argument is invalid");
-        x = rect->x;
-        y = rect->y;
-        w = rect->w;
-        h = rect->h;
-    }            
+        /* make sure the area specified is within the Surface */
+        left   = MAX( rect->x, 0 );
+        right  = MIN( rect->x + rect->w, surf->w );
+        top    = MAX( rect->y, 0 );
+        bottom = MIN( rect->y + rect->h, surf->h );
+    }
+    /* determine total number of pixels in the clipped rectangle */
+    size = ( right - left ) * ( bottom - top );
+    if ( size == 0 )
+        return RAISE (PyExc_ValueError, "rectangle has zero width or height");
 
     Py_BEGIN_ALLOW_THREADS;    
-    average_color(surf, x, y, w, h, &r, &g, &b, &a);
+    average_color(surf, left, right, top, bottom, size, &r, &g, &b, &a);
     Py_END_ALLOW_THREADS;
 
     PySurface_Unlock (surfobj);
