Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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.