123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include "sky.h"
- static void dodecode(Biobuf*, Pix*, int, int, uchar*);
- static long getlong(uchar*);
- int debug;
- Img*
- dssread(char *file)
- {
- int nx, ny, scale, sumall;
- Pix *p, *pend;
- uchar buf[21];
- Biobuf *bp;
- Img *ip;
- if(debug)
- Bprint(&bout, "reading %s\n", file);
- bp = Bopen(file, OREAD);
- if(bp == 0)
- return 0;
- if(Bread(bp, buf, sizeof(buf)) != sizeof(buf) ||
- buf[0] != 0xdd || buf[1] != 0x99){
- werrstr("bad format");
- return 0;
- }
- nx = getlong(buf+2);
- ny = getlong(buf+6);
- scale = getlong(buf+10);
- sumall = getlong(buf+14);
- if(debug)
- fprint(2, "%s: nx=%d, ny=%d, scale=%d, sumall=%d, nbitplanes=%d,%d,%d\n",
- file, nx, ny, scale, sumall, buf[18], buf[19], buf[20]);
- ip = malloc(sizeof(Img) + (nx*ny-1)*sizeof(int));
- if(ip == 0){
- Bterm(bp);
- werrstr("no memory");
- return 0;
- }
- ip->nx = nx;
- ip->ny = ny;
- dodecode(bp, ip->a, nx, ny, buf+18);
- ip->a[0] = sumall; /* sum of all pixels */
- Bterm(bp);
- if(scale > 1){
- p = ip->a;
- pend = &ip->a[nx*ny];
- while(p < pend)
- *p++ *= scale;
- }
- hinv(ip->a, nx, ny);
- return ip;
- }
- static
- void
- dodecode(Biobuf *infile, Pix *a, int nx, int ny, uchar *nbitplanes)
- {
- int nel, nx2, ny2, bits, mask;
- Pix *aend, px;
- nel = nx*ny;
- nx2 = (nx+1)/2;
- ny2 = (ny+1)/2;
- memset(a, 0, nel*sizeof(*a));
- /*
- * Initialize bit input
- */
- start_inputing_bits();
- /*
- * read bit planes for each quadrant
- */
- qtree_decode(infile, &a[0], ny, nx2, ny2, nbitplanes[0]);
- qtree_decode(infile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]);
- qtree_decode(infile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]);
- qtree_decode(infile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]);
- /*
- * make sure there is an EOF symbol (nybble=0) at end
- */
- if(input_nybble(infile) != 0){
- fprint(2, "dodecode: bad bit plane values\n");
- exits("format");
- }
- /*
- * get the sign bits
- */
- aend = &a[nel];
- mask = 0;
- bits = 0;;
- for(; a<aend; a++) {
- if(px = *a) {
- if(mask == 0) {
- mask = 0x80;
- bits = Bgetc(infile);
- }
- if(mask & bits)
- *a = -px;
- mask >>= 1;
- }
- }
- }
- static
- long getlong(uchar *p)
- {
- return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
- }
|