creadimage.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 }