ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ftzopen.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftzopen.c                                                              */
00004 /*                                                                         */
00005 /*    FreeType support for .Z compressed files.                            */
00006 /*                                                                         */
00007 /*  This optional component relies on NetBSD's zopen().  It should mainly  */
00008 /*  be used to parse compressed PCF fonts, as found with many X11 server   */
00009 /*  distributions.                                                         */
00010 /*                                                                         */
00011 /*  Copyright 2005, 2006, 2007, 2009 by David Turner.                      */
00012 /*                                                                         */
00013 /*  This file is part of the FreeType project, and may only be used,       */
00014 /*  modified, and distributed under the terms of the FreeType project      */
00015 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00016 /*  this file you indicate that you have read the license and              */
00017 /*  understand and accept it fully.                                        */
00018 /*                                                                         */
00019 /***************************************************************************/
00020 
00021 #include "ftzopen.h"
00022 #include FT_INTERNAL_MEMORY_H
00023 #include FT_INTERNAL_STREAM_H
00024 #include FT_INTERNAL_DEBUG_H
00025 
00026 
00027   static int
00028   ft_lzwstate_refill( FT_LzwState  state )
00029   {
00030     FT_ULong  count;
00031 
00032 
00033     if ( state->in_eof )
00034       return -1;
00035 
00036     count = FT_Stream_TryRead( state->source,
00037                                state->buf_tab,
00038                                state->num_bits );  /* WHY? */
00039 
00040     state->buf_size   = (FT_UInt)count;
00041     state->buf_total += count;
00042     state->in_eof     = FT_BOOL( count < state->num_bits );
00043     state->buf_offset = 0;
00044     state->buf_size   = ( state->buf_size << 3 ) - ( state->num_bits - 1 );
00045 
00046     if ( count == 0 )  /* end of file */
00047       return -1;
00048 
00049     return 0;
00050   }
00051 
00052 
00053   static FT_Int32
00054   ft_lzwstate_get_code( FT_LzwState  state )
00055   {
00056     FT_UInt   num_bits = state->num_bits;
00057     FT_Int    offset   = state->buf_offset;
00058     FT_Byte*  p;
00059     FT_Int    result;
00060 
00061 
00062     if ( state->buf_clear                    ||
00063          offset >= state->buf_size           ||
00064          state->free_ent >= state->free_bits )
00065     {
00066       if ( state->free_ent >= state->free_bits )
00067       {
00068         state->num_bits  = ++num_bits;
00069         state->free_bits = state->num_bits < state->max_bits
00070                            ? (FT_UInt)( ( 1UL << num_bits ) - 256 )
00071                            : state->max_free + 1;
00072       }
00073 
00074       if ( state->buf_clear )
00075       {
00076         state->num_bits  = num_bits = LZW_INIT_BITS;
00077         state->free_bits = (FT_UInt)( ( 1UL << num_bits ) - 256 );
00078         state->buf_clear = 0;
00079       }
00080 
00081       if ( ft_lzwstate_refill( state ) < 0 )
00082         return -1;
00083 
00084       offset = 0;
00085     }
00086 
00087     state->buf_offset = offset + num_bits;
00088 
00089     p         = &state->buf_tab[offset >> 3];
00090     offset   &= 7;
00091     result    = *p++ >> offset;
00092     offset    = 8 - offset;
00093     num_bits -= offset;
00094 
00095     if ( num_bits >= 8 )
00096     {
00097       result   |= *p++ << offset;
00098       offset   += 8;
00099       num_bits -= 8;
00100     }
00101     if ( num_bits > 0 )
00102       result |= ( *p & LZW_MASK( num_bits ) ) << offset;
00103 
00104     return result;
00105   }
00106 
00107 
00108   /* grow the character stack */
00109   static int
00110   ft_lzwstate_stack_grow( FT_LzwState  state )
00111   {
00112     if ( state->stack_top >= state->stack_size )
00113     {
00114       FT_Memory  memory = state->memory;
00115       FT_Error   error;
00116       FT_Offset  old_size = state->stack_size;
00117       FT_Offset  new_size = old_size;
00118 
00119       new_size = new_size + ( new_size >> 1 ) + 4;
00120 
00121       if ( state->stack == state->stack_0 )
00122       {
00123         state->stack = NULL;
00124         old_size     = 0;
00125       }
00126 
00127       if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) )
00128         return -1;
00129 
00130       state->stack_size = new_size;
00131     }
00132     return 0;
00133   }
00134 
00135 
00136   /* grow the prefix/suffix arrays */
00137   static int
00138   ft_lzwstate_prefix_grow( FT_LzwState  state )
00139   {
00140     FT_UInt    old_size = state->prefix_size;
00141     FT_UInt    new_size = old_size;
00142     FT_Memory  memory   = state->memory;
00143     FT_Error   error;
00144 
00145 
00146     if ( new_size == 0 )  /* first allocation -> 9 bits */
00147       new_size = 512;
00148     else
00149       new_size += new_size >> 2;  /* don't grow too fast */
00150 
00151     /*
00152      *  Note that the `suffix' array is located in the same memory block
00153      *  pointed to by `prefix'.
00154      *
00155      *  I know that sizeof(FT_Byte) == 1 by definition, but it is clearer
00156      *  to write it literally.
00157      *
00158      */
00159     if ( FT_REALLOC_MULT( state->prefix, old_size, new_size,
00160                           sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) )
00161       return -1;
00162 
00163     /* now adjust `suffix' and move the data accordingly */
00164     state->suffix = (FT_Byte*)( state->prefix + new_size );
00165 
00166     FT_MEM_MOVE( state->suffix,
00167                  state->prefix + old_size,
00168                  old_size * sizeof ( FT_Byte ) );
00169 
00170     state->prefix_size = new_size;
00171     return 0;
00172   }
00173 
00174 
00175   FT_LOCAL_DEF( void )
00176   ft_lzwstate_reset( FT_LzwState  state )
00177   {
00178     state->in_eof     = 0;
00179     state->buf_offset = 0;
00180     state->buf_size   = 0;
00181     state->buf_clear  = 0;
00182     state->buf_total  = 0;
00183     state->stack_top  = 0;
00184     state->num_bits   = LZW_INIT_BITS;
00185     state->phase      = FT_LZW_PHASE_START;
00186   }
00187 
00188 
00189   FT_LOCAL_DEF( void )
00190   ft_lzwstate_init( FT_LzwState  state,
00191                     FT_Stream    source )
00192   {
00193     FT_ZERO( state );
00194 
00195     state->source = source;
00196     state->memory = source->memory;
00197 
00198     state->prefix      = NULL;
00199     state->suffix      = NULL;
00200     state->prefix_size = 0;
00201 
00202     state->stack      = state->stack_0;
00203     state->stack_size = sizeof ( state->stack_0 );
00204 
00205     ft_lzwstate_reset( state );
00206   }
00207 
00208 
00209   FT_LOCAL_DEF( void )
00210   ft_lzwstate_done( FT_LzwState  state )
00211   {
00212     FT_Memory  memory = state->memory;
00213 
00214 
00215     ft_lzwstate_reset( state );
00216 
00217     if ( state->stack != state->stack_0 )
00218       FT_FREE( state->stack );
00219 
00220     FT_FREE( state->prefix );
00221     state->suffix = NULL;
00222 
00223     FT_ZERO( state );
00224   }
00225 
00226 
00227 #define FTLZW_STACK_PUSH( c )                        \
00228   FT_BEGIN_STMNT                                     \
00229     if ( state->stack_top >= state->stack_size &&    \
00230          ft_lzwstate_stack_grow( state ) < 0   )     \
00231       goto Eof;                                      \
00232                                                      \
00233     state->stack[state->stack_top++] = (FT_Byte)(c); \
00234   FT_END_STMNT
00235 
00236 
00237   FT_LOCAL_DEF( FT_ULong )
00238   ft_lzwstate_io( FT_LzwState  state,
00239                   FT_Byte*     buffer,
00240                   FT_ULong     out_size )
00241   {
00242     FT_ULong  result = 0;
00243 
00244     FT_UInt  old_char = state->old_char;
00245     FT_UInt  old_code = state->old_code;
00246     FT_UInt  in_code  = state->in_code;
00247 
00248 
00249     if ( out_size == 0 )
00250       goto Exit;
00251 
00252     switch ( state->phase )
00253     {
00254     case FT_LZW_PHASE_START:
00255       {
00256         FT_Byte   max_bits;
00257         FT_Int32  c;
00258 
00259 
00260         /* skip magic bytes, and read max_bits + block_flag */
00261         if ( FT_Stream_Seek( state->source, 2 ) != 0               ||
00262              FT_Stream_TryRead( state->source, &max_bits, 1 ) != 1 )
00263           goto Eof;
00264 
00265         state->max_bits   = max_bits & LZW_BIT_MASK;
00266         state->block_mode = max_bits & LZW_BLOCK_MASK;
00267         state->max_free   = (FT_UInt)( ( 1UL << state->max_bits ) - 256 );
00268 
00269         if ( state->max_bits > LZW_MAX_BITS )
00270           goto Eof;
00271 
00272         state->num_bits = LZW_INIT_BITS;
00273         state->free_ent = ( state->block_mode ? LZW_FIRST
00274                                               : LZW_CLEAR ) - 256;
00275         in_code  = 0;
00276 
00277         state->free_bits = state->num_bits < state->max_bits
00278                            ? (FT_UInt)( ( 1UL << state->num_bits ) - 256 )
00279                            : state->max_free + 1;
00280 
00281         c = ft_lzwstate_get_code( state );
00282         if ( c < 0 )
00283           goto Eof;
00284 
00285         old_code = old_char = (FT_UInt)c;
00286 
00287         if ( buffer )
00288           buffer[result] = (FT_Byte)old_char;
00289 
00290         if ( ++result >= out_size )
00291           goto Exit;
00292 
00293         state->phase = FT_LZW_PHASE_CODE;
00294       }
00295       /* fall-through */
00296 
00297     case FT_LZW_PHASE_CODE:
00298       {
00299         FT_Int32  c;
00300         FT_UInt   code;
00301 
00302 
00303       NextCode:
00304         c = ft_lzwstate_get_code( state );
00305         if ( c < 0 )
00306           goto Eof;
00307 
00308         code = (FT_UInt)c;
00309 
00310         if ( code == LZW_CLEAR && state->block_mode )
00311         {
00312           /* why not LZW_FIRST-256 ? */
00313           state->free_ent  = ( LZW_FIRST - 1 ) - 256;
00314           state->buf_clear = 1;
00315           c = ft_lzwstate_get_code( state );
00316           if ( c < 0 )
00317             goto Eof;
00318 
00319           code = (FT_UInt)c;
00320         }
00321 
00322         in_code = code; /* save code for later */
00323 
00324         if ( code >= 256U )
00325         {
00326           /* special case for KwKwKwK */
00327           if ( code - 256U >= state->free_ent )
00328           {
00329             FTLZW_STACK_PUSH( old_char );
00330             code = old_code;
00331           }
00332 
00333           while ( code >= 256U )
00334           {
00335             if ( !state->prefix )
00336               goto Eof;
00337 
00338             FTLZW_STACK_PUSH( state->suffix[code - 256] );
00339             code = state->prefix[code - 256];
00340           }
00341         }
00342 
00343         old_char = code;
00344         FTLZW_STACK_PUSH( old_char );
00345 
00346         state->phase = FT_LZW_PHASE_STACK;
00347       }
00348       /* fall-through */
00349 
00350     case FT_LZW_PHASE_STACK:
00351       {
00352         while ( state->stack_top > 0 )
00353         {
00354           --state->stack_top;
00355 
00356           if ( buffer )
00357             buffer[result] = state->stack[state->stack_top];
00358 
00359           if ( ++result == out_size )
00360             goto Exit;
00361         }
00362 
00363         /* now create new entry */
00364         if ( state->free_ent < state->max_free )
00365         {
00366           if ( state->free_ent >= state->prefix_size &&
00367                ft_lzwstate_prefix_grow( state ) < 0  )
00368             goto Eof;
00369 
00370           FT_ASSERT( state->free_ent < state->prefix_size );
00371 
00372           state->prefix[state->free_ent] = (FT_UShort)old_code;
00373           state->suffix[state->free_ent] = (FT_Byte)  old_char;
00374 
00375           state->free_ent += 1;
00376         }
00377 
00378         old_code = in_code;
00379 
00380         state->phase = FT_LZW_PHASE_CODE;
00381         goto NextCode;
00382       }
00383 
00384     default:  /* state == EOF */
00385       ;
00386     }
00387 
00388   Exit:
00389     state->old_code = old_code;
00390     state->old_char = old_char;
00391     state->in_code  = in_code;
00392 
00393     return result;
00394 
00395   Eof:
00396     state->phase = FT_LZW_PHASE_EOF;
00397     goto Exit;
00398   }
00399 
00400 
00401 /* END */

Generated on Sun May 27 2012 04:33:52 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.