Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}