From 53e54a632a2203423b5f56717ea85cd4926d3f4a Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 15 Mar 2005 18:18:57 +0000 Subject: [PATCH] * src/bdf/bdflib.c: various improvements to the bdf loader, mainly used to reduce the amount of heap size required to only test wether we're dealing with a BDF font (the old code allocated 64 Kb right before any test). * src/lzw/ftlzw.c (FT_Stream_OpenLZW): modified the function to check the LZW header before doing anything else. This helps avoid un-necessary heap allocations (400 Kb of heap memory for the LZW decoder ! Oh my !) * src/gzip/ftgzip.c (FT_Stream_OpenGZip): ditto for the .gz decoder, though the code savings is smaller. --- ChangeLog | 9 + include/freetype/internal/ftstream.h | 10 +- src/base/ftstream.c | 29 ++ src/bdf/bdflib.c | 553 +++++++++++++-------------- src/gzip/ftgzip.c | 6 + src/lzw/ftlzw.c | 10 + 6 files changed, 331 insertions(+), 286 deletions(-) diff --git a/ChangeLog b/ChangeLog index de3a76596..0095ce491 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-03-15 David Turner + + * src/lzw/ftlzw.c (FT_Stream_OpenLZW): modified the function to check + the LZW header before doing anything else. This helps avoid un-necessary + heap allocations (400 Kb of heap memory for the LZW decoder ! Oh my !) + + * src/gzip/ftgzip.c (FT_Stream_OpenGZip): ditto for the .gz decoder, + though the code savings is smaller. + 2005-03-10 David Turner * src/tools/glnames.py: Add comment to explain the compression diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h index 9833cd092..b5c70667d 100644 --- a/include/freetype/internal/ftstream.h +++ b/include/freetype/internal/ftstream.h @@ -343,7 +343,7 @@ FT_BEGIN_HEADER /* free a stream */ FT_BASE( void ) - FT_Stream_Free( FT_Stream stream, + FT_Stream_Free( FT_Stream stream, FT_Int external ); /* initialize a stream for reading in-memory data */ @@ -385,6 +385,14 @@ FT_BEGIN_HEADER FT_Byte* buffer, FT_ULong count ); + /* try to read bytes at the end of a stream, return + * the number of bytes really available + */ + FT_BASE( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ /* error if the frame could not be read/accessed. The caller can use */ /* the FT_Stream_Get_XXX functions to retrieve frame data without */ diff --git a/src/base/ftstream.c b/src/base/ftstream.c index 4fb933ef4..2ff29cb15 100644 --- a/src/base/ftstream.c +++ b/src/base/ftstream.c @@ -153,6 +153,35 @@ } + FT_BASE_DEF( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong read_bytes = 0; + + + if ( stream->pos >= stream->size ) + goto Exit; + + if ( stream->read ) + read_bytes = stream->read( stream, stream->pos, buffer, count ); + else + { + read_bytes = stream->size - stream->pos; + if ( read_bytes > count ) + read_bytes = count; + + FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes ); + } + + stream->pos += read_bytes; + + Exit: + return read_bytes; + } + + FT_BASE_DEF( FT_Error ) FT_Stream_ExtractFrame( FT_Stream stream, FT_ULong count, diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c index 825385e1d..9ac50beab 100644 --- a/src/bdf/bdflib.c +++ b/src/bdf/bdflib.c @@ -224,7 +224,6 @@ if ( FT_NEW_ARRAY( ht->table, ht->size ) ) goto Exit; - FT_MEM_ZERO( ht->table, sizeof ( hashnode ) * ht->size ); for ( i = 0, bp = obp; i < sz; i++, bp++ ) { @@ -255,7 +254,6 @@ if ( FT_NEW_ARRAY( ht->table, sz ) ) goto Exit; - FT_MEM_ZERO( ht->table, sizeof ( hashnode ) * sz ); Exit: return error; @@ -351,6 +349,7 @@ char** field; unsigned long size; unsigned long used; + FT_Memory memory; } _bdf_list_t; @@ -389,20 +388,123 @@ #define sbitset( m, cc ) ( m[(cc) >> 3] & ( 1 << ( (cc) & 7 ) ) ) + static void + _bdf_list_init( _bdf_list_t* list, + FT_Memory memory ) + { + FT_ZERO(list); + list->memory = memory; + } + + static void + _bdf_list_done( _bdf_list_t* list ) + { + FT_Memory memory = list->memory; + + if ( memory ) + { + FT_FREE( list->field ); + FT_ZERO(list); + } + } + + + static FT_Error + _bdf_list_ensure( _bdf_list_t* list, + int num_items ) + { + FT_Error error = 0; + + if ( num_items > list->size ) + { + int oldsize = list->size; + int newsize = oldsize + (oldsize >> 1) + 4; + int bigsize = FT_INT_MAX / sizeof(char*); + FT_Memory memory = list->memory; + + if ( oldsize == bigsize ) + { + error = FT_Err_Out_Of_Memory; + goto Exit; + } + else if ( newsize < oldsize || newsize > bigsize ) + newsize = bigsize; + + if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) ) + goto Exit; + + list->size = newsize; + } + Exit: + return error; + } + + + static void + _bdf_list_shift( _bdf_list_t* list, + unsigned long n ) + { + unsigned long i, u; + + + if ( list == 0 || list->used == 0 || n == 0 ) + return; + + if ( n >= list->used ) + { + list->used = 0; + return; + } + + for ( u = n, i = 0; u < list->used; i++, u++ ) + list->field[i] = list->field[u]; + list->used -= n; + } + + + static char * + _bdf_list_join( _bdf_list_t* list, + int c, + unsigned long *alen ) + { + unsigned long i, j; + char *fp, *dp; + + + *alen = 0; + + if ( list == 0 || list->used == 0 ) + return 0; + + dp = list->field[0]; + for ( i = j = 0; i < list->used; i++ ) + { + fp = list->field[i]; + while ( *fp ) + dp[j++] = *fp++; + + if ( i + 1 < list->used ) + dp[j++] = (char)c; + } + dp[j] = 0; + + *alen = j; + return dp; + } + + + /* An empty string for empty fields. */ static const char empty[1] = { 0 }; /* XXX eliminate this */ - /* Assume the line is NULL-terminated and that the `list' parameter */ - /* was initialized the first time it was used. */ static FT_Error - _bdf_split( char* separators, - char* line, - unsigned long linelen, - _bdf_list_t* list, - FT_Memory memory ) + _bdf_list_split( _bdf_list_t* list, + char* separators, + char* line, + unsigned long linelen ) { int mult, final_empty; char *sp, *ep, *end; @@ -451,20 +553,9 @@ /* Resize the list if necessary. */ if ( list->used == list->size ) { - if ( list->size == 0 ) - { - if ( FT_NEW_ARRAY( list->field, 5 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY ( list->field , - list->size, - list->size + 5 ) ) - goto Exit; - } - - list->size += 5; + error = _bdf_list_ensure( list, list->used+1 ); + if ( error ) + goto Exit; } /* Assign the field appropriately. */ @@ -489,48 +580,16 @@ } /* Finally, NULL-terminate the list. */ - if ( list->used + final_empty + 1 >= list->size ) + if ( list->used + final_empty >= list->size ) { - if ( list->used == list->size ) - { - if ( list->size == 0 ) - { - if ( FT_NEW_ARRAY( list->field, 5 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY( list->field, - list->size, - list->size + 5 ) ) - goto Exit; - } - - list->size += 5; - } + error = _bdf_list_ensure( list, list->used+final_empty+1 ); + if ( error ) + goto Exit; } if ( final_empty ) list->field[list->used++] = (char*)empty; - if ( list->used == list->size ) - { - if ( list->size == 0 ) - { - if ( FT_NEW_ARRAY( list->field, 5 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY( list->field, - list->size, - list->size + 5 ) ) - goto Exit; - } - - list->size += 5; - } - list->field[list->used] = 0; Exit: @@ -538,100 +597,8 @@ } - static void - _bdf_shift( unsigned long n, - _bdf_list_t* list ) - { - unsigned long i, u; - - - if ( list == 0 || list->used == 0 || n == 0 ) - return; - - if ( n >= list->used ) - { - list->used = 0; - return; - } - - for ( u = n, i = 0; u < list->used; i++, u++ ) - list->field[i] = list->field[u]; - list->used -= n; - } - - - static char * - _bdf_join( int c, - unsigned long* len, - _bdf_list_t* list ) - { - unsigned long i, j; - char *fp, *dp; - - - if ( list == 0 || list->used == 0 ) - return 0; - - *len = 0; - - dp = list->field[0]; - for ( i = j = 0; i < list->used; i++ ) - { - fp = list->field[i]; - while ( *fp ) - dp[j++] = *fp++; - - if ( i + 1 < list->used ) - dp[j++] = (char)c; - } - dp[j] = 0; - - *len = j; - return dp; - } - - - /* High speed file reader that passes each line to a callback. */ - static FT_Error - bdf_internal_readstream( FT_Stream stream, - char* buffer, - int count, - int *read_bytes ) - { - int rbytes; - unsigned long pos = stream->pos; - FT_Error error = BDF_Err_Ok; - - - if ( pos > stream->size ) - { - FT_ERROR(( "bdf_internal_readstream:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - error = BDF_Err_Invalid_Stream_Operation; - goto Exit; - } - - if ( stream->read ) - rbytes = stream->read( stream, pos, - (unsigned char *)buffer, count ); - else - { - rbytes = stream->size - pos; - if ( rbytes > count ) - rbytes = count; - - FT_MEM_COPY( buffer, stream->base + pos, rbytes ); - } - - stream->pos = pos + rbytes; - - *read_bytes = rbytes; - - Exit: - return error; - } +#define NO_SKIP 256 /* this value cannot be stored in a 'char' */ static FT_Error _bdf_readstream( FT_Stream stream, @@ -640,10 +607,10 @@ unsigned long *lno ) { _bdf_line_func_t cb; - unsigned long lineno; - int n, done, refill, bytes, hold; - char *ls, *le, *pp, *pe, *hp; - char *buf = 0; + unsigned long lineno, buf_size; + int refill, bytes, hold, to_skip; + int start, end, cursor, avail; + char* buf = 0; FT_Memory memory = stream->memory; FT_Error error = BDF_Err_Ok; @@ -654,85 +621,115 @@ goto Exit; } - if ( FT_NEW_ARRAY( buf, 65536L ) ) - goto Exit; + /* initial size and allocation of the input buffer + */ + buf_size = 1024; - cb = callback; - lineno = 1; - buf[0] = 0; - - done = 0; - pp = ls = le = buf; + if ( FT_NEW_ARRAY( buf, buf_size ) ) + goto Exit; - bytes = 65536L; + cb = callback; + lineno = 1; + buf[0] = 0; + start = 0; + end = 0; + avail = 0; + cursor = 0; + refill = 1; + to_skip = NO_SKIP; - while ( !done ) + for (;;) { - error = bdf_internal_readstream( stream, pp, bytes, &n ); - if ( error ) - goto Exit; + if ( refill ) + { + bytes = (int) FT_Stream_TryRead( stream, buf + cursor, + (FT_ULong)(buf_size - cursor) ); + avail = cursor + bytes; + cursor = 0; + refill = 0; + } - if ( n == 0 ) - break; + end = start; - /* Determine the new end of the buffer pages. */ - pe = pp + n; + /* should we skip an optional character like \n or \r ? */ + if ( start < avail && buf[start] == to_skip ) + { + start += 1; + to_skip = NO_SKIP; + continue; + } - for ( refill = 0; done == 0 && refill == 0; ) + /* try to find the end of the line */ + while ( end < avail && buf[end] != '\n' && buf[end] != '\r' ) + end++; + + /* if we hit the end of the buffer, try shifting its content + * or even resizing it + */ + if ( end >= avail ) { - while ( le < pe && *le != '\n' && *le != '\r' ) - le++; + if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ + break; /* ignore it then exit */ - if ( le == pe ) + if ( start == 0 ) { - /* Hit the end of the last page in the buffer. Need to find */ - /* out how many pages to shift and how many pages need to be */ - /* read in. Adjust the line start and end pointers down to */ - /* point to the right places in the pages. */ - - pp = buf + ( ( ( ls - buf ) >> 13 ) << 13 ); - n = pp - buf; - ls -= n; - le -= n; - n = pe - pp; - - FT_MEM_MOVE( buf, pp, n ); - - pp = buf + n; - bytes = 65536L - n; - refill = 1; + /* this line is definitely too long, try resizing the input buffer + * a bit to handle it. + */ + FT_ULong new_size; + + if ( buf_size >= 65536UL ) /* limit ourselves to 64 Kb */ + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + new_size = buf_size*2; + if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) + goto Exit; + + cursor = buf_size; + buf_size = new_size; } else { - /* Temporarily NULL-terminate the line. */ - hp = le; - hold = *le; - *le = 0; - - /* XXX: Use encoding independent value for 0x1a */ - if ( *ls != '#' && *ls != 0x1a && - le > ls && - ( error = (*cb)( ls, le - ls, lineno, (void *)&cb, - client_data ) ) != BDF_Err_Ok ) - done = 1; - else - { - ls = ++le; - /* Handle the case of DOS crlf sequences. */ - if ( le < pe && hold == '\n' && *le =='\r' ) - ls = ++le; - } + bytes = avail - start; - /* Increment the line number. */ - lineno++; + FT_MEM_COPY( buf, buf+start, bytes ); - /* Restore the character at the end of the line. */ - *hp = (char)hold; + cursor = bytes; + avail -= bytes; + start = 0; } + refill = 1; + continue; + } + + /* Temporarily NUL-terminate the line. */ + hold = buf[end]; + buf[end] = 0; + + /* XXX: Use encoding independent value for 0x1a */ + if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) + { + error = (*cb)( buf+start, end-start, lineno, (void*)&cb, client_data ); + if ( error ) + break; } + + lineno += 1; + buf[end] = (char)hold; + start = end+1; + + if ( hold == '\n' ) + to_skip = '\r'; + else if ( hold == '\r' ) + to_skip = '\n'; + else + to_skip = NO_SKIP; } - *lno = lineno; + *lno = lineno; Exit: FT_FREE( buf ); @@ -955,7 +952,8 @@ if ( c1->encoding < c2->encoding ) return -1; - else if ( c1->encoding > c2->encoding ) + + if ( c1->encoding > c2->encoding ) return 1; return 0; @@ -979,23 +977,16 @@ if ( hash_lookup( name, &(font->proptbl) ) ) goto Exit; - if ( font->nuser_props == 0 ) - { - if ( FT_NEW_ARRAY( font->user_props, 1 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY( font->user_props, - font->nuser_props, - font->nuser_props + 1 ) ) - goto Exit; - } + if ( FT_RENEW_ARRAY( font->user_props, + font->nuser_props, + font->nuser_props + 1 ) ) + goto Exit; p = font->user_props + font->nuser_props; - FT_MEM_ZERO( p, sizeof ( bdf_property_t ) ); + FT_ZERO( p ); n = (unsigned long)( ft_strlen( name ) + 1 ); + if ( FT_NEW_ARRAY( p->name, n ) ) goto Exit; @@ -1110,23 +1101,16 @@ FT_Error error = BDF_Err_Ok; - if ( font->comments_len == 0 ) - { - if ( FT_NEW_ARRAY( font->comments, len + 1 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY( font->comments, - font->comments_len, - font->comments_len + len + 1 ) ) - goto Exit; - } + if ( FT_RENEW_ARRAY( font->comments, + font->comments_len, + font->comments_len + len + 1 ) ) + goto Exit; cp = font->comments + font->comments_len; + FT_MEM_COPY( cp, comment, len ); - cp += len; - *cp++ = '\n'; + cp[len] = '\n'; + font->comments_len += len + 1; Exit: @@ -1155,16 +1139,16 @@ memory = font->memory; + _bdf_list_init( &list, memory ); + font->spacing = opts->font_spacing; len = (unsigned long)( ft_strlen( font->name ) + 1 ); FT_MEM_COPY( name, font->name, len ); - list.size = list.used = 0; - - error = _bdf_split( (char *)"-", name, len, &list, memory ); + error = _bdf_list_split( &list, (char *)"-", name, len ); if ( error ) - goto Exit; + goto Fail; if ( list.used == 15 ) { @@ -1185,7 +1169,8 @@ } } - FT_FREE( list.field ); + Fail: + _bdf_list_done( &list ); Exit: return error; @@ -1484,7 +1469,7 @@ goto Exit; } - error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); @@ -1538,15 +1523,17 @@ /* encoding can be checked for an unencoded character. */ FT_FREE( p->glyph_name ); - error = _bdf_split( (char *)" +", line, linelen, &p->list,memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - _bdf_shift( 1, &p->list ); - s = _bdf_join( ' ', &slen, &p->list ); + _bdf_list_shift( &p->list, 1 ); + + s = _bdf_list_join( &p->list, ' ', &slen ); if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) goto Exit; + FT_MEM_COPY( p->glyph_name, s, slen + 1 ); p->flags |= _BDF_GLYPH; @@ -1565,9 +1552,10 @@ goto Exit; } - error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); /* Check to see whether this encoding has already been encountered. */ @@ -1598,8 +1586,7 @@ font->glyphs_size, font->glyphs_size + 64 ) ) goto Exit; - FT_MEM_ZERO( font->glyphs + font->glyphs_size, - sizeof ( bdf_glyph_t ) * 64 ); /* FZ inutile */ + font->glyphs_size += 64; } @@ -1619,18 +1606,11 @@ /* Allocate the next unencoded glyph. */ if ( font->unencoded_used == font->unencoded_size ) { - if ( font->unencoded_size == 0 ) - { - if ( FT_NEW_ARRAY( font->unencoded, 4 ) ) - goto Exit; - } - else - { - if ( FT_RENEW_ARRAY( font->unencoded , - font->unencoded_size, - font->unencoded_size + 4 ) ) - goto Exit; - } + if ( FT_RENEW_ARRAY( font->unencoded , + font->unencoded_size, + font->unencoded_size + 4 ) ) + goto Exit; + font->unencoded_size += 4; } @@ -1719,9 +1699,10 @@ goto Exit; } - error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); p->flags |= _BDF_SWIDTH; @@ -1731,9 +1712,10 @@ /* Expect the DWIDTH (scalable width) field next. */ if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) { - error = _bdf_split( (char *)" +", line, linelen, &p->list,memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); if ( !( p->flags & _BDF_SWIDTH ) ) @@ -1755,7 +1737,7 @@ /* Expect the BBX field next. */ if ( ft_memcmp( line, "BBX", 3 ) == 0 ) { - error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; @@ -1936,13 +1918,13 @@ } else { - error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; name = p->list.field[0]; - _bdf_shift( 1, &p->list ); - value = _bdf_join( ' ', &vlen, &p->list ); + _bdf_list_shift( &p->list, 1 ); + value = _bdf_list_join( &p->list, ' ', &vlen ); error = _bdf_add_property( p->font, name, value ); if ( error ) @@ -2057,7 +2039,7 @@ /* Check for the start of the properties. */ if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 ) { - error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); @@ -2082,7 +2064,7 @@ goto Exit; } - error = _bdf_split( (char *)" +", line, linelen, &p->list , memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; @@ -2105,12 +2087,12 @@ /* The next thing to check for is the FONT field. */ if ( ft_memcmp( line, "FONT", 4 ) == 0 ) { - error = _bdf_split( (char *)" +", line, linelen, &p->list , memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - _bdf_shift( 1, &p->list ); + _bdf_list_shift( &p->list, 1 ); - s = _bdf_join( ' ', &slen, &p->list ); + s = _bdf_list_join( &p->list, ' ', &slen ); if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) goto Exit; FT_MEM_COPY( p->font->name, s, slen + 1 ); @@ -2137,7 +2119,7 @@ goto Exit; } - error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; @@ -2207,7 +2189,7 @@ FT_Error error = BDF_Err_Ok; - if ( FT_ALLOC( p, sizeof ( _bdf_parse_t ) ) ) + if ( FT_NEW( p ) ) goto Exit; memory = NULL; @@ -2215,6 +2197,8 @@ p->minlb = 32767; p->memory = extmemory; /* only during font creation */ + _bdf_list_init( &p->list, extmemory ); + error = _bdf_readstream( stream, _bdf_parse_start, (void *)p, &lineno ); if ( error ) @@ -2301,10 +2285,6 @@ } } - /* Free up the list used during the parsing. */ - if ( memory != NULL ) - FT_FREE( p->list.field ); - if ( p->font != 0 ) { /* Make sure the comments are NULL terminated if they exist. */ @@ -2327,7 +2307,10 @@ Exit: if ( p ) { + _bdf_list_done( &p->list ); + memory = extmemory; + FT_FREE( p ); } diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c index a78c19524..c2ae1a00e 100644 --- a/src/gzip/ftgzip.c +++ b/src/gzip/ftgzip.c @@ -561,6 +561,12 @@ FT_Memory memory = source->memory; FT_GZipFile zip; + /* check the header right now, this prevents allocating un-necessary + * objects when we don't need them + */ + error = ft_gzip_check_header( source ); + if ( error ) + goto Exit; FT_ZERO( stream ); stream->memory = memory; diff --git a/src/lzw/ftlzw.c b/src/lzw/ftlzw.c index a0e4cc576..bf52b77fc 100644 --- a/src/lzw/ftlzw.c +++ b/src/lzw/ftlzw.c @@ -414,6 +414,16 @@ FT_Memory memory = source->memory; FT_LZWFile zip; + /* check the header right now, this will prevent us from + * allocating a huge LZWFile object (400 Kb of heap memory !!) + * when not necessary. + * + * Did I mention that you should never use .Z compressed font + * file ? + */ + error = ft_lzw_check_header( source ); + if ( error ) + goto Exit; FT_ZERO( stream ); stream->memory = memory;