cload.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <memdraw.h>
  5. int
  6. cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
  7. {
  8. int y, bpl, c, cnt, offs;
  9. uchar mem[NMEM], *memp, *omemp, *emem, *linep, *elinep, *u, *eu;
  10. if(!rectinrect(r, i->r))
  11. return -1;
  12. bpl = bytesperline(r, i->depth);
  13. u = data;
  14. eu = data+ndata;
  15. memp = mem;
  16. emem = mem+NMEM;
  17. y = r.min.y;
  18. linep = byteaddr(i, Pt(r.min.x, y));
  19. elinep = linep+bpl;
  20. for(;;){
  21. if(linep == elinep){
  22. if(++y == r.max.y)
  23. break;
  24. linep = byteaddr(i, Pt(r.min.x, y));
  25. elinep = linep+bpl;
  26. }
  27. if(u == eu){ /* buffer too small */
  28. return -1;
  29. }
  30. c = *u++;
  31. if(c >= 128){
  32. for(cnt=c-128+1; cnt!=0 ;--cnt){
  33. if(u == eu){ /* buffer too small */
  34. return -1;
  35. }
  36. if(linep == elinep){ /* phase error */
  37. return -1;
  38. }
  39. *linep++ = *u;
  40. *memp++ = *u++;
  41. if(memp == emem)
  42. memp = mem;
  43. }
  44. }
  45. else{
  46. if(u == eu) /* short buffer */
  47. return -1;
  48. offs = *u++ + ((c&3)<<8)+1;
  49. if(memp-mem < offs)
  50. omemp = memp+(NMEM-offs);
  51. else
  52. omemp = memp-offs;
  53. for(cnt=(c>>2)+NMATCH; cnt!=0; --cnt){
  54. if(linep == elinep) /* phase error */
  55. return -1;
  56. *linep++ = *omemp;
  57. *memp++ = *omemp++;
  58. if(omemp == emem)
  59. omemp = mem;
  60. if(memp == emem)
  61. memp = mem;
  62. }
  63. }
  64. }
  65. return u-data;
  66. }