Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <memdraw.h>
6 Memimage*
7 creadmemimage(int fd)
8 {
9 char hdr[5*12+1];
10 Rectangle r;
11 int m, nb, miny, maxy, new, ldepth, ncblock;
12 uchar *buf;
13 Memimage *i;
14 u32int chan;
16 if(readn(fd, hdr, 5*12) != 5*12){
17 werrstr("readmemimage: short header (2)");
18 return nil;
19 }
21 /*
22 * distinguish new channel descriptor from old ldepth.
23 * channel descriptors have letters as well as numbers,
24 * while ldepths are a single digit formatted as %-11d.
25 */
26 new = 0;
27 for(m=0; m<10; m++){
28 if(hdr[m] != ' '){
29 new = 1;
30 break;
31 }
32 }
33 if(hdr[11] != ' '){
34 werrstr("creadimage: bad format");
35 return nil;
36 }
37 if(new){
38 hdr[11] = '\0';
39 if((chan = strtochan(hdr)) == 0){
40 werrstr("creadimage: bad channel string %s", hdr);
41 return nil;
42 }
43 }else{
44 ldepth = ((int)hdr[10])-'0';
45 if(ldepth<0 || ldepth>3){
46 werrstr("creadimage: bad ldepth %d", ldepth);
47 return nil;
48 }
49 chan = drawld2chan[ldepth];
50 }
51 r.min.x=atoi(hdr+1*12);
52 r.min.y=atoi(hdr+2*12);
53 r.max.x=atoi(hdr+3*12);
54 r.max.y=atoi(hdr+4*12);
55 if(r.min.x>r.max.x || r.min.y>r.max.y){
56 werrstr("creadimage: bad rectangle");
57 return nil;
58 }
60 i = allocmemimage(r, chan);
61 if(i == nil)
62 return nil;
63 ncblock = _compblocksize(r, i->depth);
64 buf = malloc(ncblock);
65 if(buf == nil)
66 goto Errout;
67 miny = r.min.y;
68 while(miny != r.max.y){
69 if(readn(fd, hdr, 2*12) != 2*12){
70 Shortread:
71 werrstr("readmemimage: short read");
72 Errout:
73 freememimage(i);
74 free(buf);
75 return nil;
76 }
77 maxy = atoi(hdr+0*12);
78 nb = atoi(hdr+1*12);
79 if(maxy<=miny || r.max.y<maxy){
80 werrstr("readimage: bad maxy %d", maxy);
81 goto Errout;
82 }
83 if(nb<=0 || ncblock<nb){
84 werrstr("readimage: bad count %d", nb);
85 goto Errout;
86 }
87 if(readn(fd, buf, nb)!=nb)
88 goto Shortread;
89 if(!new) /* old image: flip the data bits */
90 _twiddlecompressed(buf, nb);
91 cloadmemimage(i, Rect(r.min.x, miny, r.max.x, maxy), buf, nb);
92 miny = maxy;
93 }
94 free(buf);
95 return i;
96 }