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 }