/[freetype]/freetype2/src/lzw/ftzopen.c
ViewVC logotype

Diff of /freetype2/src/lzw/ftzopen.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by wl, Fri Oct 21 09:08:28 2005 UTC revision 1.3 by wl, Sun Oct 23 19:25:41 2005 UTC
# Line 23  Line 23 
23  #include FT_INTERNAL_STREAM_H  #include FT_INTERNAL_STREAM_H
24  #include FT_INTERNAL_DEBUG_H  #include FT_INTERNAL_DEBUG_H
25    
26  /* refill input buffer, return 0 on success, or -1 if eof    /* refill input buffer, return 0 on success, or -1 if eof */
27   */    static int
28  static int    ft_lzwstate_refill( FT_LzwState  state )
29  ft_lzwstate_refill( FT_LzwState  state )    {
30  {      int  result = -1;
31    int  result = -1;  
32    
33    if ( !state->in_eof )      if ( !state->in_eof )
34        {
35          FT_ULong  count = FT_Stream_TryRead( state->source,
36                                               state->in_buff,
37                                               sizeof ( state->in_buff ) );
38    
39          state->in_cursor = state->in_buff;
40          state->in_limit  = state->in_buff + count;
41          state->in_eof    = FT_BOOL( count < sizeof ( state->in_buff ) );
42    
43          if ( count > 0 )
44            result = 0;
45        }
46        return result;
47      }
48    
49    
50      /* return new code of 'num_bits', or -1 if eof */
51      static FT_Int32
52      ft_lzwstate_get_code( FT_LzwState  state,
53                            FT_UInt      num_bits )
54    {    {
55      FT_ULong  count = FT_Stream_TryRead( state->source,      FT_Int32   result   = -1;
56                                           state->in_buff,      FT_UInt32  pad      = state->pad;
57                                           sizeof( state->in_buff ) );      FT_UInt    pad_bits = state->pad_bits;
58    
     state->in_cursor = state->in_buff;  
     state->in_limit  = state->in_buff + count;  
     state->in_eof    = FT_BOOL( count < sizeof( state->in_buff ) );  
59    
60      if ( count > 0 )      while ( num_bits > pad_bits )
61        result = 0;      {
62          if ( state->in_cursor >= state->in_limit &&
63               ft_lzwstate_refill( state ) < 0     )
64            goto Exit;
65    
66          pad      |= (FT_UInt32)(*state->in_cursor++) << pad_bits;
67          pad_bits += 8;
68        }
69    
70        result          = (FT_Int32)( pad & LZW_MASK( num_bits ) );
71        state->pad_bits = pad_bits - num_bits;
72        state->pad      = pad >> num_bits;
73    
74      Exit:
75        return result;
76    }    }
   return result;  
 }  
77    
78    
79  /* return new code of 'num_bits', or -1 if eof    /* grow the character stack */
80   */    static int
81  static FT_Int32    ft_lzwstate_stack_grow( FT_LzwState  state )
82  ft_lzwstate_get_code( FT_LzwState  state,    {
83                        FT_UInt      num_bits )      if ( state->stack_top >= state->stack_size )
84  {      {
85    FT_Int32   result   = -1;        FT_Memory  memory = state->memory;
86    FT_UInt32  pad      = state->pad;        FT_Error   error;
87    FT_UInt    pad_bits = state->pad_bits;        FT_UInt    old_size = state->stack_size;
88          FT_UInt    new_size = old_size;
89    
90    while ( num_bits > pad_bits )        new_size = new_size + ( new_size >> 1 ) + 4;
91    
92          if ( state->stack == state->stack_0 )
93          {
94            state->stack = NULL;
95            old_size     = 0;
96          }
97    
98          if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) )
99            return -1;
100    
101          state->stack_size = new_size;
102        }
103        return 0;
104      }
105    
106    
107      /* grow the prefix/suffix arrays */
108      static int
109      ft_lzwstate_prefix_grow( FT_LzwState  state )
110    {    {
111      if ( state->in_cursor >= state->in_limit &&      FT_UInt    old_size = state->prefix_size;
112           ft_lzwstate_refill( state ) < 0    )      FT_UInt    new_size = old_size;
113        goto Exit;      FT_Memory  memory   = state->memory;
114        FT_Error   error;
115    
116    
117        if ( new_size == 0 )  /* first allocation -> 9 bits */
118          new_size = 512;
119        else
120          new_size += new_size >> 2;  /* don't grow too fast */
121    
122        /*
123         *  Note that the `suffix' array is located in the same memory block
124         *  pointed to by `prefix'.
125         *
126         *  I know that sizeof(FT_Byte) == 1 by definition, but it is clearer
127         *  to write it literally.
128         *
129         */
130        if ( FT_REALLOC(
131               state->prefix,
132               old_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ),
133               new_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) ) )
134          return -1;
135    
136      pad      |= (FT_UInt32)(*state->in_cursor++) << pad_bits;      /* now adjust `suffix' and move the data accordingly */
137      pad_bits += 8;      state->suffix = (FT_Byte*)( state->prefix + new_size );
138    
139        FT_MEM_MOVE( state->suffix,
140                     state->prefix + old_size,
141                     old_size * sizeof ( FT_Byte ) );
142    
143        state->prefix_size = new_size;
144        return 0;
145    }    }
146    
147    result          = (FT_Int32)( pad & LZW_MASK(num_bits) );  
148    state->pad_bits = pad_bits - num_bits;    FT_LOCAL_DEF( void )
149    state->pad      = pad >> num_bits;    ft_lzwstate_reset( FT_LzwState  state )
150      {
151  Exit:      state->in_cursor = state->in_buff;
152    return result;      state->in_limit  = state->in_buff;
153  }      state->in_eof    = 0;
154        state->pad_bits  = 0;
155        state->pad       = 0;
156    
157        state->stack_top = 0;
158        state->num_bits  = LZW_INIT_BITS;
159        state->phase     = FT_LZW_PHASE_START;
160      }
161    
162    
163  /* grow the character stack    FT_LOCAL_DEF( void )
164   */    ft_lzwstate_init( FT_LzwState  state,
165  static int                      FT_Stream    source )
166  ft_lzwstate_stack_grow( FT_LzwState  state )    {
167  {      FT_ZERO( state );
168    if ( state->stack_top >= state->stack_size )  
169        state->source = source;
170        state->memory = source->memory;
171    
172        state->prefix      = NULL;
173        state->suffix      = NULL;
174        state->prefix_size = 0;
175    
176        state->stack      = state->stack_0;
177        state->stack_size = sizeof ( state->stack_0 );
178    
179        ft_lzwstate_reset( state );
180      }
181    
182    
183      FT_LOCAL_DEF( void )
184      ft_lzwstate_done( FT_LzwState  state )
185    {    {
186      FT_Memory  memory = state->memory;      FT_Memory  memory = state->memory;
     FT_Error   error;  
     FT_UInt    old_size = state->stack_size;  
     FT_UInt    new_size = old_size;  
187    
     new_size = new_size + (new_size >> 1) + 4;  
188    
189      if ( state->stack == state->stack_0 )      ft_lzwstate_reset( state );
     {  
       state->stack = NULL;  
       old_size     = 0;  
     }  
190    
191      if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) )      if ( state->stack != state->stack_0 )
192        return -1;        FT_FREE( state->stack );
193    
194      state->stack_size = new_size;      FT_FREE( state->prefix );
195        state->suffix = NULL;
196    
197        FT_ZERO( state );
198    }    }
   return 0;  
 }  
199    
200    
201  /* grow the prefix/suffix arrays  #define FTLZW_STACK_PUSH( c )                          \
202   */    FT_BEGIN_STMNT                                       \
203  static int      if ( state->stack_top >= state->stack_size &&      \
204  ft_lzwstate_prefix_grow( FT_LzwState  state )           ft_lzwstate_stack_grow( state ) < 0   )       \
205  {        goto Eof;                                        \
206    FT_UInt    old_size = state->prefix_size;                                                         \
207    FT_UInt    new_size = old_size;      state->stack[ state->stack_top++ ] = (FT_Byte)(c); \
   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'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;  
 }  
   
   
 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;  
   
   state->stack_top  = 0;  
   state->num_bits   = LZW_INIT_BITS;  
   state->phase      = FT_LZW_PHASE_START;  
 }  
   
   
 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_lzwstate_reset( state );  
   
   if ( state->stack != state->stack_0 )  
     FT_FREE( state->stack );  
   
   FT_FREE( state->prefix );  
   state->suffix = NULL;  
   
   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);     \  
208    FT_END_STMNT    FT_END_STMNT
209    
210    
211      FT_LOCAL_DEF( FT_ULong )
212      ft_lzwstate_io( FT_LzwState  state,
213                      FT_Byte*     buffer,
214                      FT_ULong     out_size )
215      {
216        FT_ULong  result = 0;
217    
218        FT_UInt  num_bits = state->num_bits;
219        FT_UInt  free_ent = state->free_ent;
220        FT_UInt  old_char = state->old_char;
221        FT_UInt  old_code = state->old_code;
222        FT_UInt  in_code  = state->in_code;
223    
 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;  
224    
225    if ( out_size == 0 )      if ( out_size == 0 )
226      goto Exit;        goto Exit;
227    
228    switch ( state->phase )      switch ( state->phase )
229    {      {
230      case FT_LZW_PHASE_START:      case FT_LZW_PHASE_START:
231        {        {
232          FT_Byte   max_bits;          FT_Byte   max_bits;
233          FT_Int32  c;          FT_Int32  c;
234    
235    
236          /* skip magic bytes, and read max_bits + block_flag */          /* skip magic bytes, and read max_bits + block_flag */
237          if ( FT_Stream_Seek( state->source, 2 ) != 0               ||          if ( FT_Stream_Seek( state->source, 2 ) != 0               ||
238               FT_Stream_TryRead( state->source, &max_bits, 1 ) != 1 )               FT_Stream_TryRead( state->source, &max_bits, 1 ) != 1 )
# Line 236  ft_lzwstate_io( FT_LzwState  state, Line 240  ft_lzwstate_io( FT_LzwState  state,
240    
241          state->max_bits   = max_bits & LZW_BIT_MASK;          state->max_bits   = max_bits & LZW_BIT_MASK;
242          state->block_mode = max_bits & LZW_BLOCK_MASK;          state->block_mode = max_bits & LZW_BLOCK_MASK;
243          state->max_free   = (FT_UInt)((1UL << state->max_bits) - 256);          state->max_free   = (FT_UInt)( ( 1UL << state->max_bits ) - 256 );
244    
245          if ( state->max_bits > LZW_MAX_BITS )          if ( state->max_bits > LZW_MAX_BITS )
246            goto Eof;            goto Eof;
247    
248          num_bits = LZW_INIT_BITS;          num_bits = LZW_INIT_BITS;
249          free_ent = (state->block_mode ? LZW_FIRST : LZW_CLEAR) - 256;          free_ent = ( state->block_mode ? LZW_FIRST : LZW_CLEAR ) - 256;
250          in_code  = 0;          in_code  = 0;
251    
252          state->free_bits = num_bits < state->max_bits          state->free_bits = num_bits < state->max_bits
253                           ? (FT_UInt)((1UL << num_bits) - 256)                             ? (FT_UInt)( ( 1UL << num_bits ) - 256 )
254                           : state->max_free+1;                             : state->max_free + 1;
255    
256          c = ft_lzwstate_get_code( state, num_bits );          c = ft_lzwstate_get_code( state, num_bits );
257          if ( c < 0 )          if ( c < 0 )
# Line 270  ft_lzwstate_io( FT_LzwState  state, Line 274  ft_lzwstate_io( FT_LzwState  state,
274          FT_Int32  c;          FT_Int32  c;
275          FT_UInt   code;          FT_UInt   code;
276    
277    
278        NextCode:        NextCode:
279          c = ft_lzwstate_get_code( state, num_bits );          c = ft_lzwstate_get_code( state, num_bits );
280          if ( c < 0 ) goto Eof;          if ( c < 0 )
281              goto Eof;
282    
283          code = (FT_UInt)c;          code = (FT_UInt)c;
284    
285          if ( code == LZW_CLEAR && state->block_mode )          if ( code == LZW_CLEAR && state->block_mode )
286          {          {
287            free_ent = (LZW_FIRST-1)-256; /* why not LZW_FIRST-256 ? */            free_ent = ( LZW_FIRST - 1 ) - 256; /* why not LZW_FIRST-256 ? */
288            num_bits = LZW_INIT_BITS;            num_bits = LZW_INIT_BITS;
289    
290            state->free_bits = num_bits < state->max_bits            state->free_bits = num_bits < state->max_bits
291                             ? (FT_UInt)((1UL << num_bits) - 256)                               ? (FT_UInt)( ( 1UL << num_bits ) - 256 )
292                             : state->max_free+1;                               : state->max_free + 1;
293    
294            c = ft_lzwstate_get_code( state, num_bits );            c = ft_lzwstate_get_code( state, num_bits );
295            if ( c < 0 ) goto Eof;            if ( c < 0 )
296                goto Eof;
297    
298            code = (FT_UInt)c;            code = (FT_UInt)c;
299          }          }
# Line 296  ft_lzwstate_io( FT_LzwState  state, Line 303  ft_lzwstate_io( FT_LzwState  state,
303          if ( code >= 256U )          if ( code >= 256U )
304          {          {
305            /* special case for KwKwKwK */            /* special case for KwKwKwK */
306            if ( code-256U >= free_ent )            if ( code - 256U >= free_ent )
307            {            {
308              FTLZW_STACK_PUSH( old_char );              FTLZW_STACK_PUSH( old_char );
309              code = old_code;              code = old_code;
# Line 304  ft_lzwstate_io( FT_LzwState  state, Line 311  ft_lzwstate_io( FT_LzwState  state,
311    
312            while ( code >= 256U )            while ( code >= 256U )
313            {            {
314              FTLZW_STACK_PUSH( state->suffix[code-256] );              FTLZW_STACK_PUSH( state->suffix[code - 256] );
315              code = state->prefix[code-256];              code = state->prefix[code - 256];
316            }            }
317          }          }
318    
319          old_char = code;          old_char = code;
320          FTLZW_STACK_PUSH(old_char);          FTLZW_STACK_PUSH( old_char );
321    
322          state->phase = FT_LZW_PHASE_STACK;          state->phase = FT_LZW_PHASE_STACK;
323        }        }
# Line 338  ft_lzwstate_io( FT_LzwState  state, Line 345  ft_lzwstate_io( FT_LzwState  state,
345    
346            FT_ASSERT( free_ent < state->prefix_size );            FT_ASSERT( free_ent < state->prefix_size );
347    
348            state->prefix[free_ent] = (FT_UShort) old_code;            state->prefix[free_ent] = (FT_UShort)old_code;
349            state->suffix[free_ent] = (FT_Byte)   old_char;            state->suffix[free_ent] = (FT_Byte)  old_char;
350    
351            if ( ++free_ent == state->free_bits )            if ( ++free_ent == state->free_bits )
352            {            {
353              num_bits++;              num_bits++;
354    
355              state->free_bits = num_bits < state->max_bits              state->free_bits = num_bits < state->max_bits
356                               ? (FT_UInt)((1UL << num_bits)-256)                                 ? (FT_UInt)( ( 1UL << num_bits ) - 256 )
357                               : state->max_free+1;                                 : state->max_free + 1;
358            }            }
359          }          }
360    
# Line 359  ft_lzwstate_io( FT_LzwState  state, Line 366  ft_lzwstate_io( FT_LzwState  state,
366    
367      default:  /* state == EOF */      default:  /* state == EOF */
368        ;        ;
369        }
370    
371      Exit:
372        state->num_bits = num_bits;
373        state->free_ent = free_ent;
374        state->old_code = old_code;
375        state->old_char = old_char;
376        state->in_code  = in_code;
377    
378        return result;
379    
380      Eof:
381        state->phase = FT_LZW_PHASE_EOF;
382        goto Exit;
383    }    }
384  Exit:  
385    state->num_bits = num_bits;  
386    state->free_ent = free_ent;  /* END */
   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;  
 }  

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26