home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * This function almost taken wholesale from the xv2.21 distribution.
- *
- * Slight modifications by Brett Van Sprewenburg
- * For relevant information on the xv disturbtion, get the xv display kit.
- *
- * Altered some return codes to return < 0 on error.
- *
- * LoadSunRas(fname) - loads a Raster pic
- *
- */
-
- #include <writeilbm.h>
-
- static int SunRasError();
- static void SunRas1to8();
- static int rle_read();
- static void flipl();
- static void fixBGR();
- byte *pic, r[256], g[256], b[256];
- int pHIGH,pWIDE;
-
- int LoadSunRas(char *fname)
- {
- FILE *fp;
- int linesize,lsize,csize,isize,flipit,i,w,h,d,rv;
- byte *image, *line;
-
- rv = 0;
-
- /* read in the Sun Rasterfile picture */
- fp=fopen(fname,"r");
- if (!fp) return( SunRasError("unable to open file") );
-
- flipit = FALSE;
- fread(&sunheader,sizeof(struct RasterHeader),1,fp);
- if (sunheader.ras_magic != RAS_MAGIC)
- {
- flipl( (byte *) &sunheader.ras_magic);
- if (sunheader.ras_magic == RAS_MAGIC) flipit = TRUE;
- else flipl( (byte *) &sunheader.ras_magic);
- }
- if (sunheader.ras_magic != RAS_MAGIC) {
- fprintf(stderr,"'%s' is not a Sun Raster file. Exiting.\n",fname);
- fclose(fp);
- return -1;
- }
-
- if (flipit) {
- flipl((byte *) &sunheader.ras_width);
- flipl((byte *) &sunheader.ras_height);
- flipl((byte *) &sunheader.ras_depth);
- flipl((byte *) &sunheader.ras_length);
- flipl((byte *) &sunheader.ras_type);
- flipl((byte *) &sunheader.ras_maptype);
- flipl((byte *) &sunheader.ras_maplength);
- }
-
- /* make sure that the input picture can be dealt with */
- if ( sunheader.ras_depth != 1 &&
- sunheader.ras_depth != 8 &&
- sunheader.ras_depth != 24 &&
- sunheader.ras_depth != 32) {
- fprintf (stderr, "Sun rasterfile image has depth %d\n",
- sunheader.ras_depth);
- fprintf (stderr, "Depths supported are 1, 8, 24, and 32\n");
- return -1;
- }
-
- if (sunheader.ras_type != RT_OLD &&
- sunheader.ras_type != RT_STANDARD &&
- sunheader.ras_type != RT_BYTE_ENCODED &&
- sunheader.ras_type != RT_FORMAT_RGB) {
- fprintf (stderr, "Sun rasterfile of unsupported type %d\n",
- sunheader.ras_type);
- return -1;
- }
-
- if (sunheader.ras_maptype != RMT_RAW &&
- sunheader.ras_maptype != RMT_NONE &&
- sunheader.ras_maptype != RMT_EQUAL_RGB) {
- fprintf (stderr, "Sun rasterfile colormap of unsupported type %d\n",
- sunheader.ras_maptype);
- return -1;
- }
-
- w = sunheader.ras_width;
- h = sunheader.ras_height;
- d = sunheader.ras_depth;
- isize = sunheader.ras_length ?
- sunheader.ras_length :
- (w * h * d) / 8;
- csize = (sunheader.ras_maptype == RMT_NONE) ? 0 : sunheader.ras_maplength;
-
- lsize = w * h;
- if (d == 24 || d == 32) lsize = lsize * 3;
-
- linesize = w * d;
- /* if ((linesize % 48) && d == 24) linesize += (48 - (linesize % 48)); */
- if (linesize % 16) linesize += (16 - (linesize % 16));
- linesize /= 8;
-
- if (DEBUG)
- {
- fprintf(stderr,"readsunras: LoadSunRas() - loading a %dx%d pic, %d planes\n",
- w, h,
- d);
- fprintf (stderr,
- "type %d, maptype %d, isize %d, csize %d, lsize %d, linesize %d\n",
- sunheader.ras_type, sunheader.ras_maptype,
- isize, csize, lsize, linesize);
- }
-
-
- fprintf(stderr,"%dx%d Sun %s rasterfile. (%d plane%s) (%d uncompressed bytes)\n",
- sunheader.ras_width, sunheader.ras_height,
- sunheader.ras_type == RT_BYTE_ENCODED ? "rle" : "standard",
- d,
- d == 1 ? "" : "s",
- sizeof (struct RasterHeader) + csize + isize);
-
- /* read in the colormap, if any */
- if (sunheader.ras_maptype == RMT_EQUAL_RGB && csize)
- {
- fread (r, sizeof (byte), sunheader.ras_maplength/3, fp);
- fread (g, sizeof (byte), sunheader.ras_maplength/3, fp);
- fread (b, sizeof (byte), sunheader.ras_maplength/3, fp);
-
- }
- else if (sunheader.ras_maptype == RMT_RAW && csize)
- {
- /* we don't know how to handle raw colormap, ignore */
- fseek (fp, (long) csize, 1);
- }
-
- else { /* no colormap, make one up */
- if (sunheader.ras_depth == 1) {
- r[0] = g[0] = b[0] = 0;
- r[1] = g[1] = b[1] = 255;
- }
-
- else if (sunheader.ras_depth == 8) {
- for (i = 0; i < 256; i++)
- r[i] = g[i] = b[i] = i;
- }
- }
-
-
- /* allocate memory for picture and read it in */
- /* note we may slightly overallocate here (if image is padded) */
- image = (byte *) malloc (lsize);
- line = (byte *) malloc (linesize);
- if (image == NULL || line == NULL)
- fprintf(stderr,"Can't allocate memory for image\n");
-
- for (i = 0; i < h; i++) {
- if (sunheader.ras_type == RT_BYTE_ENCODED) {
- if (rle_read (line, 1, linesize, fp, (i==0)) != linesize) break;
- return (SunRasError ("rle file read error"));
- }
-
- else {
- if (fread (line, 1, linesize, fp) != linesize)
- return (SunRasError ("file read error"));
- }
-
- switch (d) {
- case 1: SunRas1to8 (image + w * i, line, w); break;
- case 8: memcpy (image + w * i, line, w); break;
- case 24: memcpy (image + w * i * 3, line, w * 3); break;
- case 32: {
- int k;
- byte *ip, *op;
- ip = line;
- op = (byte *) (image + w * i * 3);
- for (k = 0; k<w; k++) {
- *ip++; /* skip 'alpha' */
- *op++ = *ip++; /* red */
- *op++ = *ip++; /* green */
- *op++ = *ip++; /* blue */
- }
- }
- }
- }
-
- if (fp != stdin) fclose (fp);
- if (DEBUG) fprintf(stderr,"Sun ras: image loaded!\n");
-
- if (d == 24 || d == 32)
- if (sunheader.ras_type != RT_FORMAT_RGB) fixBGR(image,w,h);
-
- pic = image;
- pWIDE = w;
- pHIGH = h;
- return 0;
- }
-
-
- /*****************************/
- static int rle_read (ptr, size, nitems, fp, init)
- byte *ptr;
- int size, nitems,init;
- FILE *fp;
- {
- static int count, ch;
- int readbytes, c, read;
-
- if (init) { count = ch = 0; }
-
- readbytes = size * nitems;
- for (read = 0; read < readbytes; read++) {
- if (count) {
- *ptr++ = (byte) ch;
- count--;
- }
-
- else {
- c = getc(fp);
- if (c == EOF) break;
-
- if (c == RAS_RLE) { /* 0x80 */
- count = getc(fp);
- if (count == EOF) break;
-
- if (count < 0) count &= 0xff;
- if (count == 0) *ptr++ = c;
- else {
- if ((ch = getc(fp)) == EOF) break;
- *ptr++ = ch;
- }
- }
- else *ptr++ = c;
- }
- }
-
- return (read/size);
- }
-
-
- /*****************************/
- static int SunRasError(st)
- char *st;
- {
- fprintf(stderr,"LoadSunRas() - %s",st);
- return -1;
- }
-
-
- /*****************************/
- static void SunRas1to8 (dest, src, len)
- byte *dest, *src;
- int len;
- {
- int i, b;
- int c;
-
- for (i = 0, b = -1; i < len; i++) {
- if (b < 0) {
- b = 7;
- c = ~*src++;
- }
- *dest++ = ((c >> (b--)) & 1);
- }
- }
-
-
- /*****************************/
- static void flipl(p)
- byte *p;
- {
- byte t;
- t = p[0]; p[0]=p[3]; p[3] = t;
- t = p[1]; p[1]=p[2]; p[2] = t;
- }
-
- /* kr3 - fix up BGR order SUN 24-bit rasters to be RGB order */
- static void fixBGR(img,w,h)
- unsigned char *img;
- int w,h;
- {
- int i,npixels;
- unsigned char tmp;
-
- npixels = w*h;
- for (i=0; i<npixels; i++) {
- tmp = img[0]; /* swap red and blue channels */
- img[0] = img[2];
- img[2] = tmp;
- img += 3; /* bump to next pixel */
- }
- }
-
-