URI:
       tread.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
       ---
       tread.c (2160B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <memdraw.h>
            5 
            6 Memimage*
            7 readmemimage(int fd)
            8 {
            9         char hdr[5*12+1];
           10         int dy;
           11         u32int chan;
           12         uint l, n;
           13         int m, j;
           14         int new, miny, maxy;
           15         Rectangle r;
           16         uchar *tmp;
           17         int ldepth, chunk;
           18         Memimage *i;
           19 
           20         if(readn(fd, hdr, 11) != 11){
           21                 werrstr("readimage: short header");
           22                 return nil;
           23         }
           24         if(memcmp(hdr, "compressed\n", 11) == 0)
           25                 return creadmemimage(fd);
           26         if(readn(fd, hdr+11, 5*12-11) != 5*12-11){
           27                 werrstr("readimage: short header (2)");
           28                 return nil;
           29         }
           30 
           31         /*
           32          * distinguish new channel descriptor from old ldepth.
           33          * channel descriptors have letters as well as numbers,
           34          * while ldepths are a single digit formatted as %-11d.
           35          */
           36         new = 0;
           37         for(m=0; m<10; m++){
           38                 if(hdr[m] != ' '){
           39                         new = 1;
           40                         break;
           41                 }
           42         }
           43         if(hdr[11] != ' '){
           44                 werrstr("readimage: bad format");
           45                 return nil;
           46         }
           47         if(new){
           48                 hdr[11] = '\0';
           49                 if((chan = strtochan(hdr)) == 0){
           50                         werrstr("readimage: bad channel string %s", hdr);
           51                         return nil;
           52                 }
           53         }else{
           54                 ldepth = ((int)hdr[10])-'0';
           55                 if(ldepth<0 || ldepth>3){
           56                         werrstr("readimage: bad ldepth %d", ldepth);
           57                         return nil;
           58                 }
           59                 chan = drawld2chan[ldepth];
           60         }
           61 
           62         r.min.x = atoi(hdr+1*12);
           63         r.min.y = atoi(hdr+2*12);
           64         r.max.x = atoi(hdr+3*12);
           65         r.max.y = atoi(hdr+4*12);
           66         if(r.min.x>r.max.x || r.min.y>r.max.y){
           67                 werrstr("readimage: bad rectangle");
           68                 return nil;
           69         }
           70 
           71         miny = r.min.y;
           72         maxy = r.max.y;
           73 
           74         l = bytesperline(r, chantodepth(chan));
           75         i = allocmemimage(r, chan);
           76         if(i == nil)
           77                 return nil;
           78         chunk = 32*1024;
           79         if(chunk < l)
           80                 chunk = l;
           81         tmp = malloc(chunk);
           82         if(tmp == nil)
           83                 goto Err;
           84         while(maxy > miny){
           85                 dy = maxy - miny;
           86                 if(dy*l > chunk)
           87                         dy = chunk/l;
           88                 if(dy <= 0){
           89                         werrstr("readmemimage: image too wide for buffer");
           90                         goto Err;
           91                 }
           92                 n = dy*l;
           93                 m = readn(fd, tmp, n);
           94                 if(m != n){
           95                         werrstr("readmemimage: read count %d not %d: %r", m, n);
           96    Err:
           97                          freememimage(i);
           98                         free(tmp);
           99                         return nil;
          100                 }
          101                 if(!new)        /* an old image: must flip all the bits */
          102                         for(j=0; j<chunk; j++)
          103                                 tmp[j] ^= 0xFF;
          104 
          105                 if(loadmemimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, chunk) <= 0)
          106                         goto Err;
          107                 miny += dy;
          108         }
          109         free(tmp);
          110         return i;
          111 }