X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/97c4effc5cb6c972260ba40636d3885fe1fcbbd6..e1c0692925:/io.c diff --git a/io.c b/io.c index 73fbd3be..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 @@ -24,7 +25,8 @@ static int malloc_need_init = 1; typedef struct { void* ptr; size_t size; - char comm[MAXDESC]; + const char *file; + int line; } malloc_entry; malloc_entry malloc_pointers[MAXMAL]; @@ -68,26 +70,25 @@ set_entry(int i, char *buf, size_t size, char *file, int line) { buf += UNDRRNVAL; malloc_pointers[i].ptr = buf; malloc_pointers[i].size = size; - sprintf(malloc_pointers[i].comm,"%s (%d)", file, line); + malloc_pointers[i].file = file; + malloc_pointers[i].line = line; return buf; } - - - void malloc_state(void) { - int i, total = 0; + int i; + size_t total = 0; i_clear_error(); 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)); + mm_log((1,"mymalloc_file_line: slot <%d> %ld bytes allocated at %p for %s (%d)\n", i, (long)size, buf, file, line)); return buf; } - - - - - +void * +(mymalloc)(size_t size) { + return mymalloc_file_line(size, "unknown", 0); +} void* myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) { @@ -146,17 +146,20 @@ myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) { } if ( (buf = realloc(((char *)ptr)-UNDRRNVAL, UNDRRNVAL+OVERRNVAL+newsize)) == NULL ) { - mm_log((1,"Unable to reallocate %i bytes at %p for %s (%i)\n", newsize, ptr, file, line)); + mm_log((1,"Unable to reallocate %ld bytes at %p for %s (%i)\n", (long) + newsize, ptr, file, line)); exit(3); } buf = set_entry(i, buf, newsize, file, line); - mm_log((1,"realloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, newsize, buf, file, line)); + mm_log((1,"realloc_file_line: slot <%d> %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 @@ -169,13 +172,15 @@ bndcheck(int idx) { return; } - for(i=0;i %p\n", size, buf)); + mm_log((1, "mymalloc(size %ld) -> %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 %u)\n", block, size)); + 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"); @@ -256,6 +272,11 @@ myrealloc(void *block, size_t size) { return result; } +void * +myrealloc_file_line(void *block, size_t newsize, char *file, int size) { + return myrealloc(block, newsize); +} + #endif /* IMAGER_MALLOC_DEBUG */ @@ -299,13 +320,100 @@ i_mempool_destroy(i_mempool *mp) { #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; } + +struct utf8_size { + int mask, expect; + int size; +}; + +struct utf8_size utf8_sizes[] = +{ + { 0x80, 0x00, 1 }, + { 0xE0, 0xC0, 2 }, + { 0xF0, 0xE0, 3 }, + { 0xF8, 0xF0, 4 }, +}; + +/* +=item i_utf8_advance(char **p, size_t *len) + +Retrieve a C 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; + } +} +