X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/cd4b0b20d84aad69c036b6c3bf8dadbb4d93a5b9..86c50c46b13eb07f84a907b798e62b0f2fc94600:/io.c diff --git a/io.c b/io.c index 6661a3ab..df00421c 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 @@ -72,9 +73,6 @@ set_entry(int i, char *buf, size_t size, char *file, int line) { return buf; } - - - void malloc_state(void) { int i, total = 0; @@ -115,11 +113,10 @@ mymalloc_file_line(size_t size, char* file, int line) { return buf; } - - - - - +void * +(mymalloc)(int size) { + return mymalloc_file_line(size, "unknown", 0); +} void* myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) { @@ -155,8 +152,10 @@ myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) { return buf; } - - +void * +(myrealloc)(void *ptr, size_t newsize) { + return myrealloc_file_line(ptr, newsize, "unknown", 0); +} static void @@ -187,15 +186,14 @@ bndcheck_all() { bndcheck(idx); } - - - - void myfree_file_line(void *p, char *file, int line) { char *pp = p; int match = 0; int i; + + if (p == NULL) + return; for(i=0; ialloc = 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? */ @@ -267,13 +321,96 @@ myrealloc(void *block, size_t size) { #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. + +This doesn't check that the C character is using the shortest +possible representation. + +=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; + } +} +