1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include "sky.h"
5219b2ee8SDavid du Colombier
6219b2ee8SDavid du Colombier static void dodecode(Biobuf*, Pix*, int, int, uchar*);
7219b2ee8SDavid du Colombier static long getlong(uchar*);
8219b2ee8SDavid du Colombier int debug;
9219b2ee8SDavid du Colombier
107dd7cddfSDavid du Colombier Img*
dssread(char * file)11219b2ee8SDavid du Colombier dssread(char *file)
12219b2ee8SDavid du Colombier {
13219b2ee8SDavid du Colombier int nx, ny, scale, sumall;
14219b2ee8SDavid du Colombier Pix *p, *pend;
15219b2ee8SDavid du Colombier uchar buf[21];
16219b2ee8SDavid du Colombier Biobuf *bp;
177dd7cddfSDavid du Colombier Img *ip;
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier if(debug)
20*59cc4ca5SDavid du Colombier Bprint(&bout, "reading %s\n", file);
21219b2ee8SDavid du Colombier bp = Bopen(file, OREAD);
22219b2ee8SDavid du Colombier if(bp == 0)
23219b2ee8SDavid du Colombier return 0;
24219b2ee8SDavid du Colombier if(Bread(bp, buf, sizeof(buf)) != sizeof(buf) ||
25219b2ee8SDavid du Colombier buf[0] != 0xdd || buf[1] != 0x99){
26219b2ee8SDavid du Colombier werrstr("bad format");
27219b2ee8SDavid du Colombier return 0;
28219b2ee8SDavid du Colombier }
29219b2ee8SDavid du Colombier nx = getlong(buf+2);
30219b2ee8SDavid du Colombier ny = getlong(buf+6);
31219b2ee8SDavid du Colombier scale = getlong(buf+10);
32219b2ee8SDavid du Colombier sumall = getlong(buf+14);
33219b2ee8SDavid du Colombier if(debug)
34219b2ee8SDavid du Colombier fprint(2, "%s: nx=%d, ny=%d, scale=%d, sumall=%d, nbitplanes=%d,%d,%d\n",
35219b2ee8SDavid du Colombier file, nx, ny, scale, sumall, buf[18], buf[19], buf[20]);
367dd7cddfSDavid du Colombier ip = malloc(sizeof(Img) + (nx*ny-1)*sizeof(int));
37219b2ee8SDavid du Colombier if(ip == 0){
38219b2ee8SDavid du Colombier Bterm(bp);
39219b2ee8SDavid du Colombier werrstr("no memory");
40219b2ee8SDavid du Colombier return 0;
41219b2ee8SDavid du Colombier }
42219b2ee8SDavid du Colombier ip->nx = nx;
43219b2ee8SDavid du Colombier ip->ny = ny;
44219b2ee8SDavid du Colombier dodecode(bp, ip->a, nx, ny, buf+18);
45219b2ee8SDavid du Colombier ip->a[0] = sumall; /* sum of all pixels */
46219b2ee8SDavid du Colombier Bterm(bp);
47219b2ee8SDavid du Colombier if(scale > 1){
48219b2ee8SDavid du Colombier p = ip->a;
49219b2ee8SDavid du Colombier pend = &ip->a[nx*ny];
50219b2ee8SDavid du Colombier while(p < pend)
51219b2ee8SDavid du Colombier *p++ *= scale;
52219b2ee8SDavid du Colombier }
53219b2ee8SDavid du Colombier hinv(ip->a, nx, ny);
54219b2ee8SDavid du Colombier return ip;
55219b2ee8SDavid du Colombier }
56219b2ee8SDavid du Colombier
57219b2ee8SDavid du Colombier static
58219b2ee8SDavid du Colombier void
dodecode(Biobuf * infile,Pix * a,int nx,int ny,uchar * nbitplanes)59219b2ee8SDavid du Colombier dodecode(Biobuf *infile, Pix *a, int nx, int ny, uchar *nbitplanes)
60219b2ee8SDavid du Colombier {
61219b2ee8SDavid du Colombier int nel, nx2, ny2, bits, mask;
62219b2ee8SDavid du Colombier Pix *aend, px;
63219b2ee8SDavid du Colombier
64219b2ee8SDavid du Colombier nel = nx*ny;
65219b2ee8SDavid du Colombier nx2 = (nx+1)/2;
66219b2ee8SDavid du Colombier ny2 = (ny+1)/2;
67219b2ee8SDavid du Colombier memset(a, 0, nel*sizeof(*a));
68219b2ee8SDavid du Colombier
69219b2ee8SDavid du Colombier /*
70219b2ee8SDavid du Colombier * Initialize bit input
71219b2ee8SDavid du Colombier */
72219b2ee8SDavid du Colombier start_inputing_bits();
73219b2ee8SDavid du Colombier
74219b2ee8SDavid du Colombier /*
75219b2ee8SDavid du Colombier * read bit planes for each quadrant
76219b2ee8SDavid du Colombier */
77219b2ee8SDavid du Colombier qtree_decode(infile, &a[0], ny, nx2, ny2, nbitplanes[0]);
78219b2ee8SDavid du Colombier qtree_decode(infile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]);
79219b2ee8SDavid du Colombier qtree_decode(infile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]);
80219b2ee8SDavid du Colombier qtree_decode(infile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]);
81219b2ee8SDavid du Colombier
82219b2ee8SDavid du Colombier /*
83219b2ee8SDavid du Colombier * make sure there is an EOF symbol (nybble=0) at end
84219b2ee8SDavid du Colombier */
85219b2ee8SDavid du Colombier if(input_nybble(infile) != 0){
86219b2ee8SDavid du Colombier fprint(2, "dodecode: bad bit plane values\n");
87219b2ee8SDavid du Colombier exits("format");
88219b2ee8SDavid du Colombier }
89219b2ee8SDavid du Colombier
90219b2ee8SDavid du Colombier /*
91219b2ee8SDavid du Colombier * get the sign bits
92219b2ee8SDavid du Colombier */
93219b2ee8SDavid du Colombier aend = &a[nel];
94219b2ee8SDavid du Colombier mask = 0;
95219b2ee8SDavid du Colombier bits = 0;;
96219b2ee8SDavid du Colombier for(; a<aend; a++) {
97219b2ee8SDavid du Colombier if(px = *a) {
98219b2ee8SDavid du Colombier if(mask == 0) {
99219b2ee8SDavid du Colombier mask = 0x80;
100219b2ee8SDavid du Colombier bits = Bgetc(infile);
101219b2ee8SDavid du Colombier }
102219b2ee8SDavid du Colombier if(mask & bits)
103219b2ee8SDavid du Colombier *a = -px;
104219b2ee8SDavid du Colombier mask >>= 1;
105219b2ee8SDavid du Colombier }
106219b2ee8SDavid du Colombier }
107219b2ee8SDavid du Colombier }
108219b2ee8SDavid du Colombier
109219b2ee8SDavid du Colombier static
getlong(uchar * p)110219b2ee8SDavid du Colombier long getlong(uchar *p)
111219b2ee8SDavid du Colombier {
112219b2ee8SDavid du Colombier return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
113219b2ee8SDavid du Colombier }
114