7 2d bitmask with test and set operations
11 btm_new(i_img_dim xsize,i_img_dim ysize) {
14 btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap)); /* checked 4jul05 tonyc */
15 bytes = (xsize*ysize+8)/8;
16 if (bytes * 8 / ysize < xsize-1) { /* this is kind of rough */
17 fprintf(stderr, "Integer overflow allocating bitmap (" i_DFp ")",
18 i_DFcp(xsize, ysize));
21 btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
24 memset(btm->data, 0, bytes);
30 btm_destroy(struct i_bitmap *btm) {
37 btm_test(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
39 if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) return 0;
41 return (1<<(btno%8))&(btm->data[btno/8]);
45 btm_set(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
47 if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) abort();
49 btm->data[btno/8]|=1<<(btno%8);
57 Bucketed linked list - stack type
61 llink_new(struct llink* p,size_t size);
63 llist_llink_push(struct llist *lst, struct llink *lnk,const void *data);
65 llink_destroy(struct llink* l);
69 =synopsis struct llist *l = llist_new(100, sizeof(foo);
71 Create a new stack structure. Implemented as a linked list of pools.
79 multip - number of entries in each pool
83 ssize - size of the objects being pushed/popped
91 llist_new(int multip, size_t ssize) {
93 l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */
104 =synopsis llist_push(l, &foo);
106 Push an item on the stack.
112 llist_push(struct llist *l,const void *data) {
113 size_t ssize = l->ssize;
114 int multip = l->multip;
116 /* fprintf(stderr,"llist_push: data=0x%08X\n",data);
117 fprintf(stderr,"Chain size: %d\n", l->count); */
120 l->t = l->h = llink_new(NULL,ssize*multip); /* Tail is empty - list is empty */
121 /* fprintf(stderr,"Chain empty - extended\n"); */
123 else { /* Check for overflow in current tail */
124 if (l->t->fill >= l->multip) {
125 struct llink* nt = llink_new(l->t, ssize*multip);
128 /* fprintf(stderr,"Chain extended\n"); */
131 /* fprintf(stderr,"0x%08X\n",l->t); */
132 if (llist_llink_push(l,l->t,data)) {
133 i_fatal(3, "out of memory\n");
140 Pop an item off the list, storing it at C<data> which must have enough room for an object of the size supplied to llist_new().
142 returns 0 if the list is empty
148 llist_pop(struct llist *l,void *data) {
149 /* int ssize=l->ssize;
150 int multip=l->multip;*/
151 if (l->t == NULL) return 0;
154 memcpy(data,(char*)(l->t->data)+l->ssize*l->t->fill,l->ssize);
156 if (!l->t->fill) { /* This link empty */
157 if (l->t->p == NULL) { /* and it's the only link */
163 llink_destroy(l->t->n);
170 llist_dump(struct llist *l) {
176 for(j=0;j<lnk->fill;j++) {
177 /* memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
178 /*memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
179 printf("%d - %p\n",i,*(void **)((char *)(lnk->data)+l->ssize*j));
187 =item llist_destroy()
189 Destroy a linked-list based stack.
195 llist_destroy(struct llist *l) {
196 struct llink *t,*lnk = l->h;
197 while( lnk != NULL ) {
207 static struct llink *
208 llink_new(struct llink* p,size_t size) {
210 l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
214 l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
218 /* free's the data pointer, itself, and sets the previous' next pointer to null */
221 llink_destroy(struct llink* l) {
222 if (l->p != NULL) { l->p->n=NULL; }
228 /* if it returns true there wasn't room for the
232 llist_llink_push(struct llist *lst, struct llink *lnk, const void *data) {
234 multip = lst->multip;
236 /* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
237 fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
238 if (lnk->fill == lst->multip) return 1;
239 /* memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize); */
240 memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize);
242 /* printf("data=%X res=%X\n",*(int*)data,*(int*)(lnk->data));*/
249 Oct-tree implementation
257 t=(struct octt*)mymalloc(sizeof(struct octt)); /* checked 4jul05 tonyc */
258 for(i=0;i<8;i++) t->t[i]=NULL;
264 /* returns 1 if the colors wasn't in the octtree already */
268 octt_add(struct octt *ct,unsigned char r,unsigned char g,unsigned char b) {
275 /* printf("[r,g,b]=[%d,%d,%d]\n",r,g,b); */
278 ci=((!!(r&cm))<<2)+((!!(g&cm))<<1)+!!(b&cm);
279 /* printf("idx[%d]=%d\n",i,ci); */
280 if (c->t[ci] == NULL) {
286 c->cnt++; /* New. The only thing really needed (I think) */
292 octt_delete(struct octt *ct) {
294 for(i=0;i<8;i++) if (ct->t[i] != NULL) octt_delete(ct->t[i]); /* do not free instance here because it will free itself */
300 octt_dump(struct octt *ct) {
302 /* printf("node [0x%08X] -> (%d)\n",ct,ct->cnt); */
304 if (ct->t[i] != NULL)
305 printf("[ %d ] -> %p\n", i, (void *)ct->t[i]);
307 if (ct->t[i] != NULL)
311 /* note that all calls of octt_count are operating on the same overflow
312 variable so all calls will know at the same time if an overflow
313 has occured and stops there. */
316 octt_count(struct octt *ct,int *tot,int max,int *overflow) {
319 if (!(*overflow)) return;
320 for(i=0;i<8;i++) if (ct->t[i]!=NULL) {
321 octt_count(ct->t[i],tot,max,overflow);
325 if ( (*tot) > (*overflow) ) *overflow=0;
328 /* This whole function is new */
329 /* walk through the tree and for each colour, store its seen count in the
330 space pointed by *col_usage_it_adr */
332 octt_histo(struct octt *ct, unsigned int **col_usage_it_adr) {
335 for(i = 0; i < 8; i++)
336 if (ct->t[i] != NULL) {
337 octt_histo(ct->t[i], col_usage_it_adr);
341 *(*col_usage_it_adr)++ = ct->cnt;
348 return x < 0 ? -x : x;