28#include FT_CONFIG_STANDARD_LIBRARY_H
36#define FT_ERR_PREFIX LZW_Err_
37#define FT_ERR_BASE FT_Mod_Err_LZW
42#ifdef FT_CONFIG_OPTION_USE_LZW
63#define FT_LZW_BUFFER_SIZE 4096
65 typedef struct FT_LZWFileRec_
72 FT_Byte buffer[FT_LZW_BUFFER_SIZE];
77 } FT_LZWFileRec, *FT_LZWFile;
82 ft_lzw_check_header( FT_Stream stream )
88 if ( FT_STREAM_SEEK( 0 ) ||
89 FT_STREAM_READ( head, 2 ) )
93 if ( head[0] != 0x1F ||
95 error = FT_THROW( Invalid_File_Format );
103 ft_lzw_file_init( FT_LZWFile zip,
107 FT_LzwState lzw = &zip->lzw;
111 zip->stream = stream;
112 zip->source = source;
113 zip->memory = stream->memory;
115 zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE;
116 zip->cursor = zip->limit;
120 error = ft_lzw_check_header( source );
125 ft_lzwstate_init( lzw, source );
133 ft_lzw_file_done( FT_LZWFile zip )
136 ft_lzwstate_done( &zip->lzw );
145 ft_lzw_file_reset( FT_LZWFile zip )
147 FT_Stream stream = zip->source;
151 if ( !FT_STREAM_SEEK( 0 ) )
153 ft_lzwstate_reset( &zip->lzw );
155 zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE;
156 zip->cursor = zip->limit;
165 ft_lzw_file_fill_output( FT_LZWFile zip )
167 FT_LzwState lzw = &zip->lzw;
169 FT_Error error = FT_Err_Ok;
172 zip->cursor = zip->buffer;
174 count = ft_lzwstate_io( lzw, zip->buffer, FT_LZW_BUFFER_SIZE );
176 zip->limit = zip->cursor + count;
179 error = FT_THROW( Invalid_Stream_Operation );
187 ft_lzw_file_skip_output( FT_LZWFile zip,
190 FT_Error error = FT_Err_Ok;
195 FT_ULong delta = (FT_ULong)( zip->limit - zip->cursor );
198 if ( delta >= count )
201 zip->cursor += delta;
210 FT_ULong delta = FT_LZW_BUFFER_SIZE;
217 numread = ft_lzwstate_io( &zip->lzw, NULL, delta );
218 if ( numread < delta )
221 error = FT_THROW( Invalid_Stream_Operation );
234 ft_lzw_file_io( FT_LZWFile zip,
244 if ( pos < zip->pos )
248 if ( ( zip->pos - pos ) <= (FT_ULong)( zip->cursor - zip->buffer ) )
250 zip->cursor -= zip->pos - pos;
255 error = ft_lzw_file_reset( zip );
262 if ( pos > zip->pos )
264 error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );
278 delta = (FT_ULong)( zip->limit - zip->cursor );
279 if ( delta >= count )
282 FT_MEM_COPY( buffer + result, zip->cursor, delta );
284 zip->cursor += delta;
291 error = ft_lzw_file_fill_output( zip );
310 ft_lzw_stream_close( FT_Stream stream )
312 FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer;
313 FT_Memory memory = stream->memory;
319 ft_lzw_file_done( zip );
323 stream->descriptor.pointer = NULL;
329 ft_lzw_stream_io( FT_Stream stream,
330 unsigned long offset,
331 unsigned char* buffer,
332 unsigned long count )
334 FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer;
337 return ft_lzw_file_io( zip, offset, buffer, count );
341 FT_EXPORT_DEF( FT_Error )
342 FT_Stream_OpenLZW( FT_Stream stream,
347 FT_LZWFile zip = NULL;
350 if ( !stream || !source )
352 error = FT_THROW( Invalid_Stream_Handle );
356 memory = source->memory;
365 error = ft_lzw_check_header( source );
370 stream->memory = memory;
372 if ( !FT_QNEW( zip ) )
374 error = ft_lzw_file_init( zip, stream, source );
381 stream->descriptor.pointer = zip;
384 stream->size = 0x7FFFFFFFL;
387 stream->read = ft_lzw_stream_io;
388 stream->close = ft_lzw_stream_close;
401 FT_EXPORT_DEF( FT_Error )
402 FT_Stream_OpenLZW( FT_Stream stream,
408 return FT_THROW( Unimplemented_Feature );