/* I don't know anything about this code, and I haven't yet decided
   whether to include it or not.  Do I really want to support Sun? */

      len =
	header.ras_height * (((header.ras_width*header.ras_depth+15)>>3)&~1);

      pix1 = (byte *) xmalloc (len);

      switch (header.ras_type)
	{
	case RT_STANDARD :
	case RT_OLD:
	  read (file, pix1, len);
	  break;

	case RT_BYTE_ENCODED:
	  pix2 = (byte *)xmalloc (header.ras_length);
	  read (file, pix2, header.ras_length);
	  decode (pix2, pix1, header.ras_length, len);
	  free (pix2);
	  break;

	default:
	  free (pix1);
	  free (face);
	  close (file);
	  return (BITMAP *)NULL;
	}
	
/* decode():
 *	Read a run length encoded image, decode it in ibuf.
 *
 *	QUOTING FROM SUN MANUAL:
 *	The run length encoding used in raster files is of the form
 *	<byte><byte>...<ESC><0>...<byte><ESC><count><byte>...
 *	where the counts are in the range 0..255 and the actual number
 *	of instances of <byte> is <count>+1 (i.e. actual is 1..256).
 *	One- or two- character sequences are left unencodes; three 
 *	or more character sequences are encoded as <ESC><count><byte>.
 *	<ESC> is the character code 128. Each single <ESC> in the input
 *	data stream is encoded as <ESC><0> because the count in this
 *	scheme can never be 0 (the actual count can never be 1). 
 *	<ESC><ESC> is encoded as <ESC>1<ESC>.
 *
 *	NOTE: I like goto's much less than you, but in this case
 *	      they win, because they save in many areas..
 */
#define ESCAPE 128
int
decode (ibuf, obuf, ilen, olen)
     unsigned char *ibuf;	/* buffer to place the image	*/
     unsigned char *obuf;	/* input image 			*/
     int ilen;			/* length of the input buffer	*/
     int olen;			/* length of the output buffer	*/
{
    register unsigned char *bptr, *eptr, *buf, *ebuf, color;
    register int i;
    static int cont = 0;	/* Try to continue...		*/

    eptr = &ibuf[ilen];
    ebuf = &obuf[olen];
    buf = obuf;

    bptr = ibuf - 1;

    while (buf < ebuf)
      {
	color = *++bptr;

	if (bptr == eptr)
	  goto out_of_data;

	if (color == ESCAPE)
	  {
	    color = *++bptr;
	    if (bptr == eptr)
	      goto out_of_data;

	    switch (color)
	      {
	      case 0:
		*buf++ = ESCAPE;
		break;

	      case 1:
		color = *++bptr;
		if (bptr == eptr)
		  goto out_of_data;

		if (color != ESCAPE) 
		  if (!cont)
		    goto invalid_data;

		*buf++ = ESCAPE;
		if (buf < ebuf) 
		  *buf++ = ESCAPE;
		else 
		  goto more_data;
		break;
	    
		default:
		i = color + 1;
		color = *++bptr;

		if (bptr == eptr) 
		  goto out_of_data;

		if (buf + i > ebuf)
		  goto more_data;
#if !defined (USG)
		while (i) 
		  switch (i)
		    {
		    default:
		    case 16: *buf++ = color; i--;
		    case 15: *buf++ = color; i--;
		    case 14: *buf++ = color; i--;
		    case 13: *buf++ = color; i--;
		    case 12: *buf++ = color; i--;
		    case 11: *buf++ = color; i--;
		    case 10: *buf++ = color; i--;
		    case  9: *buf++ = color; i--;
		    case  8: *buf++ = color; i--;
		    case  7: *buf++ = color; i--;
		    case  6: *buf++ = color; i--;
		    case  5: *buf++ = color; i--;
		    case  4: *buf++ = color; i--;
		    case  3: *buf++ = color; i--;
		    case  2: *buf++ = color; i--;
		    case  1: *buf++ = color; i--;
		    }
#else
		memset(buf, (int) color, i);
		buf += i;
#endif
		break;
	      }
	  }
	else 
	  /*
	   * Unencoded
	   */
	  *buf++ = color;
      }
	

    if ( ++bptr != eptr ) 
#ifdef notdef
	(void) fprintf(stderr, 
	    "%s: Warning trailing data in file ignored.\n", pname);
#endif
	;
	

    return(0);

more_data:
#ifdef notdef
    (void) fprintf(stderr, "%s: More data in image.\n", pname);
#endif
    return(1);

invalid_data:
#ifdef notdef
    (void) fprintf(stderr, "%s: Invalid data in image.\n", pname);
#endif
    return(1);

out_of_data:
#ifdef notdef
    (void) fprintf(stderr, "%s: Out of data reading image.\n", pname);
#endif
    return(1);
} /* end decode */
