URI:
       tdssread.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tdssread.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 }