X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/358918925b41a7084b2f21922fe9aaab5da5b49e..487ec752f3005da0acf1dd99d07b591d0a1a1460:/datatypes.c diff --git a/datatypes.c b/datatypes.c index 2afdc9a5..c6604100 100644 --- a/datatypes.c +++ b/datatypes.c @@ -1,23 +1,28 @@ -#include "imio.h" -#include "datatypes.h" #include #include #include - +#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; } @@ -30,16 +35,16 @@ btm_destroy(struct i_bitmap *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); @@ -53,51 +58,40 @@ btm_set(struct i_bitmap *btm,int x,int y) { Bucketed linked list - stack type */ -struct llink * -llink_new(struct llink* p,int size) { - struct llink *l; - l = mymalloc(sizeof(struct llink)); - l->n = NULL; - l->p = p; - l->fill = 0; - l->data = 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 = mymalloc(sizeof(struct llist)); + l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */ l->h = NULL; l->t = NULL; l->multip = multip; @@ -106,9 +100,18 @@ llist_new(int multip, int ssize) { 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; +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); @@ -127,12 +130,21 @@ llist_push(struct llist *l,void *data) { } } /* fprintf(stderr,"0x%08X\n",l->t); */ - if (llist_llink_push(l,l->t,data)) { - m_fatal(3, "out of memory\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 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) { @@ -158,21 +170,29 @@ llist_pop(struct llist *l,void *data) { 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;jfill;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; @@ -184,11 +204,49 @@ llist_destroy(struct llist *l) { 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 */ @@ -198,7 +256,7 @@ octt_new() { 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; @@ -212,21 +270,22 @@ int 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<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; } @@ -243,8 +302,12 @@ void 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 @@ -263,3 +326,26 @@ octt_count(struct octt *ct,int *tot,int max,int *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; +}