* Extended X interface: pixmap objects, colormap objects visual objects,
  image objects, and lots of new methods.
* Added counting of allocations and deallocations of builtin types if
  COUNT_ALLOCS is defined.  Had to move calls to NEWREF down in some
  files.
* Bug fix in sorting lists.
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index b5a2cfa..93c0735 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -252,10 +252,10 @@
 			return err_nomem();
 		}
 	}
-	NEWREF(op);
 	op->ob_type = &Arraytype;
 	op->ob_size = size;
 	op->ob_descr = descr;
+	NEWREF(op);
 	return (object *) op;
 }
 
diff --git a/Modules/config.c.in b/Modules/config.c.in
index 484381e..f19655f 100644
--- a/Modules/config.c.in
+++ b/Modules/config.c.in
@@ -310,6 +310,9 @@
 #ifdef USE_HTML
 extern void initHTML();
 #endif
+#ifdef USE_XLIB
+extern void initXlib();
+#endif
 /* -- ADDMODULE MARKER 1 -- */
 
 struct {
@@ -485,6 +488,10 @@
 	{"HTML", initHTML},
 #endif
 
+#ifdef USE_XLIB
+       {"Xlib", initXlib},
+#endif
+
 /* -- ADDMODULE MARKER 2 -- */
 
 	{0,		0}		/* Sentinel */
diff --git a/Modules/imageop.c b/Modules/imageop.c
index 40940cb..841ec1b 100644
--- a/Modules/imageop.c
+++ b/Modules/imageop.c
@@ -542,9 +542,15 @@
     for ( i=0; i < nlen; i++ ) {
 	/* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
 	value = *cp++;
+#if 0
 	r = (value >>  5) & 7;
 	g = (value >> 13) & 7;
 	b = (value >> 22) & 3;
+#else
+	r = (int) ((value & 0xff) / 255. * 7. + .5);
+	g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
+	b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
+#endif
 	nvalue = (r<<5) | (b<<3) | g;
 	*ncp++ = nvalue;
     }
diff --git a/Modules/imgfile.c b/Modules/imgfile.c
index 93f5ef3..e57d6c4 100644
--- a/Modules/imgfile.c
+++ b/Modules/imgfile.c
@@ -43,6 +43,7 @@
 
 static object * ImgfileError; /* Exception we raise for various trouble */
 
+static int top_to_bottom;	/* True if we want top-to-bottom images */
 
 /* The image library does not always call the error hander :-(,
    therefore we have a global variable indicating that it was called.
@@ -86,6 +87,20 @@
     return image;
 }
 
+static object *
+imgfile_ttob(self, args)
+    object *self;
+    object *args;
+{
+    int newval;
+    object *rv;
+    
+    if (!getargs(args, "i", &newval))
+      return NULL;
+    rv = newintobject(top_to_bottom);
+    top_to_bottom = newval;
+    return rv;
+}
 
 static object *
 imgfile_read(self, args)
@@ -100,7 +115,8 @@
     static short rs[8192], gs[8192], bs[8192];
     int x, y;
     IMAGE *image;
-    
+    int yfirst, ylast, ystep;
+
     if ( !getargs(args, "s", &fname) )
       return NULL;
     
@@ -139,7 +155,17 @@
     }
     cdatap = getstringvalue(rv);
     idatap = (long *)cdatap;
-    for ( y=0; y < ysize && !error_called; y++ ) {
+
+    if (top_to_bottom) {
+	yfirst = ysize-1;
+	ylast = -1;
+	ystep = -1;
+    } else {
+	yfirst = 0;
+	ylast = ysize;
+	ystep = 1;
+    }
+    for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
 	if ( zsize == 1 ) {
 	    getrow(image, rs, y, 0);
 	    for(x=0; x<xsize; x++ )
@@ -164,14 +190,17 @@
 
 static IMAGE *glob_image;
 static long *glob_datap;
-static int glob_width, glob_z;
+static int glob_width, glob_z, glob_ysize;
 
 static
 xs_get(buf, y)
     short *buf;
     int y;
 {
-    getrow(glob_image, buf, y, glob_z);
+    if (top_to_bottom)
+      getrow(glob_image, buf, (glob_ysize-1-y), glob_z);
+    else
+      getrow(glob_image, buf, y, glob_z);
 }
 
 static
@@ -221,6 +250,7 @@
     glob_image = image;
     glob_datap = datap;
     glob_width = xnew;
+    glob_ysize = ysize;
     if ( zsize == 1 ) {
 	glob_z = 0;
 	filterzoom(xs_get, xs_put_c, xsize, ysize, xnew, ynew, fmode, blur);
@@ -255,6 +285,7 @@
     double blur;
     int extended;
     int fmode;
+    int yfirst, ylast, ystep;
 
     /*
      ** Parse args. Funny, since arg 4 and 5 are optional
@@ -331,7 +362,16 @@
     if ( extended ) {
 	xscale(image, xsize, ysize, zsize, idatap, xwtd, ywtd, fmode, blur);
     } else {
-	for ( y=0; y < ywtd && !error_called; y++ ) {
+	if (top_to_bottom) {
+	    yfirst = ywtd-1;
+	    ylast = -1;
+	    ystep = -1;
+	} else {
+	    yfirst = 0;
+	    ylast = ywtd;
+	    ystep = 1;
+	}
+	for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
 	    yorig = (int)(y*yfac);
 	    if ( zsize == 1 ) {
 		getrow(image, rs, yorig, 0);
@@ -392,6 +432,8 @@
     short r, g, b;
     long rgb;
     int x, y;
+    int yfirst, ylast, ystep;
+
 
     if ( !getargs(args, "(ss#iii)",
 		  &fname, &cdatap, &len, &xsize, &ysize, &zsize) )
@@ -425,7 +467,16 @@
 
     idatap = (long *)cdatap;
     
-    for( y=0; y<ysize && !error_called; y++ ) {
+    if (top_to_bottom) {
+	yfirst = ysize-1;
+	ylast = -1;
+	ystep = -1;
+    } else {
+	yfirst = 0;
+	ylast = ysize;
+	ystep = 1;
+    }
+    for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
 	if ( zsize == 1 ) {
 	    for( x=0; x<xsize; x++ )
 	      rs[x] = *cdatap++;
@@ -459,6 +510,7 @@
     { "read",		imgfile_read },
     { "readscaled",	imgfile_readscaled, 1},
     { "write",		imgfile_write },
+    { "ttob",		imgfile_ttob },
     { NULL,		NULL } /* Sentinel */
 };