X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/02d1d62827cef86398edc2013f7d2ff04bf21c63..e1c0692925:/io.c diff --git a/io.c b/io.c index 64fc84e5..222553ab 100644 --- a/io.c +++ b/io.c @@ -1,4 +1,5 @@ -#include "io.h" +#include "imager.h" +#include "imageri.h" #include #ifndef _MSC_VER #include @@ -10,11 +11,11 @@ #ifdef IMAGER_DEBUG_MALLOC -#define MAXMAL 1024 +#define MAXMAL 102400 #define MAXDESC 65 -#define UNDRRNVAL 100 -#define OVERRNVAL 100 +#define UNDRRNVAL 10 +#define OVERRNVAL 10 #define PADBYTE 0xaa @@ -22,112 +23,164 @@ static int malloc_need_init = 1; typedef struct { - void* point; + void* ptr; size_t size; - char comm[MAXDESC]; + const char *file; + int line; } malloc_entry; malloc_entry malloc_pointers[MAXMAL]; -/* -#define mymalloc(x) (mymalloc_file_line(x,__FILE__,__LINE__)) -*/ + +/* Utility functions */ + + +static void -malloc_state() { - int i, total; - total=0; - mm_log((0,"malloc_state()\n")); - bndcheck_all(); - for(i=0;i %d bytes allocated at %p for %s (%d)\n", i, size, buf, file, line)); - return buf; +void +malloc_state(void) { + int i; + size_t total = 0; + + i_clear_error(); + mm_log((0,"malloc_state()\n")); + bndcheck_all(); + for(i=0; i %ld bytes allocated at %p for %s (%d)\n", i, (long)size, buf, file, line)); + return buf; +} -/* This function not maintained for now */ +void * +(mymalloc)(size_t size) { + return mymalloc_file_line(size, "unknown", 0); +} -/* void* -mymalloc_comm(int size,char *comm) { - void *buf; +myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) { + char *buf; int i; - if (malloc_need_init) { - for(i=0;i %ld bytes allocated at %p for %s (%d)\n", i, (long)newsize, buf, file, line)); + return buf; +} + +void * +(myrealloc)(void *ptr, size_t newsize) { + return myrealloc_file_line(ptr, newsize, "unknown", 0); } -*/ static void bndcheck(int idx) { int i; size_t s = malloc_pointers[idx].size; - unsigned char *pp = malloc_pointers[idx].point; + unsigned char *pp = malloc_pointers[idx].ptr; if (!pp) { mm_log((1, "bndcheck: No pointer in slot %d\n", idx)); return; } - for(i=0;i %p\n", (long)size, buf)); return buf; } +void * +mymalloc_file_line(size_t size, char *file, int line) { + return mymalloc(size); +} + void myfree(void *p) { + mm_log((1, "myfree(p %p)\n", p)); free(p); } +void +myfree_file_line(void *p, char *file, int line) { + myfree(p); +} + +void * +myrealloc(void *block, size_t size) { + void *result; + + mm_log((1, "myrealloc(block %p, size %ld)\n", block, (long)size)); + if ((result = realloc(block, size)) == NULL) { + mm_log((1, "myrealloc: out of memory\n")); + fprintf(stderr, "Out of memory.\n"); + exit(3); + } + return result; +} + +void * +myrealloc_file_line(void *block, size_t newsize, char *file, int size) { + return myrealloc(block, newsize); +} + #endif /* IMAGER_MALLOC_DEBUG */ +/* memory pool implementation */ +void +i_mempool_init(i_mempool *mp) { + mp->alloc = 10; + mp->used = 0; + mp->p = mymalloc(sizeof(void*)*mp->alloc); +} +void +i_mempool_extend(i_mempool *mp) { + mp->p = myrealloc(mp->p, mp->alloc * 2); + mp->alloc *=2; +} +void * +i_mempool_alloc(i_mempool *mp, size_t size) { + if (mp->used == mp->alloc) i_mempool_extend(mp); + mp->p[mp->used] = mymalloc(size); + mp->used++; + return mp->p[mp->used-1]; +} + + +void +i_mempool_destroy(i_mempool *mp) { + unsigned int i; + for(i=0; iused; i++) myfree(mp->p[i]); + myfree(mp->p); +} + + + +/* Should these really be here? */ #undef min #undef max -int -min(int a,int b) { +i_img_dim +i_minx(i_img_dim a, i_img_dim b) { if (ab) return a; else return b; } -int -myread(int fd,void *buf,int len) { - unsigned char* bufc; - int bc,rc; - bufc = (unsigned char*)buf; - bc=0; - while( ((rc=read(fd,bufc+bc,len-bc))>0 ) && (bc!=len) ) bc+=rc; - if ( rc < 0 ) return rc; - else return bc; -} -int -mywrite(int fd,void *buf,int len) { - unsigned char* bufc; - int bc,rc; - bufc=(unsigned char*)buf; - bc=0; - while(((rc=write(fd,bufc+bc,len-bc))>0) && (bc!=len)) bc+=rc; - if (rc<0) return rc; - else return bc; -} +struct utf8_size { + int mask, expect; + int size; +}; -void -interleave(unsigned char *inbuffer,unsigned char *outbuffer,int rowsize,int channels) { - int ch,ind,i; - i=0; - if ( inbuffer==outbuffer ) return; /* Check if data is already in interleaved format */ - for( ind=0; ind character from the stream. +Modifies *p and *len to indicate the consumed characters. + +This doesn't support the extended C encoding used by later +versions of Perl. Since this is typically used to implement text +output by font drivers, the strings supplied shouldn't have such out +of range characters. + +This doesn't check that the C character is using the shortest +possible representation. + +Returns ~0UL on failure. + +=cut +*/ + +unsigned long +i_utf8_advance(char const **p, size_t *len) { + unsigned char c; + int i, ci, clen = 0; + unsigned char codes[3]; + if (*len == 0) + return ~0UL; + c = *(*p)++; --*len; + + for (i = 0; i < sizeof(utf8_sizes)/sizeof(*utf8_sizes); ++i) { + if ((c & utf8_sizes[i].mask) == utf8_sizes[i].expect) { + clen = utf8_sizes[i].size; + break; + } + } + if (clen == 0 || *len < clen-1) { + --*p; ++*len; + return ~0UL; + } + + /* check that each character is well formed */ + i = 1; + ci = 0; + while (i < clen) { + if (((*p)[ci] & 0xC0) != 0x80) { + --*p; ++*len; + return ~0UL; + } + codes[ci] = (*p)[ci]; + ++ci; ++i; + } + *p += clen-1; *len -= clen-1; + if (c & 0x80) { + if ((c & 0xE0) == 0xC0) { + return ((c & 0x1F) << 6) + (codes[0] & 0x3F); + } + else if ((c & 0xF0) == 0xE0) { + return ((c & 0x0F) << 12) | ((codes[0] & 0x3F) << 6) | (codes[1] & 0x3f); + } + else if ((c & 0xF8) == 0xF0) { + return ((c & 0x07) << 18) | ((codes[0] & 0x3F) << 12) + | ((codes[1] & 0x3F) << 6) | (codes[2] & 0x3F); + } + else { + *p -= clen; *len += clen; + return ~0UL; + } + } + else { + return c; + } +}