]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/scat/dssread.c
ndb/dnsquery, ndb/csquery: handle long lines
[plan9front.git] / sys / src / cmd / scat / dssread.c
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  long    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 long    getlong(uchar *p)
111 {
112         return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
113 }