Added (optional) better scaling to readscaled
diff --git a/Modules/imgfile.c b/Modules/imgfile.c
index 7d71a35..d6a636b 100644
--- a/Modules/imgfile.c
+++ b/Modules/imgfile.c
@@ -29,6 +29,8 @@
 ** image files in a neater way (so you can get rgb images off a greyscale
 ** file, for instance, or do a straight display without having to get the
 ** image bits into python, etc).
+**
+** Warning: this module is very non-reentrant (esp. the readscaled stuff)
 */
 
 #include "allobjects.h"
@@ -37,6 +39,8 @@
 #include <gl/image.h>
 #include <errno.h>
 
+#include <izoom.h>
+
 static object * ImgfileError; /* Exception we raise for various trouble */
 
 
@@ -158,6 +162,78 @@
     return rv;
 }
 
+IMAGE *glob_image;
+long *glob_datap;
+int glob_width, glob_z;
+
+static
+xs_get(buf, y)
+    short *buf;
+    int y;
+{
+    getrow(glob_image, buf, y, glob_z);
+}
+
+static
+xs_put_c(buf, y)
+    short *buf;
+    int y;
+{
+    char *datap = (char *)glob_datap + y*glob_width;
+    int width = glob_width;
+
+    while ( width-- )
+      *datap++ = (*buf++) & 0xff;
+}
+
+static
+xs_put_0(buf, y)
+    short *buf;
+    int y;
+{
+    long *datap = glob_datap + y*glob_width;
+    int width = glob_width;
+
+    while ( width-- )
+      *datap++ = (*buf++) & 0xff;
+}
+static
+xs_put_12(buf, y)
+    short *buf;
+    int y;
+{
+    long *datap = glob_datap + y*glob_width;
+    int width = glob_width;
+
+    while ( width-- )
+      *datap++ |= ((*buf++) & 0xff) << (glob_z*8);
+}
+
+static void
+xscale(image, xsize, ysize, zsize, datap, xnew, ynew, fmode, blur)
+    IMAGE *image;
+    int xsize, ysize, zsize;
+    long *datap;
+    int xnew, ynew;
+    int fmode;
+    double blur;
+{
+    glob_image = image;
+    glob_datap = datap;
+    glob_width = xnew;
+    if ( zsize == 1 ) {
+	glob_z = 0;
+	filterzoom(xs_get, xs_put_c, xsize, ysize, xnew, ynew, fmode, blur);
+    } else {
+	glob_z = 0;
+	filterzoom(xs_get, xs_put_0, xsize, ysize, xnew, ynew, fmode, blur);
+	glob_z = 1;
+	filterzoom(xs_get, xs_put_12, xsize, ysize, xnew, ynew, fmode, blur);
+	glob_z = 2;
+	filterzoom(xs_get, xs_put_12, xsize, ysize, xnew, ynew, fmode, blur);
+    }
+}
+
 
 static object *
 imgfile_readscaled(self, args)
@@ -175,10 +251,45 @@
     float xfac, yfac;
     int cnt;
     IMAGE *image;
-    
-    if ( !getargs(args, "(sii)", &fname, &xwtd, &ywtd) )
+    char *filter;
+    double blur;
+    int extended;
+    int fmode;
+
+    /*
+     ** Parse args. Funny, since arg 4 and 5 are optional
+     ** (filter name and blur factor). Also, 4 or 5 arguments indicates
+     ** extended scale algorithm in stead of simple-minded pixel drop/dup.
+     */
+    extended = 0;
+    cnt = gettuplesize(args);
+    if ( cnt == 5 ) {
+	extended = 1;
+	if ( !getargs(args, "(siisd)", &fname, &xwtd, &ywtd, &filter, &blur) )
+	  return NULL;
+    } else if ( cnt == 4 ) {
+	extended = 1;
+	if ( !getargs(args, "(siis)", &fname, &xwtd, &ywtd, &filter) )
+	  return NULL;
+	blur = 1.0;
+    } else if ( !getargs(args, "(sii)", &fname, &xwtd, &ywtd) )
       return NULL;
 
+    /*
+     ** Check parameters, open file and check type, rows, etc.
+     */
+    if ( extended ) {
+	if ( strcmp(filter, "impulse") == 0 ) fmode = IMPULSE;
+	else if ( strcmp( filter, "box") == 0 ) fmode = BOX;
+	else if ( strcmp( filter, "triangle") == 0 ) fmode = TRIANGLE;
+	else if ( strcmp( filter, "quadratic") == 0 ) fmode = QUADRATIC;
+	else if ( strcmp( filter, "gaussian") == 0 ) fmode = GAUSSIAN;
+	else {
+	    err_setstr(ImgfileError, "Unknown filter type");
+	    return NULL;
+	}
+    }
+    
     if ( (image = imgfile_open(fname)) == NULL )
       return NULL;
     
@@ -209,30 +320,35 @@
     if ( zsize == 3 ) zsize = 4;
     rv = newsizedstringobject(NULL, xwtd*ywtd*zsize);
     if ( rv == NULL ) {
-      iclose(image);
-      return NULL;
+	iclose(image);
+	return NULL;
     }
     xfac = (float)xsize/(float)xwtd;
     yfac = (float)ysize/(float)ywtd;
     cdatap = getstringvalue(rv);
     idatap = (long *)cdatap;
-    for ( y=0; y < ywtd && !error_called; y++ ) {
-	yorig = (int)(y*yfac);
-	if ( zsize == 1 ) {
-	    getrow(image, rs, yorig, 0);
-	    for(x=0; x<xwtd; x++ ) {
-		*cdatap++ = rs[(int)(x*xfac)];	
-	  }
-	} else {
-	    getrow(image, rs, yorig, 0);
-	    getrow(image, gs, yorig, 1);
-	    getrow(image, bs, yorig, 2);
-	    for(x=0; x<xwtd; x++ ) {
-		xorig = (int)(x*xfac);
-		*idatap++ = (rs[xorig] & 0xff)     |
-		           ((gs[xorig] & 0xff)<<8) |
-			   ((bs[xorig] & 0xff)<<16);
-	  }
+
+    if ( extended ) {
+	xscale(image, xsize, ysize, zsize, idatap, xwtd, ywtd, fmode, blur);
+    } else {
+	for ( y=0; y < ywtd && !error_called; y++ ) {
+	    yorig = (int)(y*yfac);
+	    if ( zsize == 1 ) {
+		getrow(image, rs, yorig, 0);
+		for(x=0; x<xwtd; x++ ) {
+		    *cdatap++ = rs[(int)(x*xfac)];	
+		}
+	    } else {
+		getrow(image, rs, yorig, 0);
+		getrow(image, gs, yorig, 1);
+		getrow(image, bs, yorig, 2);
+		for(x=0; x<xwtd; x++ ) {
+		    xorig = (int)(x*xfac);
+		    *idatap++ = (rs[xorig] & 0xff)     |
+		      ((gs[xorig] & 0xff)<<8) |
+			((bs[xorig] & 0xff)<<16);
+		}
+	    }
 	}
     }
     iclose(image);
@@ -243,7 +359,6 @@
     return rv;
 }
 
-
 static object *
 imgfile_getsizes(self, args)
     object *self;
@@ -263,7 +378,6 @@
     return rv;
 }
 
-
 static object *
 imgfile_write(self, args)
     object *self;
@@ -343,7 +457,7 @@
 static struct methodlist imgfile_methods[] = {
     { "getsizes",	imgfile_getsizes },
     { "read",		imgfile_read },
-    { "readscaled",	imgfile_readscaled },
+    { "readscaled",	imgfile_readscaled, 1},
     { "write",		imgfile_write },
     { NULL,		NULL } /* Sentinel */
 };