text: /******************************************************************************
   * SAGE - Scalable Adaptive Graphics Environment
   *
   * Copyright (C) 2004 Electronic Visualization Laboratory,
   * University of Illinois at Chicago
   *
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   *  * Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *  * Redistributions in binary form must reproduce the above
   *    copyright notice, this list of conditions and the following disclaimer
   *    in the documentation and/or other materials provided with the distribution.
   *  * Neither the name of the University of Illinois at Chicago nor
   *    the names of its contributors may be used to endorse or promote
   *    products derived from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * Direct questions, comments etc about SAGE to http://www.evl.uic.edu/cavern/forum/
   *
   *****************************************************************************/
  
  /*
   * Given a Sun raster file, return an IMG containing its raster data.
   */
  
  #include <stdio.h>
  #include <stdlib.h>
  #include "rasterfile.h"
  #include "imginfo.h"
  
  IMG *
  rasmakedisp(filename)
      char *filename;
  {
      FILE *inf;
      struct rasterfile ras;
      IMG *im = NULL;
      int xsize, ysize;
      register long *rp;
      unsigned char *rowbuf = NULL;
      long cmap[256];
  
      inf = fopen(filename, "r");
      if(inf == NULL) {
  	fprintf(stderr, "%s: cannot open: ", filename);
  	perror("");
  	return NULL;
      }
  
      if(fread(&ras, sizeof(ras), 1, inf) <= 0 || ras.ras_magic != RAS_MAGIC)
  	goto fail;
  
      xsize = ras.ras_width;
      ysize = ras.ras_height;
  
      im = (IMG *)malloc(sizeof(IMG));
      im->rowbytes = xsize * sizeof(long);
      im->type = IT_LONG;
      im->xsize = xsize;
      im->ysize = ysize;
      im->data = (unsigned char *)malloc(im->rowbytes * ysize);
      if(im->data == NULL) {
  	fprintf(stderr, "Can't malloc %ld bytes of memory for image\n",
  	    sizeof(long) * xsize * ysize);
  	exit(2);
      }
      rp = (long *)im->data;
  
      switch(ras.ras_maptype) {
  	unsigned char map[768];
  	register int i;
  
      case RMT_EQUAL_RGB:
  	if(ras.ras_maplength != 3*256) {
  	    fprintf(stderr, "%s: can't handle colormap with %d != 256 entries",
  		filename, ras.ras_maplength / 3);
  	    goto fail;
  	}
  	if(fread(map, sizeof(map), 1, inf) <= 0) {
  	    fprintf(stderr, "%s: premature EOF reading colormap", filename);
  	    goto fail;
  	}
  	for(i = 0; i < 256; i++)
  	    cmap[i] = map[i] | (map[i+256] << 8) | (map[i+512] << 16);
  	break;
  
      case RMT_NONE:
  	if(ras.ras_depth == 8) {
  	    for(i = 0; i < 256; i++)
  		cmap[i] = i * 0x010101;
  	}
  	break;
  
      default:
  	fprintf(stderr, "%s: can't handle Sun colormap type %d\n",
  		filename, ras.ras_maptype);
  	goto fail;
      }
  
      if(ras.ras_type == RT_BYTE_ENCODED) {
  	if(ras.ras_depth != 8) {
  	    fprintf(stderr, "%s: can't handle byte-encoded %d-bit images\n",
  		filename, ras.ras_depth);
  	    goto fail;
  	}
  	rowbuf = (unsigned char *)malloc(ras.ras_width*sizeof(unsigned char *));
      }
  
      if(ras.ras_width > 0) {
  	register int i, c;
  	int row;
  
  	for(row = 0; row < ras.ras_height; row++) {
  	    rp = (long *)(im->data + im->rowbytes*(ysize-1 - row));
  	    i = xsize;
  	    switch(ras.ras_depth) {
  	    case 1:
  		while((c = getc(inf)) != EOF && i >= 8) {
  		    *rp++ = (c&0x80) ? 0xFFFFFF : 0;
  		    *rp++ = (c&0x40) ? 0xFFFFFF : 0;
  		    *rp++ = (c&0x20) ? 0xFFFFFF : 0;
  		    *rp++ = (c&0x10) ? 0xFFFFFF : 0;
  		    *rp++ = (c&0x08) ? 0xFFFFFF : 0;
  		    *rp++ = (c&0x04) ? 0xFFFFFF : 0;
  		    *rp++ = (c&0x02) ? 0xFFFFFF : 0;
  		    *rp++ = (c&0x01) ? 0xFFFFFF : 0;
  		}
  		if(c != EOF) {
  		    while(--i >= 0) {
  			*rp++ = (c&0x80) ? 0xFFFFFF : 0;
  			c <<= 1;
  		    }
  		}
  		break;
  
  	    case 24:
  		do {
  		    c = getc(inf);
  		    c |= getc(inf) << 8;
  		    *rp++ = c | getc(inf) << 16;
  		} while(--i > 0);
  		break;
  
  	    case 8:
  		if(ras.ras_type == RT_BYTE_ENCODED) {
  		    register unsigned char *rowp = rowbuf;
  		    int nleft = ras.ras_width;
  		    int seen = 0;
  
  		    do {
  			seen++;
  			c = getc(inf);
  			if(c == 128) {
  			    seen++;
  			    c = getc(inf);
  			    if(c == 0) {
  				*rowp++ = 128;
  			    } else {
  				seen++;
  				nleft -= c;
  				i = getc(inf);
  				do { *rowp++ = i; } while(--c >= 0);
  			    }
  			} else {
  			    *rowp++ = c;
  			}
  		    } while(--nleft > 0);
  		    if(seen&1)
  			(void) getc(inf);
  		    /*
  		     * Copy uncompressed data.
  		     */
  		    i = xsize;
  		    rowp = rowbuf;
  		    do { *rp++ = cmap[*rowp++]; } while(--i > 0);
  
  		} else {
  
  		    do {
  			*rp++ = cmap[getc(inf)];
  		    } while(--i > 0);
  		}
  		break;
  	    }
  
  	    if(feof(inf)) {
  		fprintf(stderr, "%s: premature EOF reading row %d of %d\n",
  		    filename, row, ras.ras_height);
  		break;
  	    }
  
  	    if(ras.ras_type != RT_BYTE_ENCODED) {
  		i = (((ras.ras_width*ras.ras_depth + 15) & ~15) >> 3) - xsize;
  		while(--i >= 0)
  		    (void) getc(inf);
  	    }
  	}
      }
      if(rowbuf != NULL)
  	free(rowbuf);
      if(inf != NULL)
  	fclose(inf);
      return im;
  
    fail:
      if(im) {
  	if(im->data) free(im->data);
  	free(im);
      }
      if(inf != NULL)
  	fclose(inf);
      return NULL;
  }
  