-#include "io.h"
-#include "datatypes.h"
#include <stdlib.h>
#include <stdio.h>
-
-
+#include <string.h>
+#define IMAGER_NO_CONTEXT
+#include "imager.h"
/*
2d bitmask with test and set operations
*/
struct i_bitmap*
-btm_new(int xsize,int ysize) {
- int i;
+btm_new(i_img_dim xsize,i_img_dim ysize) {
+ size_t bytes;
struct i_bitmap *btm;
- btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap));
- btm->data=(char*)mymalloc((xsize*ysize+8)/8);
+ btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap)); /* checked 4jul05 tonyc */
+ bytes = (xsize*ysize+8)/8;
+ if (bytes * 8 / ysize < xsize-1) { /* this is kind of rough */
+ fprintf(stderr, "Integer overflow allocating bitmap (" i_DFp ")",
+ i_DFcp(xsize, ysize));
+ exit(3);
+ }
+ btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
btm->xsize=xsize;
btm->ysize=ysize;
- for(i=0;i<(xsize*ysize+8)/8;i++) btm->data[i]=0; /* Is this always needed */
+ memset(btm->data, 0, bytes);
return btm;
}
int
-btm_test(struct i_bitmap *btm,int x,int y) {
- int btno;
+btm_test(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
+ i_img_dim btno;
if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) return 0;
btno=btm->xsize*y+x;
return (1<<(btno%8))&(btm->data[btno/8]);
}
void
-btm_set(struct i_bitmap *btm,int x,int y) {
- int btno;
+btm_set(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
+ i_img_dim btno;
+ if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) abort();
btno=btm->xsize*y+x;
btm->data[btno/8]|=1<<(btno%8);
}
/*
- Linked list - stack type
+ Bucketed linked list - stack type
*/
-struct llink *
-llink_new(struct llink* p,int size) {
- struct llink *l;
- l=(struct llink*)mymalloc(sizeof(struct llink));
- l->n=NULL;
- l->p=p;
- l->fill=0;
- l->data=(void*)mymalloc(size);
- return l;
-}
+static struct llink *
+llink_new(struct llink* p,size_t size);
+static int
+llist_llink_push(struct llist *lst, struct llink *lnk,const void *data);
+static void
+llink_destroy(struct llink* l);
-/* free's the data pointer, itself, and sets the previous' next pointer to null */
+/*
+=item llist_new()
+=synopsis struct llist *l = llist_new(100, sizeof(foo);
-void
-llink_destroy(struct llink* l) {
- if (l->p != NULL) { l->p->n=NULL; }
- myfree(l->data);
- myfree(l);
-}
+Create a new stack structure. Implemented as a linked list of pools.
+Parameters:
-/* if it returns true there wasn't room for the
- item on the link */
+=over
-int
-llist_llink_push(struct llist *lst, struct llink *lnk,void *data) {
- int multip;
- multip=lst->multip;
+=item *
- /* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
- fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
- if (lnk->fill == lst->multip) return 1;
- /* memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize); */
- memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize);
-
- /* printf("data=%X res=%X\n",*(int*)data,*(int*)(lnk->data));*/
- lnk->fill++;
- lst->count++;
- return 0;
-}
+multip - number of entries in each pool
+
+=item *
+
+ssize - size of the objects being pushed/popped
+
+=back
+
+=cut
+*/
struct llist *
-llist_new(int multip, int ssize) {
+llist_new(int multip, size_t ssize) {
struct llist *l;
- l=(struct llist*)mymalloc(sizeof(struct llist));
- l->h=l->t=NULL;
- l->multip=multip;
- l->ssize=ssize;
- l->count=0;
+ l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */
+ l->h = NULL;
+ l->t = NULL;
+ l->multip = multip;
+ l->ssize = ssize;
+ l->count = 0;
return l;
}
+/*
+=item llist_push()
+=synopsis llist_push(l, &foo);
+
+Push an item on the stack.
+
+=cut
+*/
+
void
-llist_push(struct llist *l,void *data) {
- int ssize=l->ssize;
- int multip=l->multip;
+llist_push(struct llist *l,const void *data) {
+ size_t ssize = l->ssize;
+ int multip = l->multip;
- /* fprintf(stderr,"llist_push: data=0x%08X\n",data); */
-
- if (l->t == NULL) l->t=l->h=llink_new(NULL,ssize*multip); /* Tail is empty - list is empty */
+ /* fprintf(stderr,"llist_push: data=0x%08X\n",data);
+ fprintf(stderr,"Chain size: %d\n", l->count); */
+
+ if (l->t == NULL) {
+ l->t = l->h = llink_new(NULL,ssize*multip); /* Tail is empty - list is empty */
+ /* fprintf(stderr,"Chain empty - extended\n"); */
+ }
else { /* Check for overflow in current tail */
if (l->t->fill >= l->multip) {
- struct llink* nt=llink_new(l->t,ssize*multip);
+ struct llink* nt = llink_new(l->t, ssize*multip);
l->t->n=nt;
l->t=nt;
/* fprintf(stderr,"Chain extended\n"); */
}
}
/* fprintf(stderr,"0x%08X\n",l->t); */
- if (llist_llink_push(l,l->t,data)) { fprintf(stderr,"DARN!\n"); }
+ if (llist_llink_push(l,l->t,data)) {
+ dIMCTX;
+ im_fatal(aIMCTX, 3, "out of memory\n");
+ }
}
-/* returns 0 if the list is empty */
+/*
+=item llist_pop()
+
+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().
+
+returns 0 if the list is empty
+
+=cut
+*/
int
llist_pop(struct llist *l,void *data) {
if (l->t == NULL) return 0;
l->t->fill--;
l->count--;
- /* memcpy(data,(char*)(l->t->data)+l->ssize*l->t->fill,l->ssize); */
memcpy(data,(char*)(l->t->data)+l->ssize*l->t->fill,l->ssize);
if (!l->t->fill) { /* This link empty */
- if (l->t->p == NULL) l->h=l->t=NULL; /* and it's the only link */
+ if (l->t->p == NULL) { /* and it's the only link */
+ llink_destroy(l->t);
+ l->h = l->t = NULL;
+ }
else {
l->t=l->t->p;
llink_destroy(l->t->n);
void
llist_dump(struct llist *l) {
- int k,j;
+ int j;
int i=0;
struct llink *lnk;
lnk=l->h;
while(lnk != NULL) {
for(j=0;j<lnk->fill;j++) {
/* memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
- memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));
- printf("%d - %X\n",i,k);
+ /*memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
+ printf("%d - %p\n",i,*(void **)((char *)(lnk->data)+l->ssize*j));
i++;
}
lnk=lnk->n;
}
}
+/*
+=item llist_destroy()
+
+Destroy a linked-list based stack.
+
+=cut
+*/
+
void
llist_destroy(struct llist *l) {
struct llink *t,*lnk = l->h;
myfree(l);
}
+/* Links */
+
+static struct llink *
+llink_new(struct llink* p,size_t size) {
+ struct llink *l;
+ l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
+ l->n = NULL;
+ l->p = p;
+ l->fill = 0;
+ l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
+ return l;
+}
+/* free's the data pointer, itself, and sets the previous' next pointer to null */
+static void
+llink_destroy(struct llink* l) {
+ if (l->p != NULL) { l->p->n=NULL; }
+ myfree(l->data);
+ myfree(l);
+}
+/* if it returns true there wasn't room for the
+ item on the link */
+
+static int
+llist_llink_push(struct llist *lst, struct llink *lnk, const void *data) {
+ int multip;
+ multip = lst->multip;
+
+ /* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
+ fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
+ if (lnk->fill == lst->multip) return 1;
+ /* memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize); */
+ memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize);
+
+ /* printf("data=%X res=%X\n",*(int*)data,*(int*)(lnk->data));*/
+ lnk->fill++;
+ lst->count++;
+ return 0;
+}
/*
Oct-tree implementation
int i;
struct octt *t;
- t=(struct octt*)mymalloc(sizeof(struct octt));
+ t=(struct octt*)mymalloc(sizeof(struct octt)); /* checked 4jul05 tonyc */
for(i=0;i<8;i++) t->t[i]=NULL;
t->cnt=0;
return t;
octt_add(struct octt *ct,unsigned char r,unsigned char g,unsigned char b) {
struct octt *c;
int i,cm;
- int ci,idx[8];
+ int ci;
int rc;
rc=0;
c=ct;
/* printf("[r,g,b]=[%d,%d,%d]\n",r,g,b); */
- ct->cnt++;
for(i=7;i>-1;i--) {
cm=1<<i;
ci=((!!(r&cm))<<2)+((!!(g&cm))<<1)+!!(b&cm);
/* printf("idx[%d]=%d\n",i,ci); */
- if (c->t[ci] == NULL) { c->t[ci]=octt_new(); rc=1; }
+ if (c->t[ci] == NULL) {
+ c->t[ci]=octt_new();
+ rc=1;
+ }
c=c->t[ci];
- c->cnt++;
- idx[i]=ci;
}
+ c->cnt++; /* New. The only thing really needed (I think) */
return rc;
}
octt_dump(struct octt *ct) {
int i;
/* printf("node [0x%08X] -> (%d)\n",ct,ct->cnt); */
- for(i=0;i<8;i++) if (ct->t[i] != NULL) printf("[ %d ] -> 0x%08X\n",i,(unsigned int)ct->t[i]);
- for(i=0;i<8;i++) if (ct->t[i] != NULL) octt_dump(ct->t[i]);
+ for(i=0;i<8;i++)
+ if (ct->t[i] != NULL)
+ printf("[ %d ] -> %p\n", i, (void *)ct->t[i]);
+ for(i=0;i<8;i++)
+ if (ct->t[i] != NULL)
+ octt_dump(ct->t[i]);
}
/* note that all calls of octt_count are operating on the same overflow
if (!c) (*tot)++;
if ( (*tot) > (*overflow) ) *overflow=0;
}
+
+/* This whole function is new */
+/* walk through the tree and for each colour, store its seen count in the
+ space pointed by *col_usage_it_adr */
+void
+octt_histo(struct octt *ct, unsigned int **col_usage_it_adr) {
+ int i,c;
+ c = 0;
+ for(i = 0; i < 8; i++)
+ if (ct->t[i] != NULL) {
+ octt_histo(ct->t[i], col_usage_it_adr);
+ c++;
+ }
+ if (!c) {
+ *(*col_usage_it_adr)++ = ct->cnt;
+ }
+}
+
+
+i_img_dim
+i_abs(i_img_dim x) {
+ return x < 0 ? -x : x;
+}