|  | #include	<u.h> | 
|  | #include	<libc.h> | 
|  | #include	<bio.h> | 
|  | #include	"sky.h" | 
|  |  | 
|  | static	void	dodecode(Biobuf*, Pix*, int, int, uchar*); | 
|  | static	int32	getlong(uchar*); | 
|  | int	debug; | 
|  |  | 
|  | Img* | 
|  | dssread(char *file) | 
|  | { | 
|  | int nx, ny, scale, sumall; | 
|  | Pix  *p, *pend; | 
|  | uchar buf[21]; | 
|  | Biobuf *bp; | 
|  | Img *ip; | 
|  |  | 
|  | if(debug) | 
|  | Bprint(&bout, "reading %s\n", file); | 
|  | bp = Bopen(file, OREAD); | 
|  | if(bp == 0) | 
|  | return 0; | 
|  | if(Bread(bp, buf, sizeof(buf)) != sizeof(buf) || | 
|  | buf[0] != 0xdd || buf[1] != 0x99){ | 
|  | werrstr("bad format"); | 
|  | return 0; | 
|  | } | 
|  | nx = getlong(buf+2); | 
|  | ny = getlong(buf+6); | 
|  | scale = getlong(buf+10); | 
|  | sumall = getlong(buf+14); | 
|  | if(debug) | 
|  | fprint(2, "%s: nx=%d, ny=%d, scale=%d, sumall=%d, nbitplanes=%d,%d,%d\n", | 
|  | file, nx, ny, scale, sumall, buf[18], buf[19], buf[20]); | 
|  | ip = malloc(sizeof(Img) + (nx*ny-1)*sizeof(int)); | 
|  | if(ip == 0){ | 
|  | Bterm(bp); | 
|  | werrstr("no memory"); | 
|  | return 0; | 
|  | } | 
|  | ip->nx = nx; | 
|  | ip->ny = ny; | 
|  | dodecode(bp, ip->a, nx, ny, buf+18); | 
|  | ip->a[0] = sumall;	/* sum of all pixels */ | 
|  | Bterm(bp); | 
|  | if(scale > 1){ | 
|  | p = ip->a; | 
|  | pend = &ip->a[nx*ny]; | 
|  | while(p < pend) | 
|  | *p++ *= scale; | 
|  | } | 
|  | hinv(ip->a, nx, ny); | 
|  | return ip; | 
|  | } | 
|  |  | 
|  | static | 
|  | void | 
|  | dodecode(Biobuf *infile, Pix  *a, int nx, int ny, uchar *nbitplanes) | 
|  | { | 
|  | int nel, nx2, ny2, bits, mask; | 
|  | Pix *aend, px; | 
|  |  | 
|  | nel = nx*ny; | 
|  | nx2 = (nx+1)/2; | 
|  | ny2 = (ny+1)/2; | 
|  | memset(a, 0, nel*sizeof(*a)); | 
|  |  | 
|  | /* | 
|  | * Initialize bit input | 
|  | */ | 
|  | start_inputing_bits(); | 
|  |  | 
|  | /* | 
|  | * read bit planes for each quadrant | 
|  | */ | 
|  | qtree_decode(infile, &a[0],          ny, nx2,  ny2,  nbitplanes[0]); | 
|  | qtree_decode(infile, &a[ny2],        ny, nx2,  ny/2, nbitplanes[1]); | 
|  | qtree_decode(infile, &a[ny*nx2],     ny, nx/2, ny2,  nbitplanes[1]); | 
|  | qtree_decode(infile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); | 
|  |  | 
|  | /* | 
|  | * make sure there is an EOF symbol (nybble=0) at end | 
|  | */ | 
|  | if(input_nybble(infile) != 0){ | 
|  | fprint(2, "dodecode: bad bit plane values\n"); | 
|  | exits("format"); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * get the sign bits | 
|  | */ | 
|  | aend = &a[nel]; | 
|  | mask = 0; | 
|  | bits = 0;; | 
|  | for(; a<aend; a++) { | 
|  | if(px = *a) { | 
|  | if(mask == 0) { | 
|  | mask = 0x80; | 
|  | bits = Bgetc(infile); | 
|  | } | 
|  | if(mask & bits) | 
|  | *a = -px; | 
|  | mask >>= 1; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | static | 
|  | int32	getlong(uchar *p) | 
|  | { | 
|  | return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; | 
|  | } |