diff -urN old_x11/idiconv.c x11/idiconv.c
--- old_x11/idiconv.c	Wed Dec 31 18:00:00 1969
+++ x11/idiconv.c	Thu Nov 30 09:59:40 2000
@@ -0,0 +1,427 @@
+/* @(#)idilocal1.c	13.3 (ESO-DMD) 08/21/98 16:09:08 */
+/*===========================================================================
+  Copyright (C) 2000 Craig B. Markwardt
+ 
+  This program is free software; you can redistribute it and/or 
+  modify it under the terms of the GNU General Public License as 
+  published by the Free Software Foundation; either version 2 of 
+  the License, or (at your option) any later version.
+ 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public 
+  License along with this program; if not, write to the Free 
+  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
+  MA 02139, USA.
+ 
+  Correspondence concerning ESO-MIDAS should be addressed as follows:
+	Internet e-mail: midas@eso.org
+	Postal address: European Southern Observatory
+			Data Management Division 
+			Karl-Schwarzschild-Strasse 2
+			D 85748 Garching bei Muenchen 
+			GERMANY
+===========================================================================*/
+
+/***********************************************************************
+*                                                               
+*   file idiconv.c
+*                                                                 
+*   IDI  Device Dependent Routines                                 
+*   (version for XWindows release 11)                               
+*                                                                    
+*
+* V 1.00 001129: C. Markwardt - conversions for 24- and 16-bit visuals
+*
+*   get_plane_offset     : convert bitmask to a shift offset
+*   idi_conv32_24        : convert 32-bit RGB to 24-bit RGB
+*   idi_conv24_32        : convert 24-bit RGB to 32-bit RGB
+*   idi_conv32_16        : convert 32-bit RGB to 16-bit RGB
+*   idi_conv16_32        : convert 16-bit RGB to 32-bit RGB
+*   idi_putimage         : wrapper for XPutImage
+*   idi_getsubimage      : wrapper for XGetSubImage
+*   
+************************************************************************/
+
+/*
+
+*/
+
+#include    <stdlib.h>
+
+#include    <idi.h>
+#include    <idistruct.h>
+#include    <x11defs.h>
+
+
+/* Determine the shift to apply to 8-bit data to align with "mask" */
+int
+get_plane_offset(mask, wordsize)
+     unsigned int mask, wordsize;
+{
+  int i;
+  for (i=31; i>=0; i--)
+    if ( (mask>>i) & 1 ) return (i+1-wordsize);
+  return 0;
+}
+
+
+/* Convert 32-bit input to 24-bit output.  The image data sizes are
+   the same, hence each line output line will be padded by 25%.  Note
+   that this function allocates memory which must be freed by the
+   caller. */
+unsigned char *idi_conv32_24(image, src)
+     XImage *image;
+     unsigned char *src;
+{
+  unsigned char *dst, *p, *q;
+  unsigned int nbytes;
+  unsigned int test = 0x000000ff;
+  unsigned char *ptest = (unsigned char *)&test;
+  int lend;
+  int j, i;
+
+  if ( *ptest == 0xff ) lend = 1; else lend = 0;
+
+  /* Allocate a destination image */
+  nbytes = image->bytes_per_line*image->height;
+  dst = malloc(nbytes);
+  if (dst == 0) 
+    return 0;
+
+  /* Zero the new image data */
+  q = dst;
+  for (i=0; i<nbytes; i++) 
+    *q++ = 0;
+  
+  for (j=0; j<image->height; j++) {
+    p = src + image->bytes_per_line*j;
+    q = dst + image->bytes_per_line*j;
+    /* Note that for 24-bit data, all we have to do is copy the 3
+       lsb's and discard the msb, while otherwise preserving the byte
+       order. */
+    if (lend) {
+      /* Little-endian - discard msb at end of each source word */
+      for (i=0; i<image->width; i++) {
+	*q++ = *p++;   *q++ = *p++;   *q++ = *p++;
+	p++;
+      } 
+    } else {
+      /* Big-endian - discard msb at beginning of each source word */
+      for (i=0; i<image->width; i++) {
+	p++;
+	*q++ = *p++;   *q++ = *p++;   *q++ = *p++;
+      } 
+    }
+  }
+
+  return dst;
+}
+
+/* Convert 24-bit input to 32-bit output.  The image data sizes are
+   the same, hence each input line must be padded by 25%.  Note that
+   this function allocates memory which must be freed by the
+   caller. */
+unsigned char *idi_conv24_32(image, src)
+     XImage *image;
+     unsigned char *src;
+{
+  unsigned char *dst, *p, *q;
+  unsigned int nbytes;
+  unsigned int test = 0x000000ff;
+  unsigned char *ptest = (unsigned char *)&test;
+  int lend;
+  int j, i;
+
+  /* Test for endian-ness */
+  if ( *ptest == 0xff ) lend = 1; else lend = 0;
+#if 0
+  fprintf(stderr, "%s-endian\n", lend?"little":"big");
+  fprintf(stderr, "red_mask   = 0x%08x\n", image->red_mask);
+  fprintf(stderr, "green_mask = 0x%08x\n", image->green_mask);
+  fprintf(stderr, "blue_mask  = 0x%08x\n", image->blue_mask);
+#endif
+
+  /* Allocate a destination image */
+  nbytes = image->bytes_per_line*image->height;
+  dst = malloc(nbytes);
+  if (dst == 0) 
+    return 0;
+  
+  /* Zero the new image data */
+  q = dst;
+  for (i=0; i<nbytes; i++) 
+    *q++ = 0;
+  
+  for (j=0; j<image->height; j++) {
+    p = src + image->bytes_per_line*j;
+    q = dst + image->bytes_per_line*j;
+    /* Note that for 24-bit data, all we have to do is copy the 3
+       lsb's and discard the msb, while otherwise preserving the byte
+       order. */
+    if (lend > 0) {
+      /* Little-endian - insert msb at end of each dest word */
+      for (i=0; i<image->width; i++) {
+	*q++ = *p++;   *q++ = *p++;   *q++ = *p++;
+	q++;
+      } 
+    } else {
+      /* Big-endian - insert msb at beginning of each dest word */
+      for (i=0; i<image->width; i++) {
+	q++;
+	*q++ = *p++;   *q++ = *p++;   *q++ = *p++;
+      } 
+    }
+  }
+
+  return dst;
+}
+
+/* Convert 32-bit input to 16-bit output.  The image data sizes are
+   the same, hence each line output line will be padded by 50%.  Note
+   that this function allocates memory which must be freed by the
+   caller. Also, the conversion from 24-bit to 16-bit is inherently
+   lossy. */
+unsigned char *idi_conv32_16(image, src, wordsize)
+     XImage *image;
+     unsigned char *src;
+     unsigned int wordsize;
+{
+  unsigned char *dst, *p, *q;
+  unsigned short int *qi;
+  unsigned int *pi;
+  unsigned int nbytes;
+  unsigned char r, g, b;
+  unsigned int rm, gm, bm;   /* Red green and blue masks */
+  unsigned int ro, go, bo;   /* Red green and blue mask offsets */
+  unsigned int word;
+  int j, i;
+
+  rm = image->red_mask;
+  gm = image->green_mask;
+  bm = image->blue_mask;
+  ro = get_plane_offset(rm, wordsize);
+  go = get_plane_offset(gm, wordsize);
+  bo = get_plane_offset(bm, wordsize);
+  if (ro < 0 || go < 0 || bo < 0) 
+    return 0;
+#if 0
+  fprintf(stderr, "red_offset=%d red_mask=0x%08x\n", ro, rm);
+  fprintf(stderr, "green_offset=%d green_mask=0x%08x\n", go, gm);
+  fprintf(stderr, "blue_offset=%d blue_mask=0x%08x\n", bo, bm);
+#endif
+
+  /* Allocate a destination image */
+  nbytes = image->bytes_per_line*image->height;
+  dst = malloc(nbytes);
+  if (dst == 0) 
+    return 0;
+  
+  for (i=0, q=dst; i<nbytes; i++) 
+    *q++ = 0;
+  
+  for (j=0; j<image->height; j++) {
+    p = src + image->bytes_per_line*j;
+    q = dst + image->bytes_per_line*j;
+    pi = (unsigned int *) p;
+    qi = (unsigned short int *) q;
+    /* Note that for 16-bit output data the red element in the 24-bit
+       input data will always be in the LSB, given the way that RGBord
+       is constructed */
+    if (ro > 0) {
+      /* bo must be negative */
+      for (i=0; i<image->width; i++) {
+	word = *pi++;
+	r =  word        & 0xff;  
+	g = (word >>  8) & 0xff;
+	b = (word >> 16) & 0xff;
+	*qi++ = ((r << ro) & rm) | ((g << go) & gm) | ((b >> -bo) & bm);
+      } 
+    } else {
+      /* ro must be negative */
+      for (i=0; i<image->width; i++) {
+	word = *pi++;
+	r =  word        & 0xff;  
+	g = (word >>  8) & 0xff;
+	b = (word >> 16) & 0xff;
+	*qi++ = ((r >> -ro) & rm) | ((g << go) & gm) | ((b << bo) & bm);
+      } 
+    }
+  }
+
+  return dst;
+}
+
+/* Convert 16-bit input to 32-bit output.  The image data sizes are
+   the same, hence each input line must be padded by 50%.  Note that
+   this function allocates memory which must be freed by the
+   caller. Also, the conversion from 16-bit to 24-bit assumes that the
+   low-order bits are zero. */
+unsigned char *idi_conv16_32(image, src, wordsize)
+     XImage *image;
+     unsigned char *src;
+     unsigned int wordsize;
+{
+  unsigned char *dst, *p, *q;
+  unsigned short int *pi;
+  unsigned int *qi;
+  unsigned int nbytes;
+  unsigned char r, g, b;
+  unsigned int rm, gm, bm;   /* Red green and blue masks */
+  unsigned int ro, go, bo;   /* Red green and blue mask offsets */
+  unsigned short int word;
+  int j, i;
+
+  rm = image->red_mask;
+  gm = image->green_mask;
+  bm = image->blue_mask;
+  ro = get_plane_offset(rm, wordsize);
+  go = get_plane_offset(gm, wordsize);
+  bo = get_plane_offset(bm, wordsize);
+  if (ro < 0 || go < 0 || bo < 0) 
+    return 0;
+
+  /* Allocate a destination image */
+  nbytes = image->bytes_per_line*image->height;
+  dst = malloc(nbytes);
+  if (dst == 0) 
+    return 0;
+  
+  for (i=0, q=dst; i<nbytes; i++) 
+    *q++ = 0;
+  
+  for (j=0; j<image->height; j++) {
+    p = src + image->bytes_per_line*j;
+    q = dst + image->bytes_per_line*j;
+    pi = (unsigned short int *) p;
+    qi = (unsigned int *) q;
+    /* Note that for 16-bit input data the red element in the 24-bit
+       output data will always be in the LSB, given the way that
+       RGBord is constructed */
+    if (ro > 0) {
+      /* bo must be negative */
+      for (i=0; i<image->width; i++) {
+	word = *pi++;
+	r = (word & rm) >>  ro;
+	g = (word & gm) >>  go;
+	b = (word & bm) << -bo;
+	*qi++ = r | (g << 8) | (b << 16);
+      } 
+    } else {
+      /* ro must be negative */
+      for (i=0; i<image->width; i++) {
+	word = *pi++;
+	r = (word & rm) <<  -ro;
+	g = (word & gm) >>  go;
+	b = (word & bm) >>  bo;
+	*qi++ = r | (g << 8) | (b << 16);
+      }
+    }
+  }
+
+  return dst;
+}
+
+
+/* Wrapper for XPutImage.  The arguments are identical.  This function
+   takes an XImage either in 32-bit truecolor or 8-bit pseudocolor and
+   converts to the appropriate bitsize and depth of the output
+   drawable. No error checking is done on the arguments. */
+idi_putimage(display, draw, gc, image, sx, sy, dx, dy, width, height)
+     Display *display;
+     Drawable draw;
+     GC gc;
+     XImage *image;
+     int sx, sy, dx, dy;
+     unsigned int width, height;
+{
+  unsigned char *dst = 0;
+  unsigned char *src = (unsigned char *)image->data;
+  int allocated = 0;
+  int wordsize = 8;
+
+  /* Convert from a standard size, either 8-bit or 32-bit, to the
+     native pixel size */
+  switch (image->bits_per_pixel) {
+    /* 32-bit true-color, and 8-bit pseudo color are output immediately */
+  case 8:
+  case 32:
+    break;
+  case 16:
+    dst = idi_conv32_16(image, src, wordsize);  /* 32 bits to 16 bits */
+    break;
+  case 24:
+    dst = idi_conv32_24(image, src);            /* 32 bits to 24 bits */
+    break;
+  }
+
+  /* Temporarily insert the transformed data into the XImage, Put the
+     image, and then restore the original data */
+  if (dst) image->data = (char *) dst;
+  XPutImage(display, draw, gc, image, sx, sy, dx, dy, width, height);
+  image->data = (char *) src;
+  
+  if (dst) free(dst);
+  return;
+}
+
+/* Wrapper for XGetSubImage.  The arguments are identical.  This
+   function reads an XImage from the drawable, in the native bitsize
+   and depth of the drawable, and then converts to either an 8-bit
+   pseudocolor or 32-bit RGB image.  No error checking is done on the
+   arguments. */
+XImage *
+idi_getsubimage(display, draw, x, y, width, height, plane_mask, format, 
+		dimage, dx, dy)
+     Display *display;
+     Drawable draw;
+     int x, y;
+     unsigned int width, height;
+     unsigned long plane_mask;
+     int format;
+     XImage *dimage;
+     int dx, dy;
+{
+  XImage *image;
+  unsigned char *dst, *p, *q;
+  unsigned int nbytes, i;
+  int wordsize = 8;
+
+  /* Do the actual XGetSubImage, which will return in the native
+     depth and bit_per_pixel of the drawable */
+  image = XGetSubImage(display, draw, x, y, width, height, plane_mask, 
+			format, dimage, dx, dy);
+
+  /* Convert to a standard size, either 8-bit or 32-bit */
+  switch (image->bits_per_pixel) {
+    /* 32-bit true-color, and 8-bit pseudo color are done immediately */
+  case 8:
+  case 32:
+    return image;
+    break;
+  case 16:
+    dst = idi_conv16_32(image, image->data, wordsize); /* 16 bits to 32 bits */
+    break;
+  case 24:
+    dst = idi_conv24_32(image, image->data);           /* 24 bits to 32 bits */
+    break;
+  }
+
+  if (dst == 0) 
+    return image;
+
+  /* Now copy the "destination" image back into the original "source" */
+  nbytes = image->bytes_per_line * image->height;
+  p = dst; 
+  q = (unsigned char *) image->data;
+  for (i=0; i<nbytes; i++)
+    *q++ = *p++;
+
+  free(dst);
+  return image;
+}
+
+
diff -urN old_x11/idilocal1.c x11/idilocal1.c
--- old_x11/idilocal1.c	Tue Jun  6 07:26:32 2000
+++ x11/idilocal1.c	Thu Nov 30 09:59:40 2000
@@ -70,6 +70,9 @@
 #include    <x11defs.h>
 #include    <filedef.h>
 
+extern idi_putimage();
+extern XImage *idi_getsubimage();
+
 static unsigned int   tmpxdim, tmpydim;
 
 static int  discard = 1;
@@ -305,6 +308,10 @@
       }
 
   setup_RGB:
+   /* A 16-bit truecolor emulation of pseudo should really be >= 256 cells */
+   if (myvis[no]->class == TrueColor && Xworkst[no].depth == 16 
+       && myvis[no]->map_entries <= 256) 
+     myvis[no]->map_entries = 256;
    Xworkst[no].lutsize = myvis[no]->map_entries;
    Xworkst[no].nolut = 1;
    Xworkst[no].visual = 4;
@@ -935,7 +942,7 @@
 XSetErrorHandler(None);			/* use default Error handler */
 
 myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap,
-                     0,0,mem->xsize,mem->ysize,np,0);
+                     0,0,mem->xsize,mem->ysize,np,np*mem->xsize/8);
 
 total = myima->bytes_per_line * mem->ysize;
 myima->data = malloc((unsigned int)total);
@@ -954,7 +961,7 @@
 else
    {
    mem->pixmap = 1;
-   XPutImage(mydisp[no],mxpix[dspno][memid],gcima[dspno],
+   idi_putimage(mydisp[no],mxpix[dspno][memid],gcima[dspno],
              myima,0,0,0,0,mem->xsize,mem->ysize);
    }
 
@@ -990,7 +997,7 @@
    np = 8;
 
 myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap,
-                     0,0,mem->xsize,mem->ysize,np,0);
+                     0,0,mem->xsize,mem->ysize,np,np*mem->xsize/8);
 
 total = myima->bytes_per_line * mem->ysize;
 myima->data = malloc((unsigned int)total);
@@ -1029,7 +1036,7 @@
    /* here we create the structure + allocate memory  */
 
    myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap,
-                        0,0,tmpx,tmpy,np,0);
+                        0,0,tmpx,tmpy,np,np*tmpx/8);
 
    total = myima->bytes_per_line * tmpy;
    myima->data = malloc((unsigned int)total);
@@ -1054,7 +1061,7 @@
       }
    }
 
-hcopy[dspno] = XGetSubImage(mydisp[no],xdrawable,0,0,tmpx,tmpy,
+hcopy[dspno] = idi_getsubimage(mydisp[no],xdrawable,0,0,tmpx,tmpy,
                             np,ZPixmap,hcopy[dspno],0,0);
 XFlush(mydisp[no]);
 
@@ -1083,7 +1090,7 @@
 
       /* load image zoom mem. into the Window */
 
-      XPutImage(mydisp[no],mwndw[dspno],gcima[dspno],mzima[dspno][memid],
+      idi_putimage(mydisp[no],mwndw[dspno],gcima[dspno],mzima[dspno][memid],
                 0,0,0,0,xdim,ydim);
 
    else
@@ -1092,7 +1099,7 @@
       /* first (if flag > 1), load full image mem. into Pixmap */
 
       if (flag > 1)
-         XPutImage(mydisp[no],mxpix[dspno][memid],gcima[dspno],
+         idi_putimage(mydisp[no],mxpix[dspno][memid],gcima[dspno],
                    mzima[dspno][memid],0,0,0,0,mem->xsize,mem->ysize);
    
    
@@ -1121,7 +1128,7 @@
       /* load subwindow from image mem. into the Window
          at corner (dstx,dsty)  */
 
-      XPutImage(mydisp[no],mwndw[dspno],gcima[dspno],mxima[dspno][memid],
+      idi_putimage(mydisp[no],mwndw[dspno],gcima[dspno],mxima[dspno][memid],
                 srcx,srcy,dstx,dsty,xdim,ydim);
 
    else
@@ -1130,7 +1137,7 @@
       /* first (if flag > 1), load full image mem. into Pixmap */
 
       if (flag > 1)
-         XPutImage(mydisp[no],mxpix[dspno][memid],gcima[dspno],
+         idi_putimage(mydisp[no],mxpix[dspno][memid],gcima[dspno],
                    mxima[dspno][memid],0,0,0,0,mem->xsize,mem->ysize);
    
    
diff -urN old_x11/idilocal2.c x11/idilocal2.c
--- old_x11/idilocal2.c	Tue Jun  6 07:26:32 2000
+++ x11/idilocal2.c	Thu Nov 30 09:59:40 2000
@@ -72,6 +72,8 @@
 # include    <idistruct.h>
 # include    <x11defs.h>
 
+extern idi_putimage();
+
 static int lutoff;
 static unsigned long int  maska;
 static unsigned int   tmpxdim, tmpydim;
@@ -559,7 +561,7 @@
 else
    np = 32;
 myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap,
-                     0,0,bar->xsize,bar->ysize,np,0);
+                     0,0,bar->xsize,bar->ysize,np,np*bar->xsize/8);
 
 lutxima[dspno] = myima;
 total = myima->bytes_per_line * bar->ysize;
@@ -652,7 +654,7 @@
    }
 
 
-XPutImage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno],
+idi_putimage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno],
           0,0,0,0,bar->xsize,bar->ysize);
 k = ididev[dspno].lutsect;
 XSetWindowColormap(mydisp[no],lutwnd[dspno],cmap[no][k]);
@@ -687,7 +689,7 @@
    {
    XMoveResizeWindow(mydisp[no],lutwnd[dspno],bar->xoff,bar->yoff,
                      bar->xsize,bar->ysize);
-   XPutImage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno],
+   idi_putimage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno],
              0,0,0,0,bar->xsize,bar->ysize);
    XSetWindowColormap(mydisp[no],lutwnd[dspno],cmap[no][k]);
    }
diff -urN old_x11/idilocal3.c x11/idilocal3.c
--- old_x11/idilocal3.c	Tue Jun  6 07:26:32 2000
+++ x11/idilocal3.c	Thu Nov 30 09:59:40 2000
@@ -647,7 +647,7 @@
    if (bar != 0)			/* process color bar */
       {
       if (bar->wp != 0)
-         XPutImage(mydisp[wstno],lutwnd[dispno],gclut[dispno],
+         idi_putimage(mydisp[wstno],lutwnd[dispno],gclut[dispno],
                    lutxima[dispno],0,0,0,0,bar->xsize,bar->ysize);
       }
    conf = ididev[dispno].confptr;
@@ -765,7 +765,7 @@
                if (ididev[dspno].bar != 0)	/* process color bar */
                   {
                   if (ididev[dspno].bar->wp != 0)
-                     XPutImage(mydisp[nk],lutwnd[dspno],gclut[dspno],
+                     idi_putimage(mydisp[nk],lutwnd[dspno],gclut[dspno],
                                lutxima[dspno],0,0,0,0,
                                ididev[dspno].bar->xsize,
                                ididev[dspno].bar->ysize);
diff -urN old_x11/idiutil1.c x11/idiutil1.c
--- old_x11/idiutil1.c	Tue Jun  6 07:26:32 2000
+++ x11/idiutil1.c	Thu Nov 30 14:43:44 2000
@@ -429,37 +429,29 @@
       {
       int  rgbpix, shiftmask;
 
-      if (RGBflag == 0) 			/* work on red color */
-         {
-         for (loopi=0; loopi<iy; loopi++)
-            {
-            ipntrb = ipntra;
-            for (loopk=0; loopk<ix; loopk++)
-               {
-               pix = *ipntrb++;
-               *data++ = (unsigned char) pix;
-               }
-            ipntra += xsize;
-            }
-         }
-      else 
-         {
-         if (RGBflag == 1)			/* work on green color */
-            shiftmask = 8;
-         else					/* work on blue color */
-            shiftmask = 16;
-   
+      /* Must account for RGB ordering when returning a particular plane */
+      switch (RGBflag) 
+	{
+	case 0: /* Red color */
+	  if (Xworkst[no].RGBord == 0) shiftmask = 0; else shiftmask = 16;
+	  break;
+	case 1: /* Green color */
+	  shiftmask = 8;
+	  break;
+	case 2: /* Blue color */
+	  if (Xworkst[no].RGBord == 0) shiftmask = 16; else shiftmask = 0;
+	  break;
+	}
          for (loopi=0; loopi<iy; loopi++)
             {
             ipntrb = ipntra;
             for (loopk=0; loopk<ix; loopk++)
                {
                rgbpix = *ipntrb++;
-               *data++ = (unsigned char) (rgbpix >> shiftmask);
+               *data++ = (unsigned char) (rgbpix >> shiftmask) & 0xff;
                }
             ipntra += xsize;
             }
-         }
       }
 
    else				/* hardcopy - work on all 3 color channels */
@@ -471,7 +463,18 @@
          {
          ipntrb = ipntra;
 
-         for (loopk=0; loopk<ix; loopk++) *idata++ = *ipntrb++;
+	 /* It appears that these bytes need to be swapped for the
+	    hardcopy device, so that red is the LSB.  */
+
+	 if (Xworkst[no].RGBord == 0) 
+	   for (loopk=0; loopk<ix; loopk++) *idata++ = *ipntrb++;
+	 else 
+	   for (loopk=0; loopk<ix; loopk++) 
+	     {
+	       unsigned int word = *ipntrb++;
+	       *idata++ = ((word & 0x00ff00) | ((word & 0xff0000) >> 16)
+			   | ((word & 0x0000ff) << 16));
+	     }
 
          ipntra += xsize;
          }
@@ -486,92 +489,98 @@
    ipntra = (int *) inpntr;             /* no ITT here */
    ipntra += (yoff + xoff);
 
-   if (ittf == 0) 
-      {
-      if (hcopflg == 0)            /* no display snapshot */
-         {
-         for (loopi=0; loopi<iy; loopi++)	/* work on RED channel only */
-            {
-            ipntrb = ipntra;
-            for (loopk=0; loopk<ix; loopk++)
-               {
-               rgbpix = *ipntrb++;
-               pix = rgbpix & 0xff;
-               *data++ = (unsigned char) (pix - lutoff);
-               }
-            ipntra += xsize;
-            }
-         }
-      else			/* hardcopy - work on all 3 color channels */
-         {
-         int  *idata;
-
-         idata = (int *) data;
-         for (loopi=0; loopi<iy; loopi++)
-            {
-            ipntrb = ipntra;
-   
-            for (loopk=0; loopk<ix; loopk++) *idata++ = *ipntrb++;
-
-            ipntra += xsize;
-            }
-         }
-      }
-
-   else
-      {                                      /*  here we handle ITT data   */
-      int  kval;
-
-      if (hcopflg == 0)            /* no display snapshot */
-         {
-         for (loopi=0; loopi<iy; loopi++)       /* work on RED channel only */
-            {
-            ipntrb = ipntra;
-            for (loopk=0; loopk<ix; loopk++)
-               {
-               rgbpix = *ipntrb++;
-               pix = rgbpix & 0xff;
-               kval = pix-lutoff;
-               if (kval < 0) kval = 0;
-               *data++ = (unsigned char) (itt->val[kval]);
-               }
-            ipntra += xsize;
-            }
-         }
-
-      else
-         {
-         offset = Xworkst[no].lutlen;            /* highest colour only */
-         for (loopi=0; loopi<iy; loopi++)
-            {
-            ipntrb = ipntra;
-            for (loopk=0; loopk<ix; loopk++)
-               {
-               pix = *ipntrb++;
-               for (i=0; i<9; i++)              /* test, if fixed colour */
-                  {
-                  if (pix == Xworkst[no].fixpix[i])
-                     {
-                     *data++ = (unsigned char) (offset + i);
-                     goto nexte;
-                     }
-                  }
-
-               rgbpix = pix & 0xff;
-               kval = rgbpix - lutoff;
-               if (kval < 0) kval = 0;
-               *data++ = (unsigned char) (itt->val[kval]);
-
-             nexte:
-               ;
-
-               }
-            ipntra += xsize;
-            }
-         }
-      }
+   if (hcopflg == 0) 
+     {
+       unsigned long int dist, mindist;
+       unsigned int minind;
+
+       for (loopi=0; loopi<iy; loopi++)
+	 {
+	   ipntrb = ipntra;
+	   for (loopk=0; loopk<ix; loopk++)
+	     {
+	       /* It is possible to lose precision in the memory "read",
+		  namely in the conversion from 16-bit to 32-bit pixels.
+		  Thus, we loop through each color table entry to find a
+		  closest match using the pythagorean theorem.  On small
+		  enough images this is not a burden.  
+		  
+		  To get nice quality print output this step appears
+		  necessary, so those using Pseudo emulation may just have
+		  to wait.  
+		  
+		  I decided to put the ittf and hcopflg comparisons inside
+		  the inner loop.  This doesn't cost much in comparison to
+		  the color-table-lookup loop. */
+	       
+	       int i;
+	       pix = *ipntrb++;
+	       
+	       /* Removed check for fixed colours - doesn't work well in
+		  24-bit environments */
+
+	       /* Search for the best fitting color index */
+	       minind = -1;
+	       for (i=ioff; i<(offset+ioff); i++)
+		 {
+		   unsigned int lval;
+		   unsigned long int dist;
+		   int dr, dg, db;
+		   
+		   lval = Xworkst[no].mapin[i];
+		   dr = ((lval & 0x0000ff) - (pix & 0x0000ff));
+		   dg = ((lval & 0x00ff00) - (pix & 0x00ff00)) >> 8;
+		   db = ((lval & 0xff0000) - (pix & 0xff0000)) >> 16;
+		   /* Euclidean distance, squared */
+		   dist = dr*dr + dg*dg + db*db;
+		   if (minind == -1 || dist < mindist)
+		     {
+		       mindist = dist;
+		       minind  = i;
+		     }
+		 }
+	       /* Apply transfer function and global offset */
+	       if (ittf == 0) 
+		 *data++ = (unsigned char) (minind - lutoff);
+	       else
+		 {
+		   int kval = (minind - lutoff);
+		   if (kval < 0) kval = 0;
+		   *data++ = (unsigned char) (itt->val[kval]);
+		 }
+	       
+	     next_pix:
+	       ;
+	     }
+
+	   ipntra += xsize;
+	 }
+     }
+   else 			/* hardcopy - work on all 3 color channels */
+     {
+       int  *idata;
+       
+       /* Ignore ITT and fixed colours */
+       idata = (int *) data;
+       for (loopi=0; loopi<iy; loopi++)
+	 {
+	   ipntrb = ipntra;
+	   
+	   if (Xworkst[no].RGBord == 0) 
+	     for (loopk=0; loopk<ix; loopk++) *idata++ = *ipntrb++;
+	   else 
+	     for (loopk=0; loopk<ix; loopk++) 
+	       {
+		 unsigned int word = *ipntrb++;
+		 *idata++ = ((word & 0x00ff00) | ((word & 0xff0000) >> 16)
+			     | ((word & 0x0000ff) << 16));
+	       }
+	   
+	   ipntra += xsize;
+	 }
+     }
    }
-}
+}       
 
 /* 
 
diff -urN old_x11/makefile x11/makefile
--- old_x11/makefile	Tue Jun  6 10:30:44 2000
+++ x11/makefile	Thu Nov 30 09:59:40 2000
@@ -24,10 +24,12 @@
 LIB = $(LIBDIR)/libidi.a
 
 OBJ =	idiutil1.o idiutil2.o idilocal1.o idilocal2.o idilocal3.o \
-	iic.o iid1.o iid2.o iie.o iig.o iii.o iil.o iim.o iir.o iis.o iiz.o 
+	iic.o iid1.o iid2.o iie.o iig.o iii.o iil.o iim.o iir.o iis.o iiz.o \
+	idiconv.o
 
 SRC =	idiutil1.c idiutil2.c idilocal1.c idilocal2.c idilocal3.o \
-	iic.c iid1.c iid2.c iie.c iig.c iii.c iil.c iim.c iir.c iis.c iiz.c 
+	iic.c iid1.c iid2.c iie.c iig.c iii.c iil.c iim.c iir.c iis.c iiz.c \
+	idiconv.c
 
 # DEPENDENCIES:
 all: $(MAKEFILE_VMS) $(LIB)
