URI:
       treadimage.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
       ---
       treadimage.c (2432B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 
            5 Image*
            6 readimage(Display *d, int fd, int dolock)
            7 {
            8         char hdr[5*12+1];
            9         int dy;
           10         int new;
           11         uint l, n;
           12         int m, j, chunk;
           13         int miny, maxy;
           14         Rectangle r;
           15         int ldepth;
           16         u32int chan;
           17         uchar *tmp;
           18         Image *i;
           19 
           20         if(readn(fd, hdr, 11) != 11)
           21                 return nil;
           22         if(memcmp(hdr, "compressed\n", 11) == 0)
           23                 return creadimage(d, fd, dolock);
           24         if(readn(fd, hdr+11, 5*12-11) != 5*12-11)
           25                 return nil;
           26         if(d)
           27                 chunk = d->bufsize - 32;        /* a little room for header */
           28         else
           29                 chunk = 8192;
           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         if(d){
           76                 if(dolock)
           77                         lockdisplay(d);
           78                 i = allocimage(d, r, chan, 0, -1);
           79                 if(dolock)
           80                         unlockdisplay(d);
           81                 if(i == nil)
           82                         return nil;
           83         }else{
           84                 i = mallocz(sizeof(Image), 1);
           85                 if(i == nil)
           86                         return nil;
           87         }
           88 
           89         tmp = malloc(chunk);
           90         if(tmp == nil)
           91                 goto Err;
           92         while(maxy > miny){
           93                 dy = maxy - miny;
           94                 if(dy*l > chunk)
           95                         dy = chunk/l;
           96                 if(dy <= 0){
           97                         werrstr("readimage: image too wide for buffer");
           98                         goto Err;
           99                 }
          100                 n = dy*l;
          101                 m = readn(fd, tmp, n);
          102                 if(m != n){
          103                         werrstr("readimage: read count %d not %d: %r", m, n);
          104    Err:
          105                         if(dolock)
          106                                 lockdisplay(d);
          107    Err1:
          108                          freeimage(i);
          109                         if(dolock)
          110                                 unlockdisplay(d);
          111                         free(tmp);
          112                         return nil;
          113                 }
          114                 if(!new)        /* an old image: must flip all the bits */
          115                         for(j=0; j<chunk; j++)
          116                                 tmp[j] ^= 0xFF;
          117 
          118                 if(d){
          119                         if(dolock)
          120                                 lockdisplay(d);
          121                         if(loadimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, chunk) <= 0)
          122                                 goto Err1;
          123                         if(dolock)
          124                                 unlockdisplay(d);
          125                 }
          126                 miny += dy;
          127         }
          128         free(tmp);
          129         return i;
          130 }