File Coverage

datatypes.c
Criterion Covered Total %
statement 103 140 73.5
branch 41 78 52.5
condition n/a
subroutine n/a
pod n/a
total 144 218 66.0


line stmt bran cond sub pod time code
1             #include
2             #include
3             #include
4             #define IMAGER_NO_CONTEXT
5             #include "imager.h"
6              
7             /*
8             2d bitmask with test and set operations
9             */
10              
11             struct i_bitmap*
12 90           btm_new(i_img_dim xsize,i_img_dim ysize) {
13             size_t bytes;
14             struct i_bitmap *btm;
15 90           btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap)); /* checked 4jul05 tonyc */
16 90           bytes = (xsize*ysize+8)/8;
17 90 50         if (bytes * 8 / ysize < xsize-1) { /* this is kind of rough */
18 0           fprintf(stderr, "Integer overflow allocating bitmap (" i_DFp ")",
19             i_DFcp(xsize, ysize));
20 0           exit(3);
21             }
22 90           btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
23 90           btm->xsize=xsize;
24 90           btm->ysize=ysize;
25 90           memset(btm->data, 0, bytes);
26 90           return btm;
27             }
28              
29              
30             void
31 90           btm_destroy(struct i_bitmap *btm) {
32 90           myfree(btm->data);
33 90           myfree(btm);
34 90           }
35              
36              
37             int
38 87327           btm_test(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
39             i_img_dim btno;
40 87327 50         if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) return 0;
    100          
    50          
    50          
41 86064           btno=btm->xsize*y+x;
42 86064           return (1<<(btno%8))&(btm->data[btno/8]);
43             }
44              
45             void
46 20291           btm_set(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
47             i_img_dim btno;
48 20291 50         if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) abort();
    50          
    50          
    50          
49 20291           btno=btm->xsize*y+x;
50 20291           btm->data[btno/8]|=1<<(btno%8);
51 20291           }
52              
53              
54              
55              
56              
57             /*
58             Bucketed linked list - stack type
59             */
60              
61             static struct llink *
62             llink_new(struct llink* p,size_t size);
63             static int
64             llist_llink_push(struct llist *lst, struct llink *lnk,const void *data);
65             static void
66             llink_destroy(struct llink* l);
67              
68             /*
69             =item llist_new()
70             =synopsis struct llist *l = llist_new(100, sizeof(foo);
71              
72             Create a new stack structure. Implemented as a linked list of pools.
73              
74             Parameters:
75              
76             =over
77              
78             =item *
79              
80             multip - number of entries in each pool
81              
82             =item *
83              
84             ssize - size of the objects being pushed/popped
85              
86             =back
87              
88             =cut
89             */
90              
91             struct llist *
92 90           llist_new(int multip, size_t ssize) {
93             struct llist *l;
94 90           l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */
95 90           l->h = NULL;
96 90           l->t = NULL;
97 90           l->multip = multip;
98 90           l->ssize = ssize;
99 90           l->count = 0;
100 90           return l;
101             }
102              
103             /*
104             =item llist_push()
105             =synopsis llist_push(l, &foo);
106              
107             Push an item on the stack.
108              
109             =cut
110             */
111              
112             void
113 3020           llist_push(struct llist *l,const void *data) {
114 3020           size_t ssize = l->ssize;
115 3020           int multip = l->multip;
116            
117             /* fprintf(stderr,"llist_push: data=0x%08X\n",data);
118             fprintf(stderr,"Chain size: %d\n", l->count); */
119            
120 3020 100         if (l->t == NULL) {
121 674           l->t = l->h = llink_new(NULL,ssize*multip); /* Tail is empty - list is empty */
122             /* fprintf(stderr,"Chain empty - extended\n"); */
123             }
124             else { /* Check for overflow in current tail */
125 2346 50         if (l->t->fill >= l->multip) {
126 0           struct llink* nt = llink_new(l->t, ssize*multip);
127 0           l->t->n=nt;
128 0           l->t=nt;
129             /* fprintf(stderr,"Chain extended\n"); */
130             }
131             }
132             /* fprintf(stderr,"0x%08X\n",l->t); */
133 3020 50         if (llist_llink_push(l,l->t,data)) {
134 0           dIMCTX;
135 0           im_fatal(aIMCTX, 3, "out of memory\n");
136             }
137 3020           }
138              
139             /*
140             =item llist_pop()
141              
142             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().
143              
144             returns 0 if the list is empty
145              
146             =cut
147             */
148              
149             int
150 3020           llist_pop(struct llist *l,void *data) {
151             /* int ssize=l->ssize;
152             int multip=l->multip;*/
153 3020 50         if (l->t == NULL) return 0;
154 3020           l->t->fill--;
155 3020           l->count--;
156 3020           memcpy(data,(char*)(l->t->data)+l->ssize*l->t->fill,l->ssize);
157            
158 3020 100         if (!l->t->fill) { /* This link empty */
159 674 50         if (l->t->p == NULL) { /* and it's the only link */
160 674           llink_destroy(l->t);
161 674           l->h = l->t = NULL;
162             }
163             else {
164 0           l->t=l->t->p;
165 0           llink_destroy(l->t->n);
166             }
167             }
168 3020           return 1;
169             }
170              
171             void
172 0           llist_dump(struct llist *l) {
173             int j;
174 0           int i=0;
175             struct llink *lnk;
176 0           lnk=l->h;
177 0 0         while(lnk != NULL) {
178 0 0         for(j=0;jfill;j++) {
179             /* memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
180             /*memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
181 0           printf("%d - %p\n",i,*(void **)((char *)(lnk->data)+l->ssize*j));
182 0           i++;
183             }
184 0           lnk=lnk->n;
185             }
186 0           }
187              
188             /*
189             =item llist_destroy()
190              
191             Destroy a linked-list based stack.
192              
193             =cut
194             */
195              
196             void
197 90           llist_destroy(struct llist *l) {
198 90           struct llink *t,*lnk = l->h;
199 90 50         while( lnk != NULL ) {
200 0           t=lnk;
201 0           lnk=lnk->n;
202 0           myfree(t);
203             }
204 90           myfree(l);
205 90           }
206              
207             /* Links */
208              
209             static struct llink *
210 674           llink_new(struct llink* p,size_t size) {
211             struct llink *l;
212 674           l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
213 674           l->n = NULL;
214 674           l->p = p;
215 674           l->fill = 0;
216 674           l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
217 674           return l;
218             }
219              
220             /* free's the data pointer, itself, and sets the previous' next pointer to null */
221              
222             static void
223 674           llink_destroy(struct llink* l) {
224 674 50         if (l->p != NULL) { l->p->n=NULL; }
225 674           myfree(l->data);
226 674           myfree(l);
227 674           }
228              
229              
230             /* if it returns true there wasn't room for the
231             item on the link */
232              
233             static int
234 3020           llist_llink_push(struct llist *lst, struct llink *lnk, const void *data) {
235             /* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
236             fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
237 3020 50         if (lnk->fill == lst->multip) return 1;
238             /* memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize); */
239 3020           memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize);
240            
241             /* printf("data=%X res=%X\n",*(int*)data,*(int*)(lnk->data));*/
242 3020           lnk->fill++;
243 3020           lst->count++;
244 3020           return 0;
245             }
246              
247             /*
248             Oct-tree implementation
249             */
250              
251             struct octt *
252 1538           octt_new() {
253             int i;
254             struct octt *t;
255            
256 1538           t=(struct octt*)mymalloc(sizeof(struct octt)); /* checked 4jul05 tonyc */
257 13842 100         for(i=0;i<8;i++) t->t[i]=NULL;
258 1538           t->cnt=0;
259 1538           return t;
260             }
261              
262              
263             /* returns 1 if the colors wasn't in the octtree already */
264              
265              
266             int
267 56486           octt_add(struct octt *ct,unsigned char r,unsigned char g,unsigned char b) {
268             struct octt *c;
269             int i,cm;
270             int ci;
271             int rc;
272 56486           rc=0;
273 56486           c=ct;
274             /* printf("[r,g,b]=[%d,%d,%d]\n",r,g,b); */
275 508374 100         for(i=7;i>-1;i--) {
276 451888           cm=1<
277 451888 100         ci=((!!(r&cm))<<2)+((!!(g&cm))<<1)+!!(b&cm);
    100          
278             /* printf("idx[%d]=%d\n",i,ci); */
279 451888 100         if (c->t[ci] == NULL) {
280 1524           c->t[ci]=octt_new();
281 1524           rc=1;
282             }
283 451888           c=c->t[ci];
284             }
285 56486           c->cnt++; /* New. The only thing really needed (I think) */
286 56486           return rc;
287             }
288              
289              
290             void
291 1538           octt_delete(struct octt *ct) {
292             int i;
293 13842 100         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 */
    100          
294 1538           myfree(ct);
295 1538           }
296              
297              
298             void
299 0           octt_dump(struct octt *ct) {
300             int i;
301             /* printf("node [0x%08X] -> (%d)\n",ct,ct->cnt); */
302 0 0         for(i=0;i<8;i++)
303 0 0         if (ct->t[i] != NULL)
304 0           printf("[ %d ] -> %p\n", i, (void *)ct->t[i]);
305 0 0         for(i=0;i<8;i++)
306 0 0         if (ct->t[i] != NULL)
307 0           octt_dump(ct->t[i]);
308 0           }
309              
310             /* note that all calls of octt_count are operating on the same overflow
311             variable so all calls will know at the same time if an overflow
312             has occured and stops there. */
313              
314             void
315 0           octt_count(struct octt *ct,int *tot,int max,int *overflow) {
316             int i,c;
317 0           c=0;
318 0 0         if (!(*overflow)) return;
319 0 0         for(i=0;i<8;i++) if (ct->t[i]!=NULL) {
    0          
320 0           octt_count(ct->t[i],tot,max,overflow);
321 0           c++;
322             }
323 0 0         if (!c) (*tot)++;
324 0 0         if ( (*tot) > (*overflow) ) *overflow=0;
325             }
326              
327             /* This whole function is new */
328             /* walk through the tree and for each colour, store its seen count in the
329             space pointed by *col_usage_it_adr */
330             void
331 71           octt_histo(struct octt *ct, unsigned int **col_usage_it_adr) {
332             int i,c;
333 71           c = 0;
334 639 100         for(i = 0; i < 8; i++)
335 568 100         if (ct->t[i] != NULL) {
336 67           octt_histo(ct->t[i], col_usage_it_adr);
337 67           c++;
338             }
339 71 100         if (!c) {
340 9           *(*col_usage_it_adr)++ = ct->cnt;
341             }
342 71           }
343              
344              
345             i_img_dim
346 45473           i_abs(i_img_dim x) {
347 45473           return x < 0 ? -x : x;
348             }