cread.c (1983B)
1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 #include <memdraw.h> 5 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; 15 16 if(readn(fd, hdr, 5*12) != 5*12){ 17 werrstr("readmemimage: short header (2)"); 18 return nil; 19 } 20 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 } 59 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 }