1*7dd7cddfSDavid du Colombier #include "../lib9.h" 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier #include "../libdraw/draw.h" 4*7dd7cddfSDavid du Colombier #include "../libmemdraw/memdraw.h" 5*7dd7cddfSDavid du Colombier 6*7dd7cddfSDavid du Colombier #define CHUNK 8000 7*7dd7cddfSDavid du Colombier 8*7dd7cddfSDavid du Colombier Memimage* 9*7dd7cddfSDavid du Colombier readmemimage(int fd) 10*7dd7cddfSDavid du Colombier { 11*7dd7cddfSDavid du Colombier char hdr[5*12+1]; 12*7dd7cddfSDavid du Colombier int dy; 13*7dd7cddfSDavid du Colombier ulong chan; 14*7dd7cddfSDavid du Colombier uint l, m, n; 15*7dd7cddfSDavid du Colombier int j; 16*7dd7cddfSDavid du Colombier int new, miny, maxy; 17*7dd7cddfSDavid du Colombier Rectangle r; 18*7dd7cddfSDavid du Colombier uchar *tmp; 19*7dd7cddfSDavid du Colombier int ldepth; 20*7dd7cddfSDavid du Colombier Memimage *i; 21*7dd7cddfSDavid du Colombier 22*7dd7cddfSDavid du Colombier if(readn(fd, hdr, 11) != 11) 23*7dd7cddfSDavid du Colombier return nil; 24*7dd7cddfSDavid du Colombier if(memcmp(hdr, "compressed\n", 11) == 0) 25*7dd7cddfSDavid du Colombier return creadmemimage(fd); 26*7dd7cddfSDavid du Colombier if(readn(fd, hdr+11, 5*12-11) != 5*12-11) 27*7dd7cddfSDavid du Colombier return nil; 28*7dd7cddfSDavid du Colombier 29*7dd7cddfSDavid du Colombier /* 30*7dd7cddfSDavid du Colombier * distinguish new channel descriptor from old ldepth. 31*7dd7cddfSDavid du Colombier * channel descriptors have letters as well as numbers, 32*7dd7cddfSDavid du Colombier * while ldepths are a single digit formatted as %-11d. 33*7dd7cddfSDavid du Colombier */ 34*7dd7cddfSDavid du Colombier new = 0; 35*7dd7cddfSDavid du Colombier for(m=0; m<10; m++){ 36*7dd7cddfSDavid du Colombier if(hdr[m] != ' '){ 37*7dd7cddfSDavid du Colombier new = 1; 38*7dd7cddfSDavid du Colombier break; 39*7dd7cddfSDavid du Colombier } 40*7dd7cddfSDavid du Colombier } 41*7dd7cddfSDavid du Colombier if(hdr[11] != ' '){ 42*7dd7cddfSDavid du Colombier werrstr("readimage: bad format"); 43*7dd7cddfSDavid du Colombier return nil; 44*7dd7cddfSDavid du Colombier } 45*7dd7cddfSDavid du Colombier if(new){ 46*7dd7cddfSDavid du Colombier hdr[11] = '\0'; 47*7dd7cddfSDavid du Colombier if((chan = strtochan(hdr)) == 0){ 48*7dd7cddfSDavid du Colombier werrstr("readimage: bad channel string %s", hdr); 49*7dd7cddfSDavid du Colombier return nil; 50*7dd7cddfSDavid du Colombier } 51*7dd7cddfSDavid du Colombier }else{ 52*7dd7cddfSDavid du Colombier ldepth = ((int)hdr[10])-'0'; 53*7dd7cddfSDavid du Colombier if(ldepth<0 || ldepth>3){ 54*7dd7cddfSDavid du Colombier werrstr("readimage: bad ldepth %d", ldepth); 55*7dd7cddfSDavid du Colombier return nil; 56*7dd7cddfSDavid du Colombier } 57*7dd7cddfSDavid du Colombier chan = drawld2chan[ldepth]; 58*7dd7cddfSDavid du Colombier } 59*7dd7cddfSDavid du Colombier 60*7dd7cddfSDavid du Colombier r.min.x = atoi(hdr+1*12); 61*7dd7cddfSDavid du Colombier r.min.y = atoi(hdr+2*12); 62*7dd7cddfSDavid du Colombier r.max.x = atoi(hdr+3*12); 63*7dd7cddfSDavid du Colombier r.max.y = atoi(hdr+4*12); 64*7dd7cddfSDavid du Colombier if(r.min.x>r.max.x || r.min.y>r.max.y){ 65*7dd7cddfSDavid du Colombier werrstr("readimage: bad rectangle"); 66*7dd7cddfSDavid du Colombier return nil; 67*7dd7cddfSDavid du Colombier } 68*7dd7cddfSDavid du Colombier 69*7dd7cddfSDavid du Colombier miny = r.min.y; 70*7dd7cddfSDavid du Colombier maxy = r.max.y; 71*7dd7cddfSDavid du Colombier 72*7dd7cddfSDavid du Colombier l = bytesperline(r, chantodepth(chan)); 73*7dd7cddfSDavid du Colombier i = allocmemimage(r, chan); 74*7dd7cddfSDavid du Colombier if(i == nil) 75*7dd7cddfSDavid du Colombier return nil; 76*7dd7cddfSDavid du Colombier tmp = malloc(CHUNK); 77*7dd7cddfSDavid du Colombier if(tmp == nil) 78*7dd7cddfSDavid du Colombier goto Err; 79*7dd7cddfSDavid du Colombier while(maxy > miny){ 80*7dd7cddfSDavid du Colombier dy = maxy - miny; 81*7dd7cddfSDavid du Colombier if(dy*l > CHUNK) 82*7dd7cddfSDavid du Colombier dy = CHUNK/l; 83*7dd7cddfSDavid du Colombier if(dy <= 0){ 84*7dd7cddfSDavid du Colombier werrstr("readmemimage: image too wide for buffer"); 85*7dd7cddfSDavid du Colombier goto Err; 86*7dd7cddfSDavid du Colombier } 87*7dd7cddfSDavid du Colombier n = dy*l; 88*7dd7cddfSDavid du Colombier m = readn(fd, tmp, n); 89*7dd7cddfSDavid du Colombier if(m != n){ 90*7dd7cddfSDavid du Colombier werrstr("readmemimage: read count %d not %d: %r", m, n); 91*7dd7cddfSDavid du Colombier Err: 92*7dd7cddfSDavid du Colombier freememimage(i); 93*7dd7cddfSDavid du Colombier free(tmp); 94*7dd7cddfSDavid du Colombier return nil; 95*7dd7cddfSDavid du Colombier } 96*7dd7cddfSDavid du Colombier if(!new) /* an old image: must flip all the bits */ 97*7dd7cddfSDavid du Colombier for(j=0; j<CHUNK; j++) 98*7dd7cddfSDavid du Colombier tmp[j] ^= 0xFF; 99*7dd7cddfSDavid du Colombier 100*7dd7cddfSDavid du Colombier if(loadmemimage(i, Rect(r.min.x, miny, r.max.x, miny+dy), tmp, CHUNK) <= 0) 101*7dd7cddfSDavid du Colombier goto Err; 102*7dd7cddfSDavid du Colombier miny += dy; 103*7dd7cddfSDavid du Colombier } 104*7dd7cddfSDavid du Colombier free(tmp); 105*7dd7cddfSDavid du Colombier return i; 106*7dd7cddfSDavid du Colombier } 107