]> git.imager.perl.org - imager.git/blob - io.c
Addi's notes on scan converting polygons with anti-aliasing
[imager.git] / io.c
1 #include "io.h"
2 #include <stdlib.h>
3 #ifndef _MSC_VER
4 #include <unistd.h>
5 #endif
6
7
8 /* FIXME: make allocation dynamic */
9
10
11 #ifdef IMAGER_DEBUG_MALLOC
12
13 #define MAXMAL 1024
14 #define MAXDESC 65
15
16 #define UNDRRNVAL 100
17 #define OVERRNVAL 100
18
19 #define PADBYTE 0xaa
20
21
22 static int malloc_need_init = 1;
23
24 typedef struct {
25   void* point;
26   size_t size;
27   char  comm[MAXDESC];
28 } malloc_entry;
29
30 malloc_entry malloc_pointers[MAXMAL];
31
32 /*
33 #define mymalloc(x) (mymalloc_file_line(x,__FILE__,__LINE__)) 
34 */
35
36
37 void
38 malloc_state() {
39   int i, total;
40   total=0;
41   mm_log((0,"malloc_state()\n"));
42   bndcheck_all();
43   for(i=0;i<MAXMAL;i++) if (malloc_pointers[i].point!=NULL) {
44     mm_log((0,"%d: %d (0x%x) : %s\n",i,malloc_pointers[i].size,malloc_pointers[i].point,malloc_pointers[i].comm));
45     total+=malloc_pointers[i].size;
46   }
47   if (total==0 ) mm_log((0,"No memory currently used!\n"))
48   else mm_log((0,"total: %d\n",total));
49 }
50
51
52 void*
53 mymalloc_file_line(int size, char* file, int line) {
54   char *buf;
55   int i;
56   if (malloc_need_init) {
57     for(i=0; i<MAXMAL; i++) malloc_pointers[i].point = NULL;
58     malloc_need_init=0;
59     atexit(malloc_state);
60   }
61
62   /* bndcheck_all(); ACTIVATE FOR LOTS OF THRASHING */
63
64   if ( (buf = malloc(size+UNDRRNVAL+OVERRNVAL)) == NULL ) { mm_log((1,"Unable to allocate %i for %s (%i)\n", size, file, line)); exit(3); }
65   memset( buf, PADBYTE, UNDRRNVAL );
66   memset( &buf[UNDRRNVAL+size], PADBYTE, OVERRNVAL );
67
68   mm_log((1,"mymalloc_file_line: real address %p\n", buf));
69   buf += UNDRRNVAL; /* Do this now so we will see the returned address in the logs. */
70   
71   for(i=0;i<MAXMAL;i++) if (malloc_pointers[i].point == NULL) {
72     malloc_pointers[i].size = size;
73     sprintf(malloc_pointers[i].comm,"%s (%d)", file, line);
74     malloc_pointers[i].point = buf;
75     mm_log((1,"mymalloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, size, buf, file, line));
76     return buf; 
77   }
78   
79   mm_log((0,"more than %d segments allocated at %s (%d)\n", MAXMAL, file, line));
80   exit(255);
81   return NULL;
82 }
83
84
85
86
87 /* This function not maintained for now */
88
89 /*
90 void*
91 mymalloc_comm(int size,char *comm) {
92   void *buf;
93   int i;
94   if (malloc_need_init) {
95     for(i=0;i<MAXMAL;i++) malloc_pointers[i].point=NULL;
96     malloc_need_init=0;
97   }
98   
99   if ((buf=malloc(size))==NULL) { mm_log((1,"Unable to malloc.\n")); exit(3); }
100
101   for(i=0;i<MAXMAL;i++) if (malloc_pointers[i].point==NULL) {
102     malloc_pointers[i].point=buf;
103     malloc_pointers[i].size=size;
104     strncpy(malloc_pointers[i].comm,comm,MAXDESC-1);
105     return buf;
106   }
107   mm_log((0,"more than %d segments malloced\n",MAXMAL));
108   exit(255);
109   return NULL;
110 }
111 */
112
113 static
114 void
115 bndcheck(int idx) {
116   int i;
117   size_t s = malloc_pointers[idx].size;
118   unsigned char *pp = malloc_pointers[idx].point;
119   if (!pp) {
120     mm_log((1, "bndcheck: No pointer in slot %d\n", idx));
121     return;
122   }
123   
124   for(i=0;i<UNDRRNVAL;i++)
125     if (pp[-(1+i)] != PADBYTE)
126       mm_log((1,"bndcheck: UNDERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
127   
128   for(i=0;i<OVERRNVAL;i++)
129     if (pp[s+i] != PADBYTE)
130       mm_log((1,"bndcheck: OVERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
131 }
132
133 void
134 bndcheck_all() {
135   int idx;
136   mm_log((1, "bndcheck_all()\n"));
137   for(idx=0; idx<MAXMAL; idx++)
138     if (malloc_pointers[idx].point)
139       bndcheck(idx);
140 }
141
142
143
144
145
146 void
147 myfree_file_line(void *p, char *file, int line) {
148   char  *pp = p;
149   int match = 0;
150   int i;
151   
152   for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].point == p) {
153     mm_log((1,"myfree_file_line: pointer %i (%s) freed at %s (%i)\n", i, malloc_pointers[i].comm, file, line));
154     bndcheck(i);
155     malloc_pointers[i].point = NULL;
156     match++;
157   }
158   
159   if (match != 1) {
160     mm_log((1, "myfree_file_line: inconsistent refcount %d\n", match));
161   }
162   
163   mm_log((1, "myfree_file_line: freeing address %p\n", pp-UNDRRNVAL));
164   
165   free(pp-UNDRRNVAL);
166 }
167
168 #else 
169
170 #define malloc_comm(a,b) (mymalloc(a))
171
172 void
173 malloc_state() {
174   printf("malloc_state: not in debug mode\n");
175 }
176
177 void*
178 mymalloc(int size) {
179   void *buf;
180
181   mm_log((1, "mymalloc(size %d)\n", size));
182   if ( (buf=malloc(size)) == NULL ) {
183     mm_log((1, "mymalloc: unable to malloc\n", size));
184     fprintf(stderr,"Unable to malloc.\n"); exit(3);
185   }
186   return buf;
187 }
188
189 void
190 myfree(void *p) {
191   free(p);
192 }
193
194 #endif /* IMAGER_MALLOC_DEBUG */
195
196
197
198
199
200
201
202
203 #undef min
204 #undef max
205
206 int
207 min(int a,int b) {
208   if (a<b) return a; else return b;
209 }
210
211 int
212 max(int a,int b) {
213   if (a>b) return a; else return b;
214 }
215
216 int
217 myread(int fd,void *buf,int len) {
218   unsigned char* bufc;
219   int bc,rc;
220   bufc = (unsigned char*)buf;
221   bc=0;
222   while( ((rc=read(fd,bufc+bc,len-bc))>0 ) && (bc!=len) ) bc+=rc;
223   if ( rc < 0 ) return rc;
224   else return bc;
225 }
226
227 int
228 mywrite(int fd,void *buf,int len) {
229   unsigned char* bufc;
230   int bc,rc;
231   bufc=(unsigned char*)buf;
232   bc=0;
233   while(((rc=write(fd,bufc+bc,len-bc))>0) && (bc!=len)) bc+=rc;
234   if (rc<0) return rc;
235   else return bc;
236 }
237
238 void
239 interleave(unsigned char *inbuffer,unsigned char *outbuffer,int rowsize,int channels) {
240   int ch,ind,i;
241   i=0;
242   if ( inbuffer==outbuffer ) return; /* Check if data is already in interleaved format */
243   for( ind=0; ind<rowsize; ind++) for (ch=0; ch<channels; ch++) outbuffer[i++] = inbuffer[rowsize*ch+ind]; 
244 }
245
246