ref: 2050117574a823625a28699e6735de0ff725ce76
dir: /readpcx.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <draw.h> /* FIXME */ #include "/sys/src/cmd/jpg/imagefile.h" #include "fns.h" extern int debug; typedef struct Header Header; struct Header{ u8int id; u8int ver; u8int bpp; u16int xmin; u16int ymin; u16int xmax; u16int ymax; u8int egapal[48]; u8int np; u16int bpl; u16int ptyp; }; enum{ Hdrsz = 128 }; static void * emalloc(ulong n) { void *p; p = mallocz(n, 1); if(p == nil) sysfatal("mallocz: %r"); return p; } static void readheader(Biobuf *b, Header *h) { uchar buf[Hdrsz]; if(Bread(b, buf, sizeof buf) != sizeof buf) sysfatal("ReadPCX: can't read header: %r"); h->id = buf[0]; if(h->id != 10) sysfatal("ReadPCX: bad id %ux", h->id); h->ver = buf[1]; h->bpp = buf[3]; h->xmin = buf[4] | buf[5] << 8; h->ymin = buf[6] | buf[7] << 8; h->xmax = buf[8] | buf[9] << 8; h->ymax = buf[10] | buf[11] << 8; memcpy(h->egapal, buf+16, sizeof h->egapal); h->np = buf[65]; h->bpl = buf[66] | buf[67] << 8; h->ptyp = buf[68] | buf[69] << 8; } static Rawimage* readslave(Biobuf *b) { int w, h, t, hlen, pad; uint x; char c; uchar pal[3*256], *p, *end; Rawimage *r; Header *hd; hd = emalloc(sizeof *hd); readheader(b, hd); w = hd->xmax - hd->xmin + 1; h = hd->ymax - hd->ymin + 1; t = w * h; hlen = hd->np * hd->bpl; pad = 8 / hd->bpp * hlen - w; if(debug) fprint(2, "pcx: v.%d pt.%d %dx%dx%d in %dx%d, %d padded\n", hd->ver, hd->ptyp, w, h, hd->bpp, hd->np, hd->bpl, pad); r = emalloc(sizeof *r); r->r = Rect(0, 0, w, h); switch(hd->ver){ case 5: t *= 3; r->nchans = 1; r->chandesc = CRGB24; r->chanlen = t; r->chans[0] = emalloc(t); p = r->chans[0]; end = p + t; while(p < end){ x = 1; c = Bgetc(b); if((c & 0xc0) == 0xc0){ x = c & 0x3f; c = Bgetc(b); } while(x-- > 0 && p < end){ *p = c; p += 3; } } Bseek(b, -769, 2); if(Bgetc(b) == 0xc){ if(Bread(b, pal, sizeof pal) != sizeof pal) sysfatal("ReadPCX: bad vga palette"); p = r->chans[0]; while(p < end){ x = *p; *p++ = pal[x*3+2]; *p++ = pal[x*3+1]; *p++ = pal[x*3]; } } break; default: /* FIXME: other pcx types */ sysfatal("ReadPCX: unsupported version %d\n", hd->ver); } free(hd); return r; } Rawimage** Breadpcx(Biobuf *b, int colorspace) { Rawimage **ra; if(colorspace != CRGB){ werrstr("ReadPCX: unknown color space %d", colorspace); return nil; } ra = emalloc(2 * sizeof *ra); /* why */ ra[0] = readslave(b); ra[1] = nil; return ra; }