]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libdraw/readimage.c
remove debug print
[plan9front.git] / sys / src / libdraw / readimage.c
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         ulong 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                 if(i = creadimage(d, fd, dolock))
24                         goto Done;
25                 return nil;
26         }
27                 
28         if(readn(fd, hdr+11, 5*12-11) != 5*12-11)
29                 return nil;
30         if(d != nil)
31                 chunk = d->bufsize - 32;        /* a little room for header */
32         else
33                 chunk = 8192;
34
35         /*
36          * distinguish new channel descriptor from old ldepth.
37          * channel descriptors have letters as well as numbers,
38          * while ldepths are a single digit formatted as %-11d.
39          */
40         new = 0;
41         for(m=0; m<10; m++){
42                 if(hdr[m] != ' '){
43                         new = 1;
44                         break;
45                 }
46         }
47         if(hdr[11] != ' '){
48                 werrstr("readimage: bad format");
49                 return nil;
50         }
51         if(new){
52                 hdr[11] = '\0';
53                 if((chan = strtochan(hdr)) == 0){
54                         werrstr("readimage: bad channel string %s", hdr);
55                         return nil;
56                 }
57         }else{
58                 ldepth = ((int)hdr[10])-'0';
59                 if(ldepth<0 || ldepth>3){
60                         werrstr("readimage: bad ldepth %d", ldepth);
61                         return nil;
62                 }
63                 chan = drawld2chan[ldepth];
64         }
65
66         r.min.x = atoi(hdr+1*12);
67         r.min.y = atoi(hdr+2*12);
68         r.max.x = atoi(hdr+3*12);
69         r.max.y = atoi(hdr+4*12);
70         if(r.min.x>r.max.x || r.min.y>r.max.y){
71                 werrstr("readimage: bad rectangle");
72                 return nil;
73         }
74
75         miny = r.min.y;
76         maxy = r.max.y;
77
78         l = bytesperline(r, chantodepth(chan));
79         if(l > chunk)
80                 chunk = l;
81         if(d != nil){
82                 if(dolock)
83                         lockdisplay(d);
84                 i = allocimage(d, r, chan, 0, -1);
85                 if(dolock)
86                         unlockdisplay(d);
87                 if(i == nil)
88                         return nil;
89         }else{
90                 i = mallocz(sizeof(Image), 1);
91                 if(i == nil)
92                         return nil;
93         }
94         tmp = malloc(chunk);
95         if(tmp == nil)
96                 goto Err;
97         while(maxy > miny){
98                 dy = maxy - miny;
99                 if(dy*l > chunk)
100                         dy = chunk/l;
101                 n = dy*l;
102                 m = readn(fd, tmp, n);
103                 if(m != n){
104                         werrstr("readimage: read count %d not %d: %r", m, n);
105    Err:
106                         if(dolock)
107                                 lockdisplay(d);
108    Err1:
109                         freeimage(i);
110                         if(dolock)
111                                 unlockdisplay(d);
112                         free(tmp);
113                         return nil;
114                 }
115                 if(!new)        /* an old image: must flip all the bits */
116                         for(j=0; j<chunk; j++)
117                                 tmp[j] ^= 0xFF;
118
119                 if(d != nil){
120                         if(dolock)
121                                 lockdisplay(d);
122                         if(loadimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, chunk) <= 0)
123                                 goto Err1;
124                         if(dolock)
125                                 unlockdisplay(d);
126                 }
127                 miny += dy;
128         }
129         free(tmp);
130    Done:
131         setmalloctag(i, getcallerpc(&d));
132         return i;
133 }