|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <draw.h> | 
|  | #include <memdraw.h> | 
|  |  | 
|  | int | 
|  | _cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) | 
|  | { | 
|  | int y, bpl, c, cnt, offs; | 
|  | uchar mem[NMEM], *memp, *omemp, *emem, *linep, *elinep, *u, *eu; | 
|  |  | 
|  | if(!rectinrect(r, i->r)) | 
|  | return -1; | 
|  | bpl = bytesperline(r, i->depth); | 
|  | u = data; | 
|  | eu = data+ndata; | 
|  | memp = mem; | 
|  | emem = mem+NMEM; | 
|  | y = r.min.y; | 
|  | linep = byteaddr(i, Pt(r.min.x, y)); | 
|  | elinep = linep+bpl; | 
|  | for(;;){ | 
|  | if(linep == elinep){ | 
|  | if(++y == r.max.y) | 
|  | break; | 
|  | linep = byteaddr(i, Pt(r.min.x, y)); | 
|  | elinep = linep+bpl; | 
|  | } | 
|  | if(u == eu){	/* buffer too small */ | 
|  | return -1; | 
|  | } | 
|  | c = *u++; | 
|  | if(c >= 128){ | 
|  | for(cnt=c-128+1; cnt!=0 ;--cnt){ | 
|  | if(u == eu){		/* buffer too small */ | 
|  | return -1; | 
|  | } | 
|  | if(linep == elinep){	/* phase error */ | 
|  | return -1; | 
|  | } | 
|  | *linep++ = *u; | 
|  | *memp++ = *u++; | 
|  | if(memp == emem) | 
|  | memp = mem; | 
|  | } | 
|  | } | 
|  | else{ | 
|  | if(u == eu)	/* short buffer */ | 
|  | return -1; | 
|  | offs = *u++ + ((c&3)<<8)+1; | 
|  | if(memp-mem < offs) | 
|  | omemp = memp+(NMEM-offs); | 
|  | else | 
|  | omemp = memp-offs; | 
|  | for(cnt=(c>>2)+NMATCH; cnt!=0; --cnt){ | 
|  | if(linep == elinep)	/* phase error */ | 
|  | return -1; | 
|  | *linep++ = *omemp; | 
|  | *memp++ = *omemp++; | 
|  | if(omemp == emem) | 
|  | omemp = mem; | 
|  | if(memp == emem) | 
|  | memp = mem; | 
|  | } | 
|  | } | 
|  | } | 
|  | return u-data; | 
|  | } |