Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "sky.h"
6 static void dodecode(Biobuf*, Pix*, int, int, uchar*);
7 static int32 getlong(uchar*);
8 int debug;
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;
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 }
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;
64 nel = nx*ny;
65 nx2 = (nx+1)/2;
66 ny2 = (ny+1)/2;
67 memset(a, 0, nel*sizeof(*a));
69 /*
70 * Initialize bit input
71 */
72 start_inputing_bits();
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]);
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 }
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);
102 if(mask & bits)
103 *a = -px;
104 mask >>= 1;
109 static
110 int32 getlong(uchar *p)
112 return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];