alloc.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <memdraw.h>
  5. #include <pool.h>
  6. void
  7. memimagemove(void *from, void *to)
  8. {
  9. Memdata *md;
  10. md = *(Memdata**)to;
  11. if(md->base != from){
  12. print("compacted data not right: #%p\n", md->base);
  13. abort();
  14. }
  15. md->base = to;
  16. /* if allocmemimage changes this must change too */
  17. md->bdata = (uchar*)&md->base[2];
  18. }
  19. Memimage*
  20. allocmemimaged(Rectangle r, ulong chan, Memdata *md)
  21. {
  22. int d;
  23. ulong l;
  24. Memimage *i;
  25. if((d = chantodepth(chan)) == 0) {
  26. werrstr("bad channel descriptor %.8lux", chan);
  27. return nil;
  28. }
  29. l = wordsperline(r, d);
  30. i = mallocz(sizeof(Memimage), 1);
  31. if(i == nil)
  32. return nil;
  33. i->data = md;
  34. i->zero = sizeof(ulong)*l*r.min.y;
  35. if(r.min.x >= 0)
  36. i->zero += (r.min.x*d)/8;
  37. else
  38. i->zero -= (-r.min.x*d+7)/8;
  39. i->zero = -i->zero;
  40. i->width = l;
  41. i->r = r;
  42. i->clipr = r;
  43. i->flags = 0;
  44. i->layer = nil;
  45. i->cmap = memdefcmap;
  46. if(memsetchan(i, chan) < 0){
  47. free(i);
  48. return nil;
  49. }
  50. return i;
  51. }
  52. Memimage*
  53. allocmemimage(Rectangle r, ulong chan)
  54. {
  55. int d;
  56. ulong l, nw;
  57. Memdata *md;
  58. Memimage *i;
  59. if((d = chantodepth(chan)) == 0) {
  60. werrstr("bad channel descriptor %.8lux", chan);
  61. return nil;
  62. }
  63. l = wordsperline(r, d);
  64. nw = l*Dy(r);
  65. md = malloc(sizeof(Memdata));
  66. if(md == nil)
  67. return nil;
  68. md->ref = 1;
  69. md->base = poolalloc(imagmem, (2+nw)*sizeof(ulong));
  70. if(md->base == nil){
  71. free(md);
  72. return nil;
  73. }
  74. md->base[0] = (ulong)md;
  75. md->base[1] = getcallerpc(&r);
  76. /* if this changes, memimagemove must change too */
  77. md->bdata = (uchar*)&md->base[2];
  78. md->allocd = 1;
  79. i = allocmemimaged(r, chan, md);
  80. if(i == nil){
  81. poolfree(imagmem, md->base);
  82. free(md);
  83. return nil;
  84. }
  85. md->imref = i;
  86. return i;
  87. }
  88. void
  89. freememimage(Memimage *i)
  90. {
  91. if(i == nil)
  92. return;
  93. if(i->data->ref-- == 1 && i->data->allocd){
  94. if(i->data->base)
  95. poolfree(imagmem, i->data->base);
  96. free(i->data);
  97. }
  98. free(i);
  99. }
  100. /*
  101. * Wordaddr is deprecated.
  102. */
  103. ulong*
  104. wordaddr(Memimage *i, Point p)
  105. {
  106. return (ulong*) ((ulong)byteaddr(i, p) & ~(sizeof(ulong)-1));
  107. }
  108. uchar*
  109. byteaddr(Memimage *i, Point p)
  110. {
  111. uchar *a;
  112. a = i->data->bdata+i->zero+sizeof(ulong)*p.y*i->width;
  113. if(i->depth < 8){
  114. /*
  115. * We need to always round down,
  116. * but C rounds toward zero.
  117. */
  118. int np;
  119. np = 8/i->depth;
  120. if(p.x < 0)
  121. return a+(p.x-np+1)/np;
  122. else
  123. return a+p.x/np;
  124. }
  125. else
  126. return a+p.x*(i->depth/8);
  127. }
  128. int
  129. memsetchan(Memimage *i, ulong chan)
  130. {
  131. int d;
  132. int t, j, k;
  133. ulong cc;
  134. int bytes;
  135. if((d = chantodepth(chan)) == 0) {
  136. werrstr("bad channel descriptor");
  137. return -1;
  138. }
  139. i->depth = d;
  140. i->chan = chan;
  141. i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes);
  142. bytes = 1;
  143. for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){
  144. t=TYPE(cc);
  145. if(t < 0 || t >= NChan){
  146. werrstr("bad channel string");
  147. return -1;
  148. }
  149. if(t == CGrey)
  150. i->flags |= Fgrey;
  151. if(t == CAlpha)
  152. i->flags |= Falpha;
  153. if(t == CMap && i->cmap == nil){
  154. i->cmap = memdefcmap;
  155. i->flags |= Fcmap;
  156. }
  157. i->shift[t] = j;
  158. i->mask[t] = (1<<NBITS(cc))-1;
  159. i->nbits[t] = NBITS(cc);
  160. if(NBITS(cc) != 8)
  161. bytes = 0;
  162. }
  163. i->nchan = k;
  164. if(bytes)
  165. i->flags |= Fbytes;
  166. return 0;
  167. }