xref: /inferno-os/libdraw/unloadimage.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include "draw.h"
3 #include "kernel.h"
4 #include "interp.h"
5 
6 int
unloadimage(Image * i,Rectangle r,uchar * data,int ndata)7 unloadimage(Image *i, Rectangle r, uchar *data, int ndata)
8 {
9 	int bpl, n, ntot, dy;
10 	uchar *a;
11 	Display *d;
12 
13 	if(!rectinrect(r, i->r)){
14 		kwerrstr("unloadimage: bad rectangle");
15 		return -1;
16 	}
17 	bpl = bytesperline(r, i->depth);
18 	if(ndata < bpl*Dy(r)){
19 		kwerrstr("unloadimage: buffer too small");
20 		return -1;
21 	}
22 
23 	d = i->display;
24 	flushimage(d, 0);	/* make sure subsequent flush is for us only */
25 	ntot = 0;
26 	while(r.min.y < r.max.y){
27 		a = bufimage(d, 1+4+4*4);
28 		if(a == 0){
29 			kwerrstr("unloadimage: %r");
30 			return -1;
31 		}
32 		dy = 8000/bpl;
33 		if(dy <= 0){
34 			kwerrstr("unloadimage: image too wide");
35 			return -1;
36 		}
37 		if(dy > Dy(r))
38 			dy = Dy(r);
39 		a[0] = 'r';
40 		BPLONG(a+1, i->id);
41 		BPLONG(a+5, r.min.x);
42 		BPLONG(a+9, r.min.y);
43 		BPLONG(a+13, r.max.x);
44 		BPLONG(a+17, r.min.y+dy);
45 		if(flushimage(d, 0) < 0)
46 			return -1;
47 		if(d->local == 0)
48 			release();
49 		n = kchanio(d->datachan, data+ntot, ndata-ntot, OREAD);
50 		if(d->local == 0)
51 			acquire();
52 		if(n < 0)
53 			return n;
54 		ntot += n;
55 		r.min.y += dy;
56 	}
57 	return ntot;
58 }
59