Rasterfile Structure
struct rasterfile { int ras_magic; /* magic number */ int ras_width; /* width (pixels) of image */ int ras_height; /* height (pixels) of image */ int ras_depth; /* depth (1, 8, or 24 bits) of pixel */ int ras_length; /* length (bytes) of image */ int ras_type; /* type of file; see RT_* below */ int ras_maptype; /* type of colormap; see RMT_* below */ int ras_maplength; /* length (bytes) of following map */ };
#define RAS_MAGIC 0x59a66a95 #define RT_OLD 0 /* Raw pixrect image in 68000 byte order */ #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_NONE 0 /* ras_maplength is expected to be 0 */ #define RMT_EQUAL_RGB 1
Generating the Header
static void ras_header(struct rasterfile *h, Image *i, int cflag) { h->ras_magic = RAS_MAGIC; h->ras_width = i->w; h->ras_height = i->h; h->ras_depth = (img_type(i) == IMG_TRUECOL)? 24 : 8; h->ras_length = i->w * i->h; h->ras_type = (cflag)? RT_SIMPLE_RLE : RT_STANDARD; h->ras_maptype = (img_type(i) == IMG_MAPPCOL)? RMT_EQUAL_RGB : RMT_NONE; h->ras_maplength = (img_type(i) == IMG_MAPPCOL)? sizeof(CMap) : 0; }
Writing an Image
}void img_write(Image *i, char *fname, int cflag) { struct rasterfile h; int fd; fd = (strcmp("stdout", fname) == 0)? 1 : ecreat(fname, 0666); ras_header(&h, i, cflag); write_sunheader(fd, &h); if (img_type(i) == IMG_MAPPCOL && i->m != NULL) write(fd, i->m, sizeof(CMap)); switch (h.ras_type) { case RT_FORMAT_RGB: sunras_write(fd, h.ras_depth, i->w, i->h, i->u.c); break; case RT_STANDARD: sunras_write(fd, h.ras_depth, i->w, i->h, i->u.b); break; case RT_SIMPLE_RLE: rle_write(fd, i); break; } close(fd); }
Reading an Image
Image *img_read(char *fname) { struct rasterfile h; int fd; Image *i; fd = (strcmp("stdin", fname) == 0)? 0 : eopen(fname, 0); read_sunheader(fd, &h); if (h.ras_magic != RAS_MAGIC) error("(img_read) wrong format"); i = img_init(IMG_RASTYPE(h), h.ras_width, h.ras_height); if (h.ras_maptype == RMT_EQUAL_RGB) cmap_read(i->m, h.ras_maplength, fd); switch (h.ras_type) { case RT_FORMAT_RGB: sunras_read(fd, h.ras_depth, i->w, i->h, i->u.c); break; case RT_STANDARD: sunras_read(fd, h.ras_depth, i->w, i->h, i->u.b); break; case RT_SIMPLE_RLE: rle_read(fd, i); break; default: error("(img_read) unknown format"); } close(fd); return i; }
Machine Independent I/O
static void read_sunheader(int fd, struct rasterfile *h) { read_sun_long(&(h->ras_magic), fd); read_sun_long(&(h->ras_width), fd); read_sun_long(&(h->ras_height), fd); read_sun_long(&(h->ras_depth), fd); read_sun_long(&(h->ras_length), fd); read_sun_long(&(h->ras_type), fd); read_sun_long(&(h->ras_maptype), fd); read_sun_long(&(h->ras_maplength), fd); }
static void read_sun_long(int *l, int fd) { unsigned char c0, c1, c2, c3; read(fd,&c0,1); read(fd,&c1,1); read(fd,&c2,1); read(fd,&c3,1); *l = (((unsigned int) c0 & 0xff) << 24) | (((unsigned int) c1 & 0xff) << 16) | (((unsigned int) c2 & 0xff) << 8) | (((unsigned int) c3 & 0xff)); }
static void write_sun_long(unsigned int l, int fd) { unsigned char c; c = ((l >> 24) & 0xff); write(fd, &c, 1); c = ((l >> 16) & 0xff); write(fd, &c, 1); c = ((l >> 8) & 0xff); write(fd, &c, 1); c = (l & 0xff); write(fd, &c, 1); }
static void sunras_read(int fd, int d, int w, int h, void *buf) { int i, lsize, padline; char pad[1], *bp; lsize = (w * d)/8; padline = ((w * d) % 16)? TRUE : FALSE; for (i = 0, bp = buf; i < h; i++, bp += lsize) { read(fd, bp, lsize); if (padline) read(fd, &pad, 1); } }
static void sunras_write(int fd, int d, int w, int h, void *buf) { int i, lsize, padline; char pad[1], *bp; lsize = (w * d)/8; padline = ((w * d) % 16)? TRUE : FALSE; for (i = 0, bp = buf; i < h; i++, bp += lsize) { write(fd, bp, lsize); if (padline) write(fd, &pad, 1); } }