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

ftlzw.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftlzw.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 2004, 2005, 2006, 2009, 2010 by                              */
00012 /*  Albert Chin-A-Young.                                                   */
00013 /*                                                                         */
00014 /*  Based on code in src/gzip/ftgzip.c, Copyright 2004 by                  */
00015 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00016 /*                                                                         */
00017 /*  This file is part of the FreeType project, and may only be used,       */
00018 /*  modified, and distributed under the terms of the FreeType project      */
00019 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00020 /*  this file you indicate that you have read the license and              */
00021 /*  understand and accept it fully.                                        */
00022 /*                                                                         */
00023 /***************************************************************************/
00024 
00025 #include <ft2build.h>
00026 #include FT_INTERNAL_MEMORY_H
00027 #include FT_INTERNAL_STREAM_H
00028 #include FT_INTERNAL_DEBUG_H
00029 #include FT_LZW_H
00030 #include FT_CONFIG_STANDARD_LIBRARY_H
00031 
00032 
00033 #include FT_MODULE_ERRORS_H
00034 
00035 #undef __FTERRORS_H__
00036 
00037 #define FT_ERR_PREFIX  LZW_Err_
00038 #define FT_ERR_BASE    FT_Mod_Err_LZW
00039 
00040 #include FT_ERRORS_H
00041 
00042 
00043 #ifdef FT_CONFIG_OPTION_USE_LZW
00044 
00045 #ifdef FT_CONFIG_OPTION_PIC
00046 #error "lzw code does not support PIC yet"
00047 #endif 
00048 
00049 #include "ftzopen.h"
00050 
00051 
00052 /***************************************************************************/
00053 /***************************************************************************/
00054 /*****                                                                 *****/
00055 /*****                  M E M O R Y   M A N A G E M E N T              *****/
00056 /*****                                                                 *****/
00057 /***************************************************************************/
00058 /***************************************************************************/
00059 
00060 /***************************************************************************/
00061 /***************************************************************************/
00062 /*****                                                                 *****/
00063 /*****                   F I L E   D E S C R I P T O R                 *****/
00064 /*****                                                                 *****/
00065 /***************************************************************************/
00066 /***************************************************************************/
00067 
00068 #define FT_LZW_BUFFER_SIZE  4096
00069 
00070   typedef struct  FT_LZWFileRec_
00071   {
00072     FT_Stream       source;         /* parent/source stream        */
00073     FT_Stream       stream;         /* embedding stream            */
00074     FT_Memory       memory;         /* memory allocator            */
00075     FT_LzwStateRec  lzw;            /* lzw decompressor state      */
00076 
00077     FT_Byte         buffer[FT_LZW_BUFFER_SIZE]; /* output buffer      */
00078     FT_ULong        pos;                        /* position in output */
00079     FT_Byte*        cursor;
00080     FT_Byte*        limit;
00081 
00082   } FT_LZWFileRec, *FT_LZWFile;
00083 
00084 
00085   /* check and skip .Z header */
00086   static FT_Error
00087   ft_lzw_check_header( FT_Stream  stream )
00088   {
00089     FT_Error  error;
00090     FT_Byte   head[2];
00091 
00092 
00093     if ( FT_STREAM_SEEK( 0 )       ||
00094          FT_STREAM_READ( head, 2 ) )
00095       goto Exit;
00096 
00097     /* head[0] && head[1] are the magic numbers */
00098     if ( head[0] != 0x1f ||
00099          head[1] != 0x9d )
00100       error = LZW_Err_Invalid_File_Format;
00101 
00102   Exit:
00103     return error;
00104   }
00105 
00106 
00107   static FT_Error
00108   ft_lzw_file_init( FT_LZWFile  zip,
00109                     FT_Stream   stream,
00110                     FT_Stream   source )
00111   {
00112     FT_LzwState  lzw   = &zip->lzw;
00113     FT_Error     error = LZW_Err_Ok;
00114 
00115 
00116     zip->stream = stream;
00117     zip->source = source;
00118     zip->memory = stream->memory;
00119 
00120     zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;
00121     zip->cursor = zip->limit;
00122     zip->pos    = 0;
00123 
00124     /* check and skip .Z header */
00125     error = ft_lzw_check_header( source );
00126     if ( error )
00127       goto Exit;
00128 
00129     /* initialize internal lzw variable */
00130     ft_lzwstate_init( lzw, source );
00131 
00132   Exit:
00133     return error;
00134   }
00135 
00136 
00137   static void
00138   ft_lzw_file_done( FT_LZWFile  zip )
00139   {
00140     /* clear the rest */
00141     ft_lzwstate_done( &zip->lzw );
00142 
00143     zip->memory = NULL;
00144     zip->source = NULL;
00145     zip->stream = NULL;
00146   }
00147 
00148 
00149   static FT_Error
00150   ft_lzw_file_reset( FT_LZWFile  zip )
00151   {
00152     FT_Stream  stream = zip->source;
00153     FT_Error   error;
00154 
00155 
00156     if ( !FT_STREAM_SEEK( 0 ) )
00157     {
00158       ft_lzwstate_reset( &zip->lzw );
00159 
00160       zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;
00161       zip->cursor = zip->limit;
00162       zip->pos    = 0;
00163     }
00164 
00165     return error;
00166   }
00167 
00168 
00169   static FT_Error
00170   ft_lzw_file_fill_output( FT_LZWFile  zip )
00171   {
00172     FT_LzwState  lzw = &zip->lzw;
00173     FT_ULong     count;
00174     FT_Error     error = LZW_Err_Ok;
00175 
00176 
00177     zip->cursor = zip->buffer;
00178 
00179     count = ft_lzwstate_io( lzw, zip->buffer, FT_LZW_BUFFER_SIZE );
00180 
00181     zip->limit = zip->cursor + count;
00182 
00183     if ( count == 0 )
00184       error = LZW_Err_Invalid_Stream_Operation;
00185 
00186     return error;
00187   }
00188 
00189 
00190   /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */
00191   static FT_Error
00192   ft_lzw_file_skip_output( FT_LZWFile  zip,
00193                            FT_ULong    count )
00194   {
00195     FT_Error  error = LZW_Err_Ok;
00196 
00197 
00198     /* first, we skip what we can from the output buffer */
00199     {
00200       FT_ULong  delta = (FT_ULong)( zip->limit - zip->cursor );
00201 
00202 
00203       if ( delta >= count )
00204         delta = count;
00205 
00206       zip->cursor += delta;
00207       zip->pos    += delta;
00208 
00209       count -= delta;
00210     }
00211 
00212     /* next, we skip as many bytes remaining as possible */
00213     while ( count > 0 )
00214     {
00215       FT_ULong  delta = FT_LZW_BUFFER_SIZE;
00216       FT_ULong  numread;
00217 
00218 
00219       if ( delta > count )
00220         delta = count;
00221 
00222       numread = ft_lzwstate_io( &zip->lzw, NULL, delta );
00223       if ( numread < delta )
00224       {
00225         /* not enough bytes */
00226         error = LZW_Err_Invalid_Stream_Operation;
00227         break;
00228       }
00229 
00230       zip->pos += delta;
00231       count    -= delta;
00232     }
00233 
00234     return error;
00235   }
00236 
00237 
00238   static FT_ULong
00239   ft_lzw_file_io( FT_LZWFile  zip,
00240                   FT_ULong    pos,
00241                   FT_Byte*    buffer,
00242                   FT_ULong    count )
00243   {
00244     FT_ULong  result = 0;
00245     FT_Error  error;
00246 
00247 
00248     /* seeking backwards. */
00249     if ( pos < zip->pos )
00250     {
00251       /* If the new position is within the output buffer, simply       */
00252       /* decrement pointers, otherwise we reset the stream completely! */
00253       if ( ( zip->pos - pos ) <= (FT_ULong)( zip->cursor - zip->buffer ) )
00254       {
00255         zip->cursor -= zip->pos - pos;
00256         zip->pos     = pos;
00257       }
00258       else
00259       {
00260         error = ft_lzw_file_reset( zip );
00261         if ( error )
00262           goto Exit;
00263       }
00264     }
00265 
00266     /* skip unwanted bytes */
00267     if ( pos > zip->pos )
00268     {
00269       error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );
00270       if ( error )
00271         goto Exit;
00272     }
00273 
00274     if ( count == 0 )
00275       goto Exit;
00276 
00277     /* now read the data */
00278     for (;;)
00279     {
00280       FT_ULong  delta;
00281 
00282 
00283       delta = (FT_ULong)( zip->limit - zip->cursor );
00284       if ( delta >= count )
00285         delta = count;
00286 
00287       FT_MEM_COPY( buffer + result, zip->cursor, delta );
00288       result      += delta;
00289       zip->cursor += delta;
00290       zip->pos    += delta;
00291 
00292       count -= delta;
00293       if ( count == 0 )
00294         break;
00295 
00296       error = ft_lzw_file_fill_output( zip );
00297       if ( error )
00298         break;
00299     }
00300 
00301   Exit:
00302     return result;
00303   }
00304 
00305 
00306 /***************************************************************************/
00307 /***************************************************************************/
00308 /*****                                                                 *****/
00309 /*****            L Z W   E M B E D D I N G   S T R E A M              *****/
00310 /*****                                                                 *****/
00311 /***************************************************************************/
00312 /***************************************************************************/
00313 
00314   static void
00315   ft_lzw_stream_close( FT_Stream  stream )
00316   {
00317     FT_LZWFile  zip    = (FT_LZWFile)stream->descriptor.pointer;
00318     FT_Memory   memory = stream->memory;
00319 
00320 
00321     if ( zip )
00322     {
00323       /* finalize lzw file descriptor */
00324       ft_lzw_file_done( zip );
00325 
00326       FT_FREE( zip );
00327 
00328       stream->descriptor.pointer = NULL;
00329     }
00330   }
00331 
00332 
00333   static FT_ULong
00334   ft_lzw_stream_io( FT_Stream  stream,
00335                     FT_ULong   pos,
00336                     FT_Byte*   buffer,
00337                     FT_ULong   count )
00338   {
00339     FT_LZWFile  zip = (FT_LZWFile)stream->descriptor.pointer;
00340 
00341 
00342     return ft_lzw_file_io( zip, pos, buffer, count );
00343   }
00344 
00345 
00346   FT_EXPORT_DEF( FT_Error )
00347   FT_Stream_OpenLZW( FT_Stream  stream,
00348                      FT_Stream  source )
00349   {
00350     FT_Error    error;
00351     FT_Memory   memory = source->memory;
00352     FT_LZWFile  zip;
00353 
00354 
00355     /*
00356      *  Check the header right now; this prevents allocation of a huge
00357      *  LZWFile object (400 KByte of heap memory) if not necessary.
00358      *
00359      *  Did I mention that you should never use .Z compressed font
00360      *  files?
00361      */
00362     error = ft_lzw_check_header( source );
00363     if ( error )
00364       goto Exit;
00365 
00366     FT_ZERO( stream );
00367     stream->memory = memory;
00368 
00369     if ( !FT_NEW( zip ) )
00370     {
00371       error = ft_lzw_file_init( zip, stream, source );
00372       if ( error )
00373       {
00374         FT_FREE( zip );
00375         goto Exit;
00376       }
00377 
00378       stream->descriptor.pointer = zip;
00379     }
00380 
00381     stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */
00382     stream->pos   = 0;
00383     stream->base  = 0;
00384     stream->read  = ft_lzw_stream_io;
00385     stream->close = ft_lzw_stream_close;
00386 
00387   Exit:
00388     return error;
00389   }
00390 
00391 
00392 #include "ftzopen.c"
00393 
00394 
00395 #else  /* !FT_CONFIG_OPTION_USE_LZW */
00396 
00397 
00398   FT_EXPORT_DEF( FT_Error )
00399   FT_Stream_OpenLZW( FT_Stream  stream,
00400                      FT_Stream  source )
00401   {
00402     FT_UNUSED( stream );
00403     FT_UNUSED( source );
00404 
00405     return LZW_Err_Unimplemented_Feature;
00406   }
00407 
00408 
00409 #endif /* !FT_CONFIG_OPTION_USE_LZW */
00410 
00411 
00412 /* 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.