diff --git a/src/lzw/ftlzw2.c b/src/lzw/ftlzw2.c index 1e3bda8b5..b1239dd22 100644 --- a/src/lzw/ftlzw2.c +++ b/src/lzw/ftlzw2.c @@ -61,17 +61,17 @@ /***************************************************************************/ /***************************************************************************/ -#define FT_LZW_BUFFER_SIZE 4096 +#define FT_LZW_BUFFER_SIZE 4096 - typedef struct FT_LZWFileRec_ + typedef struct FT_LZWFileRec_ { FT_Stream source; /* parent/source stream */ FT_Stream stream; /* embedding stream */ FT_Memory memory; /* memory allocator */ FT_LzwStateRec lzw; /* lzw decompressor state */ - FT_Byte buffer[ FT_LZW_BUFFER_SIZE ]; /* output buffer */ - FT_ULong pos; /* position in output */ + FT_Byte buffer[FT_LZW_BUFFER_SIZE]; /* output buffer */ + FT_ULong pos; /* position in output */ FT_Byte* cursor; FT_Byte* limit; @@ -90,7 +90,7 @@ FT_STREAM_READ( head, 2 ) ) goto Exit; - /* head[0] && head[1] are the magic numbers */ + /* head[0] && head[1] are the magic numbers */ if ( head[0] != 0x1f || head[1] != 0x9d ) error = LZW_Err_Invalid_File_Format; @@ -194,11 +194,12 @@ { FT_Error error = LZW_Err_Ok; - /* first, we skip what we can from the output buffer - */ + + /* first, we skip what we can from the output buffer */ { FT_ULong delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) delta = count; @@ -208,13 +209,13 @@ count -= delta; } - /* next, we skip as many bytes remaining as possible - */ + /* next, we skip as many bytes remaining as possible */ while ( count > 0 ) { FT_ULong delta = FT_LZW_BUFFER_SIZE; FT_ULong numread; + if ( delta > count ) delta = count; @@ -247,12 +248,11 @@ /* seeking backwards. */ if ( pos < zip->pos ) { - /* if the new position is within the output buffer, simply - * decrement pointers, otherwise, we'll reset the stream completely !! - */ - if ( (zip->pos - pos) <= (FT_ULong)(zip->cursor - zip->buffer) ) + /* If the new position is within the output buffer, simply */ + /* decrement pointers, otherwise we reset the stream completely! */ + if ( ( zip->pos - pos ) <= (FT_ULong)( zip->cursor - zip->buffer ) ) { - zip->cursor -= (zip->pos - pos); + zip->cursor -= zip->pos - pos; zip->pos = pos; } else @@ -353,11 +353,11 @@ /* - * Check the header right now; this prevents allocation a huge + * Check the header right now; this prevents allocation of a huge * LZWFile object (400 KByte of heap memory) if not necessary. * * Did I mention that you should never use .Z compressed font - * file? + * files? */ error = ft_lzw_check_header( source ); if ( error ) @@ -388,6 +388,7 @@ return error; } + #include "ftzopen.c" diff --git a/src/lzw/ftzopen.c b/src/lzw/ftzopen.c index af6c211b6..4105cfa1e 100644 --- a/src/lzw/ftzopen.c +++ b/src/lzw/ftzopen.c @@ -23,212 +23,216 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H -/* refill input buffer, return 0 on success, or -1 if eof - */ -static int -ft_lzwstate_refill( FT_LzwState state ) -{ - int result = -1; - - if ( !state->in_eof ) + /* refill input buffer, return 0 on success, or -1 if eof */ + static int + ft_lzwstate_refill( FT_LzwState state ) { - FT_ULong count = FT_Stream_TryRead( state->source, - state->in_buff, - sizeof( state->in_buff ) ); - - state->in_cursor = state->in_buff; - state->in_limit = state->in_buff + count; - state->in_eof = FT_BOOL( count < sizeof( state->in_buff ) ); - - if ( count > 0 ) - result = 0; - } - return result; -} + int result = -1; -/* return new code of 'num_bits', or -1 if eof - */ -static FT_Int32 -ft_lzwstate_get_code( FT_LzwState state, - FT_UInt num_bits ) -{ - FT_Int32 result = -1; - FT_UInt32 pad = state->pad; - FT_UInt pad_bits = state->pad_bits; - - while ( num_bits > pad_bits ) - { - if ( state->in_cursor >= state->in_limit && - ft_lzwstate_refill( state ) < 0 ) - goto Exit; - - pad |= (FT_UInt32)(*state->in_cursor++) << pad_bits; - pad_bits += 8; - } - - result = (FT_Int32)( pad & LZW_MASK(num_bits) ); - state->pad_bits = pad_bits - num_bits; - state->pad = pad >> num_bits; - -Exit: - return result; -} - - -/* grow the character stack - */ -static int -ft_lzwstate_stack_grow( FT_LzwState state ) -{ - if ( state->stack_top >= state->stack_size ) - { - FT_Memory memory = state->memory; - FT_Error error; - FT_UInt old_size = state->stack_size; - FT_UInt new_size = old_size; - - new_size = new_size + (new_size >> 1) + 4; - - if ( state->stack == state->stack_0 ) + if ( !state->in_eof ) { - state->stack = NULL; - old_size = 0; + FT_ULong count = FT_Stream_TryRead( state->source, + state->in_buff, + sizeof ( state->in_buff ) ); + + state->in_cursor = state->in_buff; + state->in_limit = state->in_buff + count; + state->in_eof = FT_BOOL( count < sizeof ( state->in_buff ) ); + + if ( count > 0 ) + result = 0; + } + return result; + } + + + /* return new code of 'num_bits', or -1 if eof */ + static FT_Int32 + ft_lzwstate_get_code( FT_LzwState state, + FT_UInt num_bits ) + { + FT_Int32 result = -1; + FT_UInt32 pad = state->pad; + FT_UInt pad_bits = state->pad_bits; + + + while ( num_bits > pad_bits ) + { + if ( state->in_cursor >= state->in_limit && + ft_lzwstate_refill( state ) < 0 ) + goto Exit; + + pad |= (FT_UInt32)(*state->in_cursor++) << pad_bits; + pad_bits += 8; } - if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) ) + result = (FT_Int32)( pad & LZW_MASK( num_bits ) ); + state->pad_bits = pad_bits - num_bits; + state->pad = pad >> num_bits; + + Exit: + return result; + } + + + /* grow the character stack */ + static int + ft_lzwstate_stack_grow( FT_LzwState state ) + { + if ( state->stack_top >= state->stack_size ) + { + FT_Memory memory = state->memory; + FT_Error error; + FT_UInt old_size = state->stack_size; + FT_UInt new_size = old_size; + + new_size = new_size + ( new_size >> 1 ) + 4; + + if ( state->stack == state->stack_0 ) + { + state->stack = NULL; + old_size = 0; + } + + if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) ) + return -1; + + state->stack_size = new_size; + } + return 0; + } + + + /* grow the prefix/suffix arrays */ + static int + ft_lzwstate_prefix_grow( FT_LzwState state ) + { + FT_UInt old_size = state->prefix_size; + FT_UInt new_size = old_size; + FT_Memory memory = state->memory; + FT_Error error; + + + if ( new_size == 0 ) /* first allocation -> 9 bits */ + new_size = 512; + else + new_size += new_size >> 2; /* don't grow too fast */ + + /* + * Note that the `suffix' array is located in the same memory block + * pointed to by `prefix'. + * + * I know that sizeof(FT_Byte) == 1 by definition, but it is clearer + * to write it literally. + * + */ + if ( FT_REALLOC( + state->prefix, + old_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ), + new_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) ) ) return -1; - state->stack_size = new_size; + /* now adjust `suffix' and move the data accordingly */ + state->suffix = (FT_Byte*)( state->prefix + new_size ); + + FT_MEM_MOVE( state->suffix, + state->prefix + old_size, + old_size * sizeof ( FT_Byte ) ); + + state->prefix_size = new_size; + return 0; } - return 0; -} -/* grow the prefix/suffix arrays - */ -static int -ft_lzwstate_prefix_grow( FT_LzwState state ) -{ - FT_UInt old_size = state->prefix_size; - FT_UInt new_size = old_size; - FT_Memory memory = state->memory; - FT_Error error; + FT_LOCAL_DEF( void ) + ft_lzwstate_reset( FT_LzwState state ) + { + state->in_cursor = state->in_buff; + state->in_limit = state->in_buff; + state->in_eof = 0; + state->pad_bits = 0; + state->pad = 0; - if ( new_size == 0 ) /* first allocation -> 9 bits */ - new_size = 512; - else - new_size += (new_size >> 2); /* don't grow too fast */ - - /* note that the 'suffix' array is located in the same memory block - * pointed to by 'prefix' - * - * I know that sizeof(FT_Byte) == 1 by definition, but it's clearer - * to write it literally - */ - if ( FT_REALLOC( state->prefix, - old_size*(sizeof(FT_UShort)+sizeof(FT_Byte)), - new_size*(sizeof(FT_UShort)+sizeof(FT_Byte)) ) ) - return -1; - - /* now adjust 'suffix' and move the data accordingly */ - state->suffix = (FT_Byte*)(state->prefix + new_size); - - FT_MEM_MOVE( state->suffix, - state->prefix + old_size, - old_size * sizeof(FT_Byte) ); - - state->prefix_size = new_size; - return 0; -} + state->stack_top = 0; + state->num_bits = LZW_INIT_BITS; + state->phase = FT_LZW_PHASE_START; + } -FT_LOCAL_DEF( void ) -ft_lzwstate_reset( FT_LzwState state ) -{ - state->in_cursor = state->in_buff; - state->in_limit = state->in_buff; - state->in_eof = 0; - state->pad_bits = 0; - state->pad = 0; + FT_LOCAL_DEF( void ) + ft_lzwstate_init( FT_LzwState state, + FT_Stream source ) + { + FT_ZERO( state ); - state->stack_top = 0; - state->num_bits = LZW_INIT_BITS; - state->phase = FT_LZW_PHASE_START; -} + state->source = source; + state->memory = source->memory; + + state->prefix = NULL; + state->suffix = NULL; + state->prefix_size = 0; + + state->stack = state->stack_0; + state->stack_size = sizeof ( state->stack_0 ); + + ft_lzwstate_reset( state ); + } -FT_LOCAL_DEF( void ) -ft_lzwstate_init( FT_LzwState state, - FT_Stream source ) -{ - FT_ZERO( state ); - - state->source = source; - state->memory = source->memory; - - state->prefix = NULL; - state->suffix = NULL; - state->prefix_size = 0; - - state->stack = state->stack_0; - state->stack_size = sizeof(state->stack_0); - - ft_lzwstate_reset( state ); -} + FT_LOCAL_DEF( void ) + ft_lzwstate_done( FT_LzwState state ) + { + FT_Memory memory = state->memory; -FT_LOCAL_DEF( void ) -ft_lzwstate_done( FT_LzwState state ) -{ - FT_Memory memory = state->memory; + ft_lzwstate_reset( state ); - ft_lzwstate_reset( state ); + if ( state->stack != state->stack_0 ) + FT_FREE( state->stack ); - if ( state->stack != state->stack_0 ) - FT_FREE( state->stack ); + FT_FREE( state->prefix ); + state->suffix = NULL; - FT_FREE( state->prefix ); - state->suffix = NULL; - - FT_ZERO( state ); -} + FT_ZERO( state ); + } -#define FTLZW_STACK_PUSH(c) \ - FT_BEGIN_STMNT \ - if ( state->stack_top >= state->stack_size && \ - ft_lzwstate_stack_grow( state ) < 0 ) \ - goto Eof; \ - \ - state->stack[ state->stack_top++ ] = (FT_Byte)(c); \ +#define FTLZW_STACK_PUSH( c ) \ + FT_BEGIN_STMNT \ + if ( state->stack_top >= state->stack_size && \ + ft_lzwstate_stack_grow( state ) < 0 ) \ + goto Eof; \ + \ + state->stack[ state->stack_top++ ] = (FT_Byte)(c); \ FT_END_STMNT - -FT_LOCAL_DEF( FT_ULong ) -ft_lzwstate_io( FT_LzwState state, - FT_Byte* buffer, - FT_ULong out_size ) -{ - FT_ULong result = 0; - - FT_UInt num_bits = state->num_bits; - FT_UInt free_ent = state->free_ent; - FT_UInt old_char = state->old_char; - FT_UInt old_code = state->old_code; - FT_UInt in_code = state->in_code; - - if ( out_size == 0 ) - goto Exit; - - switch ( state->phase ) + FT_LOCAL_DEF( FT_ULong ) + ft_lzwstate_io( FT_LzwState state, + FT_Byte* buffer, + FT_ULong out_size ) { + FT_ULong result = 0; + + FT_UInt num_bits = state->num_bits; + FT_UInt free_ent = state->free_ent; + FT_UInt old_char = state->old_char; + FT_UInt old_code = state->old_code; + FT_UInt in_code = state->in_code; + + + if ( out_size == 0 ) + goto Exit; + + switch ( state->phase ) + { case FT_LZW_PHASE_START: { FT_Byte max_bits; FT_Int32 c; + /* skip magic bytes, and read max_bits + block_flag */ if ( FT_Stream_Seek( state->source, 2 ) != 0 || FT_Stream_TryRead( state->source, &max_bits, 1 ) != 1 ) @@ -236,18 +240,18 @@ ft_lzwstate_io( FT_LzwState state, state->max_bits = max_bits & LZW_BIT_MASK; state->block_mode = max_bits & LZW_BLOCK_MASK; - state->max_free = (FT_UInt)((1UL << state->max_bits) - 256); + state->max_free = (FT_UInt)( ( 1UL << state->max_bits ) - 256 ); if ( state->max_bits > LZW_MAX_BITS ) goto Eof; num_bits = LZW_INIT_BITS; - free_ent = (state->block_mode ? LZW_FIRST : LZW_CLEAR) - 256; + free_ent = ( state->block_mode ? LZW_FIRST : LZW_CLEAR ) - 256; in_code = 0; state->free_bits = num_bits < state->max_bits - ? (FT_UInt)((1UL << num_bits) - 256) - : state->max_free+1; + ? (FT_UInt)( ( 1UL << num_bits ) - 256 ) + : state->max_free + 1; c = ft_lzwstate_get_code( state, num_bits ); if ( c < 0 ) @@ -270,23 +274,26 @@ ft_lzwstate_io( FT_LzwState state, FT_Int32 c; FT_UInt code; + NextCode: c = ft_lzwstate_get_code( state, num_bits ); - if ( c < 0 ) goto Eof; + if ( c < 0 ) + goto Eof; code = (FT_UInt)c; if ( code == LZW_CLEAR && state->block_mode ) { - free_ent = (LZW_FIRST-1)-256; /* why not LZW_FIRST-256 ? */ + free_ent = ( LZW_FIRST - 1 ) - 256; /* why not LZW_FIRST-256 ? */ num_bits = LZW_INIT_BITS; state->free_bits = num_bits < state->max_bits - ? (FT_UInt)((1UL << num_bits) - 256) - : state->max_free+1; + ? (FT_UInt)( ( 1UL << num_bits ) - 256 ) + : state->max_free + 1; c = ft_lzwstate_get_code( state, num_bits ); - if ( c < 0 ) goto Eof; + if ( c < 0 ) + goto Eof; code = (FT_UInt)c; } @@ -296,7 +303,7 @@ ft_lzwstate_io( FT_LzwState state, if ( code >= 256U ) { /* special case for KwKwKwK */ - if ( code-256U >= free_ent ) + if ( code - 256U >= free_ent ) { FTLZW_STACK_PUSH( old_char ); code = old_code; @@ -304,13 +311,13 @@ ft_lzwstate_io( FT_LzwState state, while ( code >= 256U ) { - FTLZW_STACK_PUSH( state->suffix[code-256] ); - code = state->prefix[code-256]; + FTLZW_STACK_PUSH( state->suffix[code - 256] ); + code = state->prefix[code - 256]; } } old_char = code; - FTLZW_STACK_PUSH(old_char); + FTLZW_STACK_PUSH( old_char ); state->phase = FT_LZW_PHASE_STACK; } @@ -338,16 +345,16 @@ ft_lzwstate_io( FT_LzwState state, FT_ASSERT( free_ent < state->prefix_size ); - state->prefix[free_ent] = (FT_UShort) old_code; - state->suffix[free_ent] = (FT_Byte) old_char; + state->prefix[free_ent] = (FT_UShort)old_code; + state->suffix[free_ent] = (FT_Byte) old_char; if ( ++free_ent == state->free_bits ) { num_bits++; state->free_bits = num_bits < state->max_bits - ? (FT_UInt)((1UL << num_bits)-256) - : state->max_free+1; + ? (FT_UInt)( ( 1UL << num_bits ) - 256 ) + : state->max_free + 1; } } @@ -359,17 +366,21 @@ ft_lzwstate_io( FT_LzwState state, default: /* state == EOF */ ; + } + + Exit: + state->num_bits = num_bits; + state->free_ent = free_ent; + state->old_code = old_code; + state->old_char = old_char; + state->in_code = in_code; + + return result; + + Eof: + state->phase = FT_LZW_PHASE_EOF; + goto Exit; } -Exit: - state->num_bits = num_bits; - state->free_ent = free_ent; - state->old_code = old_code; - state->old_char = old_char; - state->in_code = in_code; - return result; -Eof: - state->phase = FT_LZW_PHASE_EOF; - goto Exit; -} +/* END */ diff --git a/src/lzw/ftzopen.h b/src/lzw/ftzopen.h index 9fb68be0f..8678241a0 100644 --- a/src/lzw/ftzopen.h +++ b/src/lzw/ftzopen.h @@ -24,139 +24,150 @@ #include #include FT_FREETYPE_H -/* this is a complete re-implementation of the LZW file reader, - * since the old one was incredibly badly written, and used - * 400 Kb of heap memory before decompressing anything. - */ -#define FT_LZW_IN_BUFF_SIZE 64 -#define FT_LZW_DEFAULT_STACK_SIZE 64 + /* + * This is a complete re-implementation of the LZW file reader, + * since the old one was incredibly badly written, using + * 400 KByte of heap memory before decompressing anything. + * + */ -#define LZW_INIT_BITS 9 -#define LZW_MAX_BITS 16 +#define FT_LZW_IN_BUFF_SIZE 64 +#define FT_LZW_DEFAULT_STACK_SIZE 64 -#define LZW_CLEAR 256 -#define LZW_FIRST 257 +#define LZW_INIT_BITS 9 +#define LZW_MAX_BITS 16 -#define LZW_BIT_MASK 0x1f -#define LZW_BLOCK_MASK 0x80 -#define LZW_MASK(n) ((1U << (n)) - 1U) +#define LZW_CLEAR 256 +#define LZW_FIRST 257 -typedef enum -{ - FT_LZW_PHASE_START = 0, - FT_LZW_PHASE_CODE, - FT_LZW_PHASE_STACK, - FT_LZW_PHASE_EOF - -} FT_LzwPhase; +#define LZW_BIT_MASK 0x1f +#define LZW_BLOCK_MASK 0x80 +#define LZW_MASK( n ) ( ( 1U << (n) ) - 1U ) -/* state of LZW decompressor - * - * small technical note: - * - * we use a few tricks in this implementation that are explained here to - * ease debugging and maintenance. - * - * - first of all, the "prefix" and "suffix" arrays contain the - * suffix and prefix for codes over 256, this means that: - * - * prefix_of(code) == state->prefix[ code-256 ] - * suffix_of(code) == state->suffix[ code-256 ] - * - * each prefix is a 16-bit code, and each suffix an 8-bit byte - * - * both arrays are stored in a single memory block, pointed to by - * 'state->prefix', this means that the following equality is always - * true: - * - * state->suffix == (FT_Byte*)(state->prefix + state->prefix_size) - * - * of course, state->prefix_size is the number of prefix/suffix slots - * in the arrays, corresponding to codes 256..255+prefix_size - * - * - 'free_ent' is the index of the next free entry in the "prefix" - * and "suffix" arrays. This means that the corresponding "next free - * code" is really '256+free_ent' - * - * moreover, 'max_free' is the maximum value that 'free_ent' can reach. - * - * 'max_free' corresponds to "(1 << max_bits) - 256". Note that this value - * is always <= 0xFF00, which means that both 'free_ent' and 'max_free' can - * be stored in FT_UInt variable, even on 16-bit machines. - * - * if 'free_ent == max_free', you cannot add new codes to the prefix/suffix - * table. - * - * - 'num_bits' is the current number of code bits, starting at 9 and - * growing each time 'free_ent' reaches the value of 'free_bits'. the - * latter is computed as follows: - * - * if num_bits < max_bits: - * free_bits = (1 << num_bits)-256 - * else: - * free_bits = max_free + 1 - * - * since the value of 'max_free + 1' can never be reached by 'free_ent', - * 'num_bits' cannot grow larger than 'max_bits' - */ -typedef struct -{ - FT_LzwPhase phase; + typedef enum + { + FT_LZW_PHASE_START = 0, + FT_LZW_PHASE_CODE, + FT_LZW_PHASE_STACK, + FT_LZW_PHASE_EOF - FT_Int in_eof; - FT_Byte* in_cursor; /* current buffer pos */ - FT_Byte* in_limit; /* current buffer limit */ - - FT_UInt32 pad; /* a pad value where incoming bits were read */ - FT_Int pad_bits; /* number of meaningful bits in pad value */ - - FT_UInt max_bits; /* max code bits, from file header */ - FT_Int block_mode; /* block mode flag, from file header */ - FT_UInt max_free; /* (1 << max_bits) - 256 */ - - FT_UInt num_bits; /* current code bit number */ - FT_UInt free_ent; /* index of next free entry */ - FT_UInt free_bits; /* if free_ent reaches this, increment num_bits */ - FT_UInt old_code; - FT_UInt old_char; - FT_UInt in_code; - - FT_UShort* prefix; /* always dynamically allocated / reallocated */ - FT_Byte* suffix; /* suffix = (FT_Byte*)(prefix + prefix_size) */ - FT_UInt prefix_size; /* number of slots in 'prefix' or 'suffix' */ - - FT_Byte* stack; /* character stack */ - FT_UInt stack_top; - FT_UInt stack_size; - - FT_Byte in_buff[ FT_LZW_IN_BUFF_SIZE ]; /* small buffer to read data */ - FT_Byte stack_0[ FT_LZW_DEFAULT_STACK_SIZE ]; /* minimize heap alloc */ - - FT_Stream source; /* source stream */ - FT_Memory memory; - -} FT_LzwStateRec, *FT_LzwState; + } FT_LzwPhase; -FT_LOCAL( void ) -ft_lzwstate_init( FT_LzwState state, - FT_Stream source ); + /* + * state of LZW decompressor + * + * small technical note + * -------------------- + * + * We use a few tricks in this implementation that are explained here to + * ease debugging and maintenance. + * + * - First of all, the `prefix' and `suffix' arrays contain the suffix + * and prefix for codes over 256; this means that + * + * prefix_of(code) == state->prefix[code-256] + * suffix_of(code) == state->suffix[code-256] + * + * Each prefix is a 16-bit code, and each suffix an 8-bit byte. + * + * Both arrays are stored in a single memory block, pointed to by + * `state->prefix'. This means that the following equality is always + * true: + * + * state->suffix == (FT_Byte*)(state->prefix + state->prefix_size) + * + * Of course, state->prefix_size is the number of prefix/suffix slots + * in the arrays, corresponding to codes 256..255+prefix_size. + * + * - `free_ent' is the index of the next free entry in the `prefix' + * and `suffix' arrays. This means that the corresponding `next free + * code' is really `256+free_ent'. + * + * Moreover, 'max_free' is the maximum value that 'free_ent' can reach. + * + * `max_free' corresponds to `(1 << max_bits) - 256'. Note that this + * value is always <= 0xFF00, which means that both `free_ent' and + * `max_free' can be stored in an FT_UInt variable, even on 16-bit + * machines. + * + * If `free_ent == max_free', you cannot add new codes to the + * prefix/suffix table. + * + * - `num_bits' is the current number of code bits, starting at 9 and + * growing each time `free_ent' reaches the value of `free_bits'. The + * latter is computed as follows + * + * if num_bits < max_bits: + * free_bits = (1 << num_bits)-256 + * else: + * free_bits = max_free + 1 + * + * Since the value of `max_free + 1' can never be reached by + * `free_ent', `num_bits' cannot grow larger than `max_bits'. + */ -FT_LOCAL( void ) -ft_lzwstate_done( FT_LzwState state ); + typedef struct _FT_LzwStateRec + { + FT_LzwPhase phase; + + FT_Int in_eof; + FT_Byte* in_cursor; /* current buffer pos */ + FT_Byte* in_limit; /* current buffer limit */ + + FT_UInt32 pad; /* a pad value where incoming bits were read */ + FT_Int pad_bits; /* number of meaningful bits in pad value */ + + FT_UInt max_bits; /* max code bits, from file header */ + FT_Int block_mode; /* block mode flag, from file header */ + FT_UInt max_free; /* (1 << max_bits) - 256 */ + + FT_UInt num_bits; /* current code bit number */ + FT_UInt free_ent; /* index of next free entry */ + FT_UInt free_bits; /* if reached by free_ent, increment num_bits */ + FT_UInt old_code; + FT_UInt old_char; + FT_UInt in_code; + + FT_UShort* prefix; /* always dynamically allocated / reallocated */ + FT_Byte* suffix; /* suffix = (FT_Byte*)(prefix + prefix_size) */ + FT_UInt prefix_size; /* number of slots in `prefix' or `suffix' */ + + FT_Byte* stack; /* character stack */ + FT_UInt stack_top; + FT_UInt stack_size; + + FT_Byte in_buff[FT_LZW_IN_BUFF_SIZE]; /* small read-buffer */ + FT_Byte stack_0[FT_LZW_DEFAULT_STACK_SIZE]; /* minimize heap alloc */ + + FT_Stream source; /* source stream */ + FT_Memory memory; + + } FT_LzwStateRec, *FT_LzwState; -FT_LOCAL( void ) -ft_lzwstate_reset( FT_LzwState state ); + FT_LOCAL( void ) + ft_lzwstate_init( FT_LzwState state, + FT_Stream source ); + + FT_LOCAL( void ) + ft_lzwstate_done( FT_LzwState state ); -FT_LOCAL( FT_ULong ) -ft_lzwstate_io( FT_LzwState state, - FT_Byte* buffer, - FT_ULong out_size ); + FT_LOCAL( void ) + ft_lzwstate_reset( FT_LzwState state ); + + + FT_LOCAL( FT_ULong ) + ft_lzwstate_io( FT_LzwState state, + FT_Byte* buffer, + FT_ULong out_size ); /* */ #endif /* __FT_ZOPEN_H__ */ + + +/* END */