treadimage.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
treadimage.c (2432B)
---
     1 #include 
     2 #include 
     3 #include 
     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