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);
}
}