tcreadimage.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tcreadimage.c (2380B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <draw.h> | |
4 | |
5 Image * | |
6 creadimage(Display *d, int fd, int dolock) | |
7 { | |
8 char hdr[5*12+1]; | |
9 Rectangle r; | |
10 int m, nb, miny, maxy, new, ldepth, ncblock; | |
11 uchar *buf, *a; | |
12 Image *i; | |
13 u32int chan; | |
14 | |
15 if(readn(fd, hdr, 5*12) != 5*12) | |
16 return nil; | |
17 | |
18 /* | |
19 * distinguish new channel descriptor from old ldepth. | |
20 * channel descriptors have letters as well as numbers, | |
21 * while ldepths are a single digit formatted as %-11d. | |
22 */ | |
23 new = 0; | |
24 for(m=0; m<10; m++){ | |
25 if(hdr[m] != ' '){ | |
26 new = 1; | |
27 break; | |
28 } | |
29 } | |
30 if(hdr[11] != ' '){ | |
31 werrstr("creadimage: bad format"); | |
32 return nil; | |
33 } | |
34 if(new){ | |
35 hdr[11] = '\0'; | |
36 if((chan = strtochan(hdr)) == 0){ | |
37 werrstr("creadimage: bad channel string %s", hdr… | |
38 return nil; | |
39 } | |
40 }else{ | |
41 ldepth = ((int)hdr[10])-'0'; | |
42 if(ldepth<0 || ldepth>3){ | |
43 werrstr("creadimage: bad ldepth %d", ldepth); | |
44 return nil; | |
45 } | |
46 chan = drawld2chan[ldepth]; | |
47 } | |
48 r.min.x=atoi(hdr+1*12); | |
49 r.min.y=atoi(hdr+2*12); | |
50 r.max.x=atoi(hdr+3*12); | |
51 r.max.y=atoi(hdr+4*12); | |
52 if(r.min.x>r.max.x || r.min.y>r.max.y){ | |
53 werrstr("creadimage: bad rectangle"); | |
54 return nil; | |
55 } | |
56 | |
57 if(d){ | |
58 if(dolock) | |
59 lockdisplay(d); | |
60 i = allocimage(d, r, chan, 0, 0); | |
61 if(dolock) | |
62 unlockdisplay(d); | |
63 if(i == nil) | |
64 return nil; | |
65 }else{ | |
66 i = mallocz(sizeof(Image), 1); | |
67 if(i == nil) | |
68 return nil; | |
69 } | |
70 ncblock = _compblocksize(r, chantodepth(chan)); | |
71 buf = malloc(ncblock); | |
72 if(buf == nil) | |
73 goto Errout; | |
74 miny = r.min.y; | |
75 while(miny != r.max.y){ | |
76 if(readn(fd, hdr, 2*12) != 2*12){ | |
77 Errout: | |
78 if(dolock) | |
79 lockdisplay(d); | |
80 Erroutlock: | |
81 freeimage(i); | |
82 if(dolock) | |
83 unlockdisplay(d); | |
84 free(buf); | |
85 return nil; | |
86 } | |
87 maxy = atoi(hdr+0*12); | |
88 nb = atoi(hdr+1*12); | |
89 if(maxy<=miny || r.max.y<maxy){ | |
90 werrstr("creadimage: bad maxy %d", maxy); | |
91 goto Errout; | |
92 } | |
93 if(nb<=0 || ncblock<nb){ | |
94 werrstr("creadimage: bad count %d", nb); | |
95 goto Errout; | |
96 } | |
97 if(readn(fd, buf, nb)!=nb) | |
98 goto Errout; | |
99 if(d){ | |
100 if(dolock) | |
101 lockdisplay(d); | |
102 a = bufimage(i->display, 21+nb); | |
103 if(a == nil) | |
104 goto Erroutlock; | |
105 a[0] = 'Y'; | |
106 BPLONG(a+1, i->id); | |
107 BPLONG(a+5, r.min.x); | |
108 BPLONG(a+9, miny); | |
109 BPLONG(a+13, r.max.x); | |
110 BPLONG(a+17, maxy); | |
111 if(!new) /* old image: flip the data bits… | |
112 _twiddlecompressed(buf, nb); | |
113 memmove(a+21, buf, nb); | |
114 if(dolock) | |
115 unlockdisplay(d); | |
116 } | |
117 miny = maxy; | |
118 } | |
119 free(buf); | |
120 return i; | |
121 } |