plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

dssread.c (2207B)


      1 #include	<u.h>
      2 #include	<libc.h>
      3 #include	<bio.h>
      4 #include	"sky.h"
      5 
      6 static	void	dodecode(Biobuf*, Pix*, int, int, uchar*);
      7 static	int32	getlong(uchar*);
      8 int	debug;
      9 
     10 Img*
     11 dssread(char *file)
     12 {
     13 	int nx, ny, scale, sumall;
     14 	Pix  *p, *pend;
     15 	uchar buf[21];
     16 	Biobuf *bp;
     17 	Img *ip;
     18 
     19 	if(debug)
     20 		Bprint(&bout, "reading %s\n", file);
     21 	bp = Bopen(file, OREAD);
     22 	if(bp == 0)
     23 		return 0;
     24 	if(Bread(bp, buf, sizeof(buf)) != sizeof(buf) ||
     25 	   buf[0] != 0xdd || buf[1] != 0x99){
     26 		werrstr("bad format");
     27 		return 0;
     28 	}
     29 	nx = getlong(buf+2);
     30 	ny = getlong(buf+6);
     31 	scale = getlong(buf+10);
     32 	sumall = getlong(buf+14);
     33 	if(debug)
     34 		fprint(2, "%s: nx=%d, ny=%d, scale=%d, sumall=%d, nbitplanes=%d,%d,%d\n",
     35 			file, nx, ny, scale, sumall, buf[18], buf[19], buf[20]);
     36 	ip = malloc(sizeof(Img) + (nx*ny-1)*sizeof(int));
     37 	if(ip == 0){
     38 		Bterm(bp);
     39 		werrstr("no memory");
     40 		return 0;
     41 	}
     42 	ip->nx = nx;
     43 	ip->ny = ny;
     44 	dodecode(bp, ip->a, nx, ny, buf+18);
     45 	ip->a[0] = sumall;	/* sum of all pixels */
     46 	Bterm(bp);
     47 	if(scale > 1){
     48 		p = ip->a;
     49 		pend = &ip->a[nx*ny];
     50 		while(p < pend)
     51 			*p++ *= scale;
     52 	}
     53 	hinv(ip->a, nx, ny);
     54 	return ip;
     55 }
     56 
     57 static
     58 void
     59 dodecode(Biobuf *infile, Pix  *a, int nx, int ny, uchar *nbitplanes)
     60 {
     61 	int nel, nx2, ny2, bits, mask;
     62 	Pix *aend, px;
     63 
     64 	nel = nx*ny;
     65 	nx2 = (nx+1)/2;
     66 	ny2 = (ny+1)/2;
     67 	memset(a, 0, nel*sizeof(*a));
     68 
     69 	/*
     70 	 * Initialize bit input
     71 	 */
     72 	start_inputing_bits();
     73 
     74 	/*
     75 	 * read bit planes for each quadrant
     76 	 */
     77 	qtree_decode(infile, &a[0],          ny, nx2,  ny2,  nbitplanes[0]);
     78 	qtree_decode(infile, &a[ny2],        ny, nx2,  ny/2, nbitplanes[1]);
     79 	qtree_decode(infile, &a[ny*nx2],     ny, nx/2, ny2,  nbitplanes[1]);
     80 	qtree_decode(infile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]);
     81 
     82 	/*
     83 	 * make sure there is an EOF symbol (nybble=0) at end
     84 	 */
     85 	if(input_nybble(infile) != 0){
     86 		fprint(2, "dodecode: bad bit plane values\n");
     87 		exits("format");
     88 	}
     89 
     90 	/*
     91 	 * get the sign bits
     92 	 */
     93 	aend = &a[nel];
     94 	mask = 0;
     95 	bits = 0;;
     96 	for(; a<aend; a++) {
     97 		if(px = *a) {
     98 			if(mask == 0) {
     99 				mask = 0x80;
    100 				bits = Bgetc(infile);
    101 			}
    102 			if(mask & bits)
    103 				*a = -px;
    104 			mask >>= 1;
    105 		}
    106 	}
    107 }
    108 
    109 static
    110 int32	getlong(uchar *p)
    111 {
    112 	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
    113 }