/* these routines were taken from the source code for XV-3.00a. Credit goes to the original creators Dave Heath (heath@cs.jhu.edu) fixBGR() added by Ken Rossman (ken@shibuya.cc.columbia.edu) Modifications to the code for usage in CISC 859 was made by: Hai Pham and Donald Quon */ #include "sunras.h" /* info on sun rasterfiles taken from rasterfile(5) man page */ #define RAS_MAGIC 0x59a66a95 struct rasterfile { int ras_magic; int ras_width; int ras_height; int ras_depth; int ras_length; int ras_type; int ras_maptype; int ras_maplength; }; /* MONO returns total intensity of r,g,b components */ #define MONO(rd,gn,bl) (((rd)*11 + (gn)*16 + (bl)*5) >> 5) /*.33R+ .5G+ .17B*/ /* values 'picType' can take */ #define PIC8 0 #define PIC24 1 #define F_FULLCOLOR 0 #define F_GREYSCALE 1 #define F_BWDITHER 2 #define F_SUNRAS 5 #define RT_OLD 0 #define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */ #define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */ #define RT_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */ #define RMT_RAW 2 #define RMT_NONE 0 #define RMT_EQUAL_RGB 1 #define RAS_RLE 0x80 static int rle_read(byte *, int, int, FILE *, int); static void SunRas1to8(byte *, byte *, int); static void SunRas8to1(byte *, byte *, int, int); static int read_sun_long(long *, FILE *); static int write_sun_long(long, FILE *); static void fixBGR(unsigned char *, int, int); static void xvbcopy(char *, char *,int); void xvbcopy(src, dst, len) char *src, *dst; int len; { /* Modern OS's (Solaris, etc.) frown upon the use of bcopy(), * and only want you to use memcpy(). However, memcpy() is broken, * in the sense that it doesn't properly handle overlapped regions * of memory. This routine does, and also has its arguments in * the same order as bcopy() did, without using bcopy(). */ /* determine if the regions overlap * * 3 cases: src=dst, srcdst * * if src=dst, they overlap completely, but nothing needs to be moved * if srcdst then they overlap * if src>dst and srcdst) { /* do a backward copy */ src = src + len - 1; dst = dst + len - 1; for ( ; len>0; len--, src--, dst--) *dst = *src; } else { /* they either overlap (src>dst) or they don't overlap */ /* do a forward copy */ for ( ; len>0; len--, src++, dst++) *dst = *src; } } /*******************************************/ int LoadSunRas(FILE *fp, PICINFO *pinfo) { int linesize,lsize,csize,isize,i,w,h,d; byte *image, *line, *pic8; struct rasterfile sunheader; long dummylong; read_sun_long (&dummylong,fp); sunheader.ras_magic=(int) dummylong; read_sun_long (&dummylong,fp); sunheader.ras_width=(int)dummylong; read_sun_long (&dummylong,fp); sunheader.ras_height=(int)dummylong; read_sun_long (&dummylong,fp); sunheader.ras_depth=(int)dummylong; read_sun_long (&dummylong,fp); sunheader.ras_length=(int)dummylong; read_sun_long (&dummylong,fp); sunheader.ras_type=(int)dummylong; read_sun_long (&dummylong,fp); sunheader.ras_maptype=(int)dummylong; read_sun_long (&dummylong,fp); sunheader.ras_maplength=(int)dummylong; if (sunheader.ras_magic != RAS_MAGIC) { fclose(fp); printf("\n%i,%ld\n",sunheader.ras_magic,RAS_MAGIC); printf("not a Sun rasterfile"); exit(0); } /* 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) { printf ("Sun rasterfile image has depth %d\n", sunheader.ras_depth); printf ("Depths supported are 1, 8, 24, and 32\n"); fclose(fp); return 0; } if (sunheader.ras_type != RT_OLD && sunheader.ras_type != RT_STANDARD && sunheader.ras_type != RT_BYTE_ENCODED && sunheader.ras_type != RT_FORMAT_RGB) { printf ("Sun rasterfile of unsupported type %d\n", sunheader.ras_type); fclose(fp); return 0; } if (sunheader.ras_maptype != RMT_RAW && sunheader.ras_maptype != RMT_NONE && sunheader.ras_maptype != RMT_EQUAL_RGB) { printf ("Sun rasterfile colormap of unsupported type %d\n", sunheader.ras_maptype); fclose(fp); return 0; } 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; /* compute length of the output (xv-format) image */ lsize = w * h; if (d == 24 || d == 32) lsize = lsize * 3; linesize = w * d; if (linesize % 16) linesize += (16 - (linesize % 16)); linesize /= 8; /* read in the colormap, if any */ if (sunheader.ras_maptype == RMT_EQUAL_RGB && csize) { fread (pinfo->r, 1, sunheader.ras_maplength/3, fp); fread (pinfo->g, 1, sunheader.ras_maplength/3, fp); fread (pinfo->b, 1, 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) { pinfo->r[0] = pinfo->g[0] = pinfo->b[0] = 0; pinfo->r[1] = pinfo->g[1] = pinfo->b[1] = 255; } else if (sunheader.ras_depth == 8) { for (i = 0; i < 256; i++) pinfo->r[i] = pinfo->g[i] = pinfo->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){ printf("Can't allocate memory for image\n"); exit(0); } for (i = 0; i < h; i++) { if (sunheader.ras_type == RT_BYTE_ENCODED) { if (rle_read (line, 1, linesize, fp, (i==0)) != linesize) break; } else { if (fread (line, 1, linesize, fp) != linesize) { free(image); free(line); fclose(fp); printf("file read error"); exit(0); } } switch (d) { case 1: SunRas1to8 (image + w * i, line, w); break; case 8: xvbcopy(line, image + w * i, w); break; case 24: xvbcopy(line, image + w * i * 3, w * 3); break; case 32: { int k; byte *ip, *op; ip = line; op = (byte *) (image + w * i * 3); for (k = 0; ktype = PIC24; } else pinfo->type = PIC8; pinfo->pic = image; pinfo->w = w; pinfo->h = h; pinfo->frmType = F_SUNRAS; pinfo->colType = (d==1) ? F_BWDITHER : F_FULLCOLOR; sprintf(pinfo->fullInfo, "Sun %s rasterfile. (%d plane%s) (%d bytes)", sunheader.ras_type == RT_BYTE_ENCODED ? "rle" : "standard", d, d == 1 ? "" : "s", sizeof (struct rasterfile) + csize + isize); sprintf(pinfo->shrtInfo, "%dx%d Sun Rasterfile.",w,h); pinfo->comment = (char *) NULL; return 1; } /*****************************/ 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 void SunRas1to8 (dest, src, len) byte *dest, *src; int len; { int i, b; int c = 0; for (i = 0, b = -1; i < len; i++) { if (b < 0) { b = 7; c = ~*src++; } *dest++ = ((c >> (b--)) & 1); } } static void SunRas8to1 (dest, src, len, flip) byte *dest, *src; int len, flip; { int i, b; int c; for (c = b = i = 0; i < len; i++) { c <<= 1; c |= (*src++ ? 1 : 0); if (b++ == 7) { if (flip) c = ~c; *dest++ = (byte) (c & 0xff); b = c = 0; } } if (b) { if (flip) c = ~c; *dest = (byte) ((c<<(8-b)) & 0xff); } } /*******************************************/ int WriteSunRas(fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle,userle) FILE *fp; byte *pic; int ptype,w,h; byte *rmap, *gmap, *bmap; int numcols, colorstyle, userle; { /* writes a sun rasterfile to the already open stream writes either 24-bit, 8-bit or 1-bit currently will not write rle files if PIC24 and F_GREYSCALE, writes an 8-bit grayscale image biggest problem w/ rle file: should we compute image size first (nicer) or go back and write it in when we are done (kludgy)? */ struct rasterfile sunheader; int linesize, i, color, d, y, flipbw; byte *line, *graypic, graymap[256], *sp, *dp; graypic = NULL; /* special case: if PIC24 and writing GREYSCALE, write 8-bit file */ if (ptype == PIC24 && colorstyle == F_GREYSCALE) { graypic = (byte *) malloc(w*h); if (!graypic) { printf("unable to malloc in WriteSunRas()"); exit(0); } for (i=0,sp=pic,dp=graypic; i> 24) & 0xff); if (putc (c, fp) == EOF) return (EOF); c = ((l >> 16) & 0xff); if (putc (c, fp) == EOF) return (EOF); c = ((l >> 8) & 0xff); if (putc (c, fp) == EOF) return (EOF); c = (l & 0xff); if (putc (c, fp) == EOF) return (EOF); return (0); } /* 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