Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 352 lines (285 sloc) 7.558 kB
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
1 #include <stdlib.h>
2 #include <stdio.h>
3589189 - fix a few compiler warnings
Tony Cook authored
3 #include <string.h>
7db37a7 @tonycoz update datatypes.c with IMAGER_NO_CONTEXT
authored
4 #define IMAGER_NO_CONTEXT
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
5 #include "imager.h"
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
6
7 /*
8 2d bitmask with test and set operations
9 */
10
11 struct i_bitmap*
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
12 btm_new(i_img_dim xsize,i_img_dim ysize) {
13 size_t bytes;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
14 struct i_bitmap *btm;
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
15 btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap)); /* checked 4jul05 tonyc */
16 bytes = (xsize*ysize+8)/8;
17 if (bytes * 8 / ysize < xsize-1) { /* this is kind of rough */
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
18 fprintf(stderr, "Integer overflow allocating bitmap (" i_DFp ")",
19 i_DFcp(xsize, ysize));
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
20 exit(3);
21 }
22 btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
23 btm->xsize=xsize;
24 btm->ysize=ysize;
b934971 @tonycoz [rt #68994] initialize the btm data structure more efficiently
authored
25 memset(btm->data, 0, bytes);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
26 return btm;
27 }
28
29
30 void
31 btm_destroy(struct i_bitmap *btm) {
32 myfree(btm->data);
33 myfree(btm);
34 }
35
36
37 int
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
38 btm_test(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
39 i_img_dim btno;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
40 if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) return 0;
41 btno=btm->xsize*y+x;
42 return (1<<(btno%8))&(btm->data[btno/8]);
43 }
44
45 void
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
46 btm_set(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
47 i_img_dim btno;
e25e59b Second attempt at flood fix.
Arnar Mar Hrafnkelsson authored
48 if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) abort();
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
49 btno=btm->xsize*y+x;
50 btm->data[btno/8]|=1<<(btno%8);
51 }
52
53
54
55
56
57 /*
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
58 Bucketed linked list - stack type
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
59 */
60
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
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);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
67
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
68 /*
69 =item llist_new()
70 =synopsis struct llist *l = llist_new(100, sizeof(foo);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
71
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
72 Create a new stack structure. Implemented as a linked list of pools.
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
73
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
74 Parameters:
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
75
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
76 =over
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
77
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
78 =item *
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
79
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
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 */
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
90
91 struct llist *
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
92 llist_new(int multip, size_t ssize) {
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
93 struct llist *l;
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
94 l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
95 l->h = NULL;
96 l->t = NULL;
97 l->multip = multip;
98 l->ssize = ssize;
99 l->count = 0;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
100 return l;
101 }
102
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
103 /*
104 =item llist_push()
105 =synopsis llist_push(l, &foo);
106
107 Push an item on the stack.
108
109 =cut
110 */
111
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
112 void
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
113 llist_push(struct llist *l,const void *data) {
114 size_t ssize = l->ssize;
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
115 int multip = l->multip;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
116
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
117 /* fprintf(stderr,"llist_push: data=0x%08X\n",data);
118 fprintf(stderr,"Chain size: %d\n", l->count); */
119
120 if (l->t == NULL) {
121 l->t = l->h = llink_new(NULL,ssize*multip); /* Tail is empty - list is empty */
122 /* fprintf(stderr,"Chain empty - extended\n"); */
123 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
124 else { /* Check for overflow in current tail */
125 if (l->t->fill >= l->multip) {
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
126 struct llink* nt = llink_new(l->t, ssize*multip);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
127 l->t->n=nt;
128 l->t=nt;
129 /* fprintf(stderr,"Chain extended\n"); */
130 }
131 }
132 /* fprintf(stderr,"0x%08X\n",l->t); */
6fe3a07 @tonycoz avoid i_push_errorf() and i_fatal() in a few more places
authored
133 if (llist_llink_push(l,l->t,data)) {
134 dIMCTX;
135 im_fatal(aIMCTX, 3, "out of memory\n");
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
136 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
137 }
138
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
139 /*
140 =item llist_pop()
141
142 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().
143
144 returns 0 if the list is empty
145
146 =cut
147 */
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
148
149 int
150 llist_pop(struct llist *l,void *data) {
151 /* int ssize=l->ssize;
152 int multip=l->multip;*/
153 if (l->t == NULL) return 0;
154 l->t->fill--;
155 l->count--;
156 memcpy(data,(char*)(l->t->data)+l->ssize*l->t->fill,l->ssize);
157
158 if (!l->t->fill) { /* This link empty */
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
159 if (l->t->p == NULL) { /* and it's the only link */
160 llink_destroy(l->t);
161 l->h = l->t = NULL;
162 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
163 else {
164 l->t=l->t->p;
165 llink_destroy(l->t->n);
166 }
167 }
168 return 1;
169 }
170
171 void
172 llist_dump(struct llist *l) {
bc8930e avoid a dangerous cast (in an unused function)
Tony Cook authored
173 int j;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
174 int i=0;
175 struct llink *lnk;
176 lnk=l->h;
177 while(lnk != NULL) {
178 for(j=0;j<lnk->fill;j++) {
179 /* memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
bc8930e avoid a dangerous cast (in an unused function)
Tony Cook authored
180 /*memcpy(&k,(char*)(lnk->data)+l->ssize*j,sizeof(void*));*/
5e2762a can't add to a void *
Tony Cook authored
181 printf("%d - %p\n",i,*(void **)((char *)(lnk->data)+l->ssize*j));
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
182 i++;
183 }
184 lnk=lnk->n;
185 }
186 }
187
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
188 /*
189 =item llist_destroy()
190
191 Destroy a linked-list based stack.
192
193 =cut
194 */
195
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
196 void
197 llist_destroy(struct llist *l) {
198 struct llink *t,*lnk = l->h;
199 while( lnk != NULL ) {
200 t=lnk;
201 lnk=lnk->n;
202 myfree(t);
203 }
204 myfree(l);
205 }
206
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
207 /* Links */
208
209 static struct llink *
210 llink_new(struct llink* p,size_t size) {
211 struct llink *l;
212 l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
213 l->n = NULL;
214 l->p = p;
215 l->fill = 0;
216 l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
217 return l;
218 }
219
220 /* free's the data pointer, itself, and sets the previous' next pointer to null */
221
222 static void
223 llink_destroy(struct llink* l) {
224 if (l->p != NULL) { l->p->n=NULL; }
225 myfree(l->data);
226 myfree(l);
227 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
228
229
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
230 /* if it returns true there wasn't room for the
231 item on the link */
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
232
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
233 static int
234 llist_llink_push(struct llist *lst, struct llink *lnk, const void *data) {
235 int multip;
236 multip = lst->multip;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
237
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
238 /* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
239 fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
240 if (lnk->fill == lst->multip) return 1;
241 /* memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize); */
242 memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize);
243
244 /* printf("data=%X res=%X\n",*(int*)data,*(int*)(lnk->data));*/
245 lnk->fill++;
246 lst->count++;
247 return 0;
248 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
249
250 /*
251 Oct-tree implementation
252 */
253
254 struct octt *
255 octt_new() {
256 int i;
257 struct octt *t;
258
f0960b1 - added integer overflow checks to many memory allocation calls
Tony Cook authored
259 t=(struct octt*)mymalloc(sizeof(struct octt)); /* checked 4jul05 tonyc */
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
260 for(i=0;i<8;i++) t->t[i]=NULL;
261 t->cnt=0;
262 return t;
263 }
264
265
266 /* returns 1 if the colors wasn't in the octtree already */
267
268
269 int
270 octt_add(struct octt *ct,unsigned char r,unsigned char g,unsigned char b) {
271 struct octt *c;
272 int i,cm;
fe622da Gabriel Vasseur's patch, corrected just enough for it to compile.
Tony Cook authored
273 int ci;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
274 int rc;
275 rc=0;
276 c=ct;
277 /* printf("[r,g,b]=[%d,%d,%d]\n",r,g,b); */
278 for(i=7;i>-1;i--) {
279 cm=1<<i;
280 ci=((!!(r&cm))<<2)+((!!(g&cm))<<1)+!!(b&cm);
281 /* printf("idx[%d]=%d\n",i,ci); */
fe622da Gabriel Vasseur's patch, corrected just enough for it to compile.
Tony Cook authored
282 if (c->t[ci] == NULL) {
283 c->t[ci]=octt_new();
284 rc=1;
285 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
286 c=c->t[ci];
287 }
fe622da Gabriel Vasseur's patch, corrected just enough for it to compile.
Tony Cook authored
288 c->cnt++; /* New. The only thing really needed (I think) */
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
289 return rc;
290 }
291
292
293 void
294 octt_delete(struct octt *ct) {
295 int i;
296 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 */
297 myfree(ct);
298 }
299
300
301 void
302 octt_dump(struct octt *ct) {
303 int i;
304 /* printf("node [0x%08X] -> (%d)\n",ct,ct->cnt); */
8a2cd31 - prevent a cast to integer warning on x64 builds in datatypes.c
Tony Cook authored
305 for(i=0;i<8;i++)
306 if (ct->t[i] != NULL)
307 printf("[ %d ] -> %p\n", i, (void *)ct->t[i]);
308 for(i=0;i<8;i++)
309 if (ct->t[i] != NULL)
310 octt_dump(ct->t[i]);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
311 }
312
313 /* note that all calls of octt_count are operating on the same overflow
314 variable so all calls will know at the same time if an overflow
315 has occured and stops there. */
316
317 void
318 octt_count(struct octt *ct,int *tot,int max,int *overflow) {
319 int i,c;
320 c=0;
321 if (!(*overflow)) return;
322 for(i=0;i<8;i++) if (ct->t[i]!=NULL) {
323 octt_count(ct->t[i],tot,max,overflow);
324 c++;
325 }
326 if (!c) (*tot)++;
327 if ( (*tot) > (*overflow) ) *overflow=0;
328 }
fe622da Gabriel Vasseur's patch, corrected just enough for it to compile.
Tony Cook authored
329
330 /* This whole function is new */
331 /* walk through the tree and for each colour, store its seen count in the
332 space pointed by *col_usage_it_adr */
333 void
334 octt_histo(struct octt *ct, unsigned int **col_usage_it_adr) {
335 int i,c;
336 c = 0;
337 for(i = 0; i < 8; i++)
338 if (ct->t[i] != NULL) {
339 octt_histo(ct->t[i], col_usage_it_adr);
340 c++;
341 }
342 if (!c) {
343 *(*col_usage_it_adr)++ = ct->cnt;
344 }
345 }
346
347
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
348 i_img_dim
349 i_abs(i_img_dim x) {
350 return x < 0 ? -x : x;
351 }
Something went wrong with that request. Please try again.