Ignore RLE data that goes past the line end (found by Uwe Bonnes).
General cleanup of the RLE routines.

diff --git a/graphics/x11drv/dib.c b/graphics/x11drv/dib.c
index 2ebc269..328fbcf 100644
--- a/graphics/x11drv/dib.c
+++ b/graphics/x11drv/dib.c
@@ -67,6 +67,13 @@
 } X11DRV_DIB_IMAGEBITS_DESCR;
 
 
+enum Rle_EscapeCodes
+{
+  RLE_EOL   = 0, /* End of line */
+  RLE_END   = 1, /* End of bitmap */
+  RLE_DELTA = 2  /* Delta */
+};
+
 /***********************************************************************
  *           X11DRV_DIB_GetXImageWidthBytes
  *
@@ -855,70 +862,44 @@
 					  int left, int *colors,
 					  XImage *bmpImage )
 {
-    int x = 0, c, length;
+    int x = 0, y = lines - 1, c, length;
     const BYTE *begin = bits;
 
-    lines--;
-
-    while ((int)lines >= 0) {
+    while (y >= 0)
+    {
         length = *bits++;
 	if (length) {	/* encoded */
 	    c = *bits++;
 	    while (length--) {
-		if(x >= width) {
-		    x = 0;
-		    if(--lines < 0)
-		        return;
-		}
-	        XPutPixel(bmpImage, x++, lines, colors[c >>4]);
-		if (length) {
-		    length--;
-		    if(x >= width) {
-		        x = 0;
-			if(--lines < 0)
-			    return;
-		    }
-		    XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
-		}
+                if (x >= width) break;
+                XPutPixel(bmpImage, x++, y, colors[c >> 4]);
+                if (!length--) break;
+                if (x >= width) break;
+                XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
 	    }
 	} else {
 	    length = *bits++;
-	    switch (length) {
-	    case 0: /* eol */
-	        x = 0;
-		lines--;
-		continue;
+	    switch (length)
+            {
+            case RLE_EOL:
+                x = 0;
+                y--;
+                break;
 
-	    case 1: /* eopicture */
+            case RLE_END:
 	        return;
 
-	    case 2: /* delta */
-	        x += *bits++;
-		if(x >= width) {
-		   FIXME_(x11drv)("x-delta is too large?\n");
-		   return;
-		}
-		lines -= *bits++;
-		continue;
+            case RLE_DELTA:
+                x += *bits++;
+                y -= *bits++;
+                break;
 
 	    default: /* absolute */
 	        while (length--) {
 		    c = *bits++;
-		    if(x >= width) {
-		        x = 0;
-			if(--lines < 0)
-			    return;
-		    }
-		    XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
-		    if (length) {
-		        length--;
-			if(x >= width) {
-			    x = 0;
-			    if(--lines < 0)
-			        return;
-			}
-			XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
-		    }
+                    if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
+                    if (!length--) break;
+                    if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
 		}
 		if ((bits - begin) & 1)
 		    bits++;
@@ -1272,172 +1253,99 @@
  *			James A. Youngman <mbcstjy@afs.man.ac.uk>
  *						[JAY]
  */
-
-enum Rle8_EscapeCodes		
-{
-  /* 
-   * Apologies for polluting your file's namespace...
-   */
-  RleEol 	= 0,		/* End of line */
-  RleEnd 	= 1,		/* End of bitmap */
-  RleDelta	= 2		/* Delta */
-};
-  
 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
 					  DWORD width, DWORD dstwidth,
 					  int left, int *colors,
 					  XImage *bmpImage )
 {
     int x;			/* X-positon on each line.  Increases. */
-    int line;			/* Line #.  Starts at lines-1, decreases */
+    int y;			/* Line #.  Starts at lines-1, decreases */
     const BYTE *pIn = bits;     /* Pointer to current position in bits */
     BYTE length;		/* The length pf a run */
-    BYTE color_index;		/* index into colors[] as read from bits */
     BYTE escape_code;		/* See enum Rle8_EscapeCodes.*/
-    int color;			/* value of colour[color_index] */
-    
-    if (lines == 0)		/* Let's hope this doesn't happen. */
-      return;
-    
+
     /*
      * Note that the bitmap data is stored by Windows starting at the
      * bottom line of the bitmap and going upwards.  Within each line,
      * the data is stored left-to-right.  That's the reason why line
      * goes from lines-1 to 0.			[JAY]
      */
-    
-    x = 0;
-    line = lines-1;
-    do
-      {
-	  length = *pIn++;
-	  
-	  /* 
-	   * If the length byte is not zero (which is the escape value),
-	   * We have a run of length pixels all the same colour.  The colour 
-	   * index is stored next. 
-	   *
-	   * If the length byte is zero, we need to read the next byte to
-	   * know what to do.			[JAY]
-	   */
-	  if (length != 0) 
-	    {                                   
-		/* 
-		 * [Run-Length] Encoded mode 
-		 */
-		color_index = (*pIn++); /* Get the colour index. */
-		color = colors[color_index];
 
-		while(length--)
-		  {
-		    if (x>=dstwidth)
-		      {
-			x=0;
-			line--;
-		      }
-		    XPutPixel(bmpImage, x++, line, color);
-		  }
-	    }
-	  else 
-	    {    
-		/* 
-		 * Escape codes (may be an absolute sequence though)
-		 */
-		escape_code = (*pIn++);
-		switch(escape_code)
-		  {
-		    case RleEol: /* =0, end of line */
-		      {
-			  x = 0;  
-			  line--;  
-			  break;
-		      }
-		      
-		    case RleEnd: /* =1, end of bitmap */
-		      {
-			  /*
-			   * Not all RLE8 bitmaps end with this 
-			   * code.  For example, Paint Shop Pro 
-			   * produces some that don't.  That's (I think)
-			   * what caused the previous implementation to 
-			   * fail.			[JAY]
-			   */
-			  line=-1; /* Cause exit from do loop. */
-			  break;
-		      }
-		      
-		    case RleDelta: /* =2, a delta */
-		      {
-			  /* 
-			   * Note that deltaing to line 0 
-			   * will cause an exit from the loop, 
-			   * which may not be what is intended. 
-			   * The fact that there is a delta in the bits
-			   * almost certainly implies that there is data
-			   * to follow.  You may feel that we should 
-			   * jump to the top of the loop to avoid exiting
-			   * in this case.  
-			   *
-			   * TODO: Decide what to do here in that case. [JAY]
-			   */
-			  x 	+= (*pIn++); 
-			  line 	-= (*pIn++);
-			  if (line == 0)
-			    {
-			      TRACE("Delta to last line of bitmap "
-                                    "(wrongly?) causes loop exit\n");
-			    }
-			  break;
-		      }
-		      
-		    default:	/* >2, switch to absolute mode */
-		      {
-			  /* 
-			   * Absolute Mode 
-			   */
-			  length = escape_code;
-			  while(length--)
-			    {
-				color_index = (*pIn++);
-				if (x>=dstwidth)
-				  {
-				    x=0;
-				    line--;
-				  }
-				XPutPixel(bmpImage, x++, line, 
-					  colors[color_index]);
-			    }
-			  
-			  /*
-			   * If you think for a moment you'll realise that the
-			   * only time we could ever possibly read an odd
-			   * number of bytes is when there is a 0x00 (escape),
-			   * a value >0x02 (absolute mode) and then an odd-
-			   * length run.  Therefore this is the only place we
-			   * need to worry about it.  Everywhere else the
-			   * bytes are always read in pairs.  [JAY]
-			   */
-			  if (escape_code & 1) 
-			    pIn++; /* Throw away the pad byte. */
-			  break;
-		      }
-		  } /* switch (escape_code) : Escape sequence */
-	    }  /* process either an encoded sequence or an escape sequence */
-	  
-	  /* We expect to come here more than once per line. */
-      } while (line >= 0);  /* Do this until the bitmap is filled */
-    
-    /*
-     * Everybody comes here at the end.
-     * Check how we exited the loop and print a message if it's a bit odd.
-     *						[JAY]
-     */
-    if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
-      {
-	TRACE("End-of-bitmap without (strictly) proper escape code.  Last two "
-              "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
-      }
-}  
+    x = 0;
+    y = lines - 1;
+    while (y >= 0)
+    {
+        length = *pIn++;
+
+        /* 
+         * If the length byte is not zero (which is the escape value),
+         * We have a run of length pixels all the same colour.  The colour 
+         * index is stored next. 
+         *
+         * If the length byte is zero, we need to read the next byte to
+         * know what to do.			[JAY]
+         */
+        if (length != 0)
+        {
+            /* 
+             * [Run-Length] Encoded mode 
+             */
+            int color = colors[*pIn++];
+            while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
+        }
+        else
+        {
+            /* 
+             * Escape codes (may be an absolute sequence though)
+             */
+            escape_code = (*pIn++);
+            switch(escape_code)
+            {
+            case RLE_EOL:
+                x = 0;
+                y--;
+                break;
+
+            case RLE_END:
+                /* Not all RLE8 bitmaps end with this code.  For
+                 * example, Paint Shop Pro produces some that don't.
+                 * That's (I think) what caused the previous
+                 * implementation to fail.  [JAY]
+                 */
+                return;
+
+            case RLE_DELTA:
+                x += (*pIn++);
+                y -= (*pIn++);
+                break;
+
+            default:  /* switch to absolute mode */
+                length = escape_code;
+                while (length--)
+                {
+                    int color = colors[*pIn++];
+                    if (x >= dstwidth)
+                    {
+                        pIn += length;
+                        break;
+                    }
+                    XPutPixel(bmpImage, x++, y, color);
+                }
+                /*
+                 * If you think for a moment you'll realise that the
+                 * only time we could ever possibly read an odd
+                 * number of bytes is when there is a 0x00 (escape),
+                 * a value >0x02 (absolute mode) and then an odd-
+                 * length run.  Therefore this is the only place we
+                 * need to worry about it.  Everywhere else the
+                 * bytes are always read in pairs.  [JAY]
+                 */
+                if (escape_code & 1) pIn++; /* Throw away the pad byte. */
+                break;
+            } /* switch (escape_code) : Escape sequence */
+        }
+    }
+}
 
 
 /***********************************************************************