|
|
|
@ -2,13 +2,13 @@ |
|
|
|
|
/* */ |
|
|
|
|
/* ftgzip.c */ |
|
|
|
|
/* */ |
|
|
|
|
/* FreeType support for .gz compressed fileds */ |
|
|
|
|
/* FreeType support for .gz compressed files. */ |
|
|
|
|
/* */ |
|
|
|
|
/* this optional component relies on zlib. It should mainly be used to */ |
|
|
|
|
/* parse compressed PCF fonts, as found with many X11 server */ |
|
|
|
|
/* distributions. */ |
|
|
|
|
/* */ |
|
|
|
|
/* Copyright 2002 by */ |
|
|
|
|
/* Copyright 2002, 2003 by */ |
|
|
|
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
|
|
|
|
/* */ |
|
|
|
|
/* This file is part of the FreeType project, and may only be used, */ |
|
|
|
@ -19,6 +19,7 @@ |
|
|
|
|
/* */ |
|
|
|
|
/***************************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <ft2build.h> |
|
|
|
|
#include FT_INTERNAL_MEMORY_H |
|
|
|
|
#include FT_INTERNAL_STREAM_H |
|
|
|
@ -29,35 +30,35 @@ |
|
|
|
|
|
|
|
|
|
#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB |
|
|
|
|
|
|
|
|
|
# include <zlib.h> |
|
|
|
|
#include <zlib.h> |
|
|
|
|
|
|
|
|
|
#else /* !SYSTEM_ZLIB */ |
|
|
|
|
#else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ |
|
|
|
|
|
|
|
|
|
/* in this case, we include our own modified sources of the ZLib */ |
|
|
|
|
/* within the "ftgzip" component. The modifications were necessary */ |
|
|
|
|
/* to #include all files without conflicts, as well as preventing */ |
|
|
|
|
/* the definition of "extern" functions that may cause linking */ |
|
|
|
|
/* conflicts when a program is linked with both FreeType and the */ |
|
|
|
|
/* original ZLib */ |
|
|
|
|
/* In this case, we include our own modified sources of the ZLib */ |
|
|
|
|
/* within the "ftgzip" component. The modifications were necessary */ |
|
|
|
|
/* to #include all files without conflicts, as well as preventing */ |
|
|
|
|
/* the definition of "extern" functions that may cause linking */ |
|
|
|
|
/* conflicts when a program is linked with both FreeType and the */ |
|
|
|
|
/* original ZLib. */ |
|
|
|
|
|
|
|
|
|
# define NO_DUMMY_DECL |
|
|
|
|
# define BUILDFIXED /* save code size */ |
|
|
|
|
# define MY_ZCALLOC |
|
|
|
|
#define NO_DUMMY_DECL |
|
|
|
|
#define BUILDFIXED /* save code size */ |
|
|
|
|
#define MY_ZCALLOC |
|
|
|
|
|
|
|
|
|
# include "zlib.h" |
|
|
|
|
#include "zlib.h" |
|
|
|
|
|
|
|
|
|
# undef SLOW |
|
|
|
|
# define SLOW 1 /* we can't use asm-optimized sources here !! */ |
|
|
|
|
#undef SLOW |
|
|
|
|
#define SLOW 1 /* we can't use asm-optimized sources here !! */ |
|
|
|
|
|
|
|
|
|
# include "zutil.c" |
|
|
|
|
# include "inftrees.c" |
|
|
|
|
# include "infcodes.c" |
|
|
|
|
# include "infutil.c" |
|
|
|
|
# include "infblock.c" |
|
|
|
|
# include "inflate.c" |
|
|
|
|
# include "adler32.c" |
|
|
|
|
#include "zutil.c" |
|
|
|
|
#include "inftrees.c" |
|
|
|
|
#include "infcodes.c" |
|
|
|
|
#include "infutil.c" |
|
|
|
|
#include "infblock.c" |
|
|
|
|
#include "inflate.c" |
|
|
|
|
#include "adler32.c" |
|
|
|
|
|
|
|
|
|
#endif /* !SYSTEM_ZLIB */ |
|
|
|
|
#endif /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************/ |
|
|
|
@ -68,48 +69,48 @@ |
|
|
|
|
/***************************************************************************/ |
|
|
|
|
/***************************************************************************/ |
|
|
|
|
|
|
|
|
|
/* it's better to use FreeType memory routines instead of raw 'malloc/free' */ |
|
|
|
|
/* it is better to use FreeType memory routines instead of raw
|
|
|
|
|
'malloc/free' */ |
|
|
|
|
|
|
|
|
|
static voidpf |
|
|
|
|
ft_gzip_alloc( FT_Memory memory, |
|
|
|
|
uInt items, |
|
|
|
|
uInt size ) |
|
|
|
|
{ |
|
|
|
|
FT_ULong sz = (FT_ULong)size * items; |
|
|
|
|
FT_Pointer p; |
|
|
|
|
|
|
|
|
|
static voidpf |
|
|
|
|
ft_gzip_alloc( FT_Memory memory, |
|
|
|
|
uInt items, |
|
|
|
|
uInt size ) |
|
|
|
|
{ |
|
|
|
|
FT_ULong sz = (FT_ULong)size * items; |
|
|
|
|
FT_Pointer p; |
|
|
|
|
|
|
|
|
|
FT_MEM_ALLOC( p, sz ); |
|
|
|
|
FT_MEM_ALLOC( p, sz ); |
|
|
|
|
|
|
|
|
|
return (voidpf) p; |
|
|
|
|
} |
|
|
|
|
return (voidpf) p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
ft_gzip_free( FT_Memory memory, |
|
|
|
|
voidpf address ) |
|
|
|
|
{ |
|
|
|
|
FT_MEM_FREE( address ); |
|
|
|
|
} |
|
|
|
|
static void |
|
|
|
|
ft_gzip_free( FT_Memory memory, |
|
|
|
|
voidpf address ) |
|
|
|
|
{ |
|
|
|
|
FT_MEM_FREE( address ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB |
|
|
|
|
|
|
|
|
|
local voidpf |
|
|
|
|
zcalloc ( /* opaque, items, size) */ |
|
|
|
|
voidpf opaque, |
|
|
|
|
unsigned items, |
|
|
|
|
unsigned size ) |
|
|
|
|
{ |
|
|
|
|
return ft_gzip_alloc( opaque, items, size ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
local void |
|
|
|
|
zcfree( voidpf opaque, |
|
|
|
|
voidpf ptr ) |
|
|
|
|
{ |
|
|
|
|
ft_gzip_free( opaque, ptr ); |
|
|
|
|
} |
|
|
|
|
local voidpf |
|
|
|
|
zcalloc ( voidpf opaque, |
|
|
|
|
unsigned items, |
|
|
|
|
unsigned size ) |
|
|
|
|
{ |
|
|
|
|
return ft_gzip_alloc( opaque, items, size ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
local void |
|
|
|
|
zcfree( voidpf opaque, |
|
|
|
|
voidpf ptr ) |
|
|
|
|
{ |
|
|
|
|
ft_gzip_free( opaque, ptr ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* !SYSTEM_ZLIB */ |
|
|
|
|
|
|
|
|
@ -124,25 +125,25 @@ |
|
|
|
|
|
|
|
|
|
#define FT_GZIP_BUFFER_SIZE 4096 |
|
|
|
|
|
|
|
|
|
typedef struct FT_GZipFileRec_ |
|
|
|
|
typedef struct FT_GZipFileRec_ |
|
|
|
|
{ |
|
|
|
|
FT_Stream source; /* parent/source stream */ |
|
|
|
|
FT_Stream stream; /* embedding stream */ |
|
|
|
|
FT_Memory memory; /* memory allocator */ |
|
|
|
|
z_stream zstream; /* zlib input stream */ |
|
|
|
|
FT_Stream source; /* parent/source stream */ |
|
|
|
|
FT_Stream stream; /* embedding stream */ |
|
|
|
|
FT_Memory memory; /* memory allocator */ |
|
|
|
|
z_stream zstream; /* zlib input stream */ |
|
|
|
|
|
|
|
|
|
FT_ULong start; /* starting position, after .gz header */ |
|
|
|
|
FT_Byte input[ FT_GZIP_BUFFER_SIZE ]; /* input read buffer */ |
|
|
|
|
FT_ULong start; /* starting position, after .gz header */ |
|
|
|
|
FT_Byte input[FT_GZIP_BUFFER_SIZE]; /* input read buffer */ |
|
|
|
|
|
|
|
|
|
FT_Byte buffer[ FT_GZIP_BUFFER_SIZE ]; /* output buffer */ |
|
|
|
|
FT_ULong pos; /* position in output */ |
|
|
|
|
FT_Byte* cursor; |
|
|
|
|
FT_Byte* limit; |
|
|
|
|
FT_Byte buffer[FT_GZIP_BUFFER_SIZE]; /* output buffer */ |
|
|
|
|
FT_ULong pos; /* position in output */ |
|
|
|
|
FT_Byte* cursor; |
|
|
|
|
FT_Byte* limit; |
|
|
|
|
|
|
|
|
|
} FT_GZipFileRec, *FT_GZipFile; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* gzip flag byte */ |
|
|
|
|
/* gzip flag byte */ |
|
|
|
|
#define FT_GZIP_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ |
|
|
|
|
#define FT_GZIP_HEAD_CRC 0x02 /* bit 1 set: header CRC present */ |
|
|
|
|
#define FT_GZIP_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ |
|
|
|
@ -151,18 +152,19 @@ |
|
|
|
|
#define FT_GZIP_RESERVED 0xE0 /* bits 5..7: reserved */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* check and skip .gz header - we don't support "transparent" compression */ |
|
|
|
|
/* check and skip .gz header - we don't support "transparent" compression */ |
|
|
|
|
static FT_Error |
|
|
|
|
ft_gzip_check_header( FT_Stream stream ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_Byte head[4]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( FT_STREAM_SEEK( 0 ) || |
|
|
|
|
FT_STREAM_READ( head, 4 ) ) |
|
|
|
|
goto Exit; |
|
|
|
|
|
|
|
|
|
/* head[0] && head[1] are the magic numbers */ |
|
|
|
|
/* head[0] && head[1] are the magic numbers; */ |
|
|
|
|
/* head[2] is the method, and head[3] the flags */ |
|
|
|
|
if ( head[0] != 0x1f || |
|
|
|
|
head[1] != 0x8b || |
|
|
|
@ -181,6 +183,7 @@ |
|
|
|
|
{ |
|
|
|
|
FT_UInt len; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( FT_READ_USHORT_LE( len ) || |
|
|
|
|
FT_STREAM_SKIP( len ) ) |
|
|
|
|
goto Exit; |
|
|
|
@ -192,7 +195,8 @@ |
|
|
|
|
{ |
|
|
|
|
FT_UInt c; |
|
|
|
|
|
|
|
|
|
if ( FT_READ_BYTE( c) ) |
|
|
|
|
|
|
|
|
|
if ( FT_READ_BYTE( c ) ) |
|
|
|
|
goto Exit; |
|
|
|
|
|
|
|
|
|
if ( c == 0 ) |
|
|
|
@ -205,7 +209,8 @@ |
|
|
|
|
{ |
|
|
|
|
FT_UInt c; |
|
|
|
|
|
|
|
|
|
if ( FT_READ_BYTE( c) ) |
|
|
|
|
|
|
|
|
|
if ( FT_READ_BYTE( c ) ) |
|
|
|
|
goto Exit; |
|
|
|
|
|
|
|
|
|
if ( c == 0 ) |
|
|
|
@ -222,15 +227,15 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static FT_Error |
|
|
|
|
ft_gzip_file_init( FT_GZipFile zip, |
|
|
|
|
FT_Stream stream, |
|
|
|
|
FT_Stream source ) |
|
|
|
|
ft_gzip_file_init( FT_GZipFile zip, |
|
|
|
|
FT_Stream stream, |
|
|
|
|
FT_Stream source ) |
|
|
|
|
{ |
|
|
|
|
z_stream* zstream = &zip->zstream; |
|
|
|
|
FT_Error error = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
zip->stream = stream; |
|
|
|
|
zip->source = source; |
|
|
|
|
zip->memory = stream->memory; |
|
|
|
@ -244,7 +249,7 @@ |
|
|
|
|
stream = source; |
|
|
|
|
|
|
|
|
|
error = ft_gzip_check_header( stream ); |
|
|
|
|
if (error) |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
|
|
|
|
|
zip->start = FT_STREAM_POS(); |
|
|
|
@ -270,7 +275,6 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
ft_gzip_file_done( FT_GZipFile zip ) |
|
|
|
|
{ |
|
|
|
@ -299,10 +303,12 @@ |
|
|
|
|
FT_Stream stream = zip->source; |
|
|
|
|
FT_Error error; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( !FT_STREAM_SEEK( zip->start ) ) |
|
|
|
|
{ |
|
|
|
|
z_stream* zstream = &zip->zstream; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inflateReset( zstream ); |
|
|
|
|
|
|
|
|
|
zstream->avail_in = 0; |
|
|
|
@ -325,9 +331,11 @@ |
|
|
|
|
FT_Stream stream = zip->source; |
|
|
|
|
FT_ULong size; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( stream->read ) |
|
|
|
|
{ |
|
|
|
|
size = stream->read( stream, stream->pos, zip->input, FT_GZIP_BUFFER_SIZE ); |
|
|
|
|
size = stream->read( stream, stream->pos, zip->input, |
|
|
|
|
FT_GZIP_BUFFER_SIZE ); |
|
|
|
|
if ( size == 0 ) |
|
|
|
|
return FT_Err_Invalid_Stream_Operation; |
|
|
|
|
} |
|
|
|
@ -338,7 +346,7 @@ |
|
|
|
|
size = FT_GZIP_BUFFER_SIZE; |
|
|
|
|
|
|
|
|
|
if ( size == 0 ) |
|
|
|
|
return FT_Err_Invalid_Stream_Operation; |
|
|
|
|
return FT_Err_Invalid_Stream_Operation; |
|
|
|
|
|
|
|
|
|
FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); |
|
|
|
|
} |
|
|
|
@ -351,13 +359,13 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static FT_Error |
|
|
|
|
ft_gzip_file_fill_output( FT_GZipFile zip ) |
|
|
|
|
{ |
|
|
|
|
z_stream* zstream = &zip->zstream; |
|
|
|
|
FT_Error error = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
zip->cursor = zip->buffer; |
|
|
|
|
zstream->next_out = zip->cursor; |
|
|
|
|
zstream->avail_out = FT_GZIP_BUFFER_SIZE; |
|
|
|
@ -366,6 +374,7 @@ |
|
|
|
|
{ |
|
|
|
|
int err; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( zstream->avail_in == 0 ) |
|
|
|
|
{ |
|
|
|
|
error = ft_gzip_file_fill_input( zip ); |
|
|
|
@ -391,7 +400,7 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* fill output buffer, 'count' must be <= FT_GZIP_BUFFER_SIZE */ |
|
|
|
|
/* fill output buffer; `count' must be <= FT_GZIP_BUFFER_SIZE */ |
|
|
|
|
static FT_Error |
|
|
|
|
ft_gzip_file_skip_output( FT_GZipFile zip, |
|
|
|
|
FT_ULong count ) |
|
|
|
@ -399,6 +408,7 @@ |
|
|
|
|
FT_Error error = 0; |
|
|
|
|
FT_ULong delta; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) |
|
|
|
|
{ |
|
|
|
|
delta = (FT_ULong)( zip->limit - zip->cursor ); |
|
|
|
@ -422,27 +432,29 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static FT_ULong |
|
|
|
|
ft_gzip_file_io( FT_GZipFile zip, |
|
|
|
|
FT_ULong pos, |
|
|
|
|
FT_Byte* buffer, |
|
|
|
|
FT_ULong count ) |
|
|
|
|
ft_gzip_file_io( FT_GZipFile zip, |
|
|
|
|
FT_ULong pos, |
|
|
|
|
FT_Byte* buffer, |
|
|
|
|
FT_ULong count ) |
|
|
|
|
{ |
|
|
|
|
FT_ULong result = 0; |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_ULong result = 0; |
|
|
|
|
FT_Error error; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reset inflate stream if we're seeking backwards */ |
|
|
|
|
/* yes, that's not too efficient, but it saves memory :-) */ |
|
|
|
|
/* Reset inflate stream if we're seeking backwards. */ |
|
|
|
|
/* Yes, that is not too efficient, but it saves memory :-) */ |
|
|
|
|
if ( pos < zip->pos ) |
|
|
|
|
{ |
|
|
|
|
error = ft_gzip_file_reset( zip ); |
|
|
|
|
if ( error ) goto Exit; |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* skip unwanted bytes */ |
|
|
|
|
if ( pos > zip->pos ) |
|
|
|
|
{ |
|
|
|
|
error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); |
|
|
|
|
if (error) |
|
|
|
|
if ( error ) |
|
|
|
|
goto Exit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -452,7 +464,8 @@ |
|
|
|
|
/* now read the data */ |
|
|
|
|
for (;;) |
|
|
|
|
{ |
|
|
|
|
FT_ULong delta; |
|
|
|
|
FT_ULong delta; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delta = (FT_ULong)( zip->limit - zip->cursor ); |
|
|
|
|
if ( delta >= count ) |
|
|
|
@ -469,7 +482,7 @@ |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
error = ft_gzip_file_fill_output( zip ); |
|
|
|
|
if (error) |
|
|
|
|
if ( error ) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -492,6 +505,7 @@ |
|
|
|
|
FT_GZipFile zip = stream->descriptor.pointer; |
|
|
|
|
FT_Memory memory = stream->memory; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( zip ) |
|
|
|
|
{ |
|
|
|
|
/* finalize gzip file descriptor */ |
|
|
|
@ -505,25 +519,27 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static FT_ULong |
|
|
|
|
ft_gzip_stream_io( FT_Stream stream, |
|
|
|
|
FT_ULong pos, |
|
|
|
|
FT_Byte* buffer, |
|
|
|
|
FT_ULong count ) |
|
|
|
|
ft_gzip_stream_io( FT_Stream stream, |
|
|
|
|
FT_ULong pos, |
|
|
|
|
FT_Byte* buffer, |
|
|
|
|
FT_ULong count ) |
|
|
|
|
{ |
|
|
|
|
FT_GZipFile zip = stream->descriptor.pointer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ft_gzip_file_io( zip, pos, buffer, count ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_EXPORT_DEF( FT_Error ) |
|
|
|
|
FT_Stream_OpenGzip( FT_Stream stream, |
|
|
|
|
FT_Stream source ) |
|
|
|
|
FT_Stream_OpenGzip( FT_Stream stream, |
|
|
|
|
FT_Stream source ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_Memory memory = source->memory; |
|
|
|
|
FT_GZipFile zip; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_ZERO( stream ); |
|
|
|
|
stream->memory = memory; |
|
|
|
|
|
|
|
|
@ -539,7 +555,7 @@ |
|
|
|
|
stream->descriptor.pointer = zip; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
stream->size = 0x7FFFFFFF; /* don't know the real size !! */ |
|
|
|
|
stream->size = 0x7FFFFFFFL; /* don't know the real size! */ |
|
|
|
|
stream->pos = 0; |
|
|
|
|
stream->base = 0; |
|
|
|
|
stream->read = ft_gzip_stream_io; |
|
|
|
@ -552,8 +568,8 @@ |
|
|
|
|
#else /* !FT_CONFIG_OPTION_USE_ZLIB */ |
|
|
|
|
|
|
|
|
|
FT_EXPORT_DEF( FT_Error ) |
|
|
|
|
FT_Stream_OpenGzip( FT_Stream stream, |
|
|
|
|
FT_Stream source ) |
|
|
|
|
FT_Stream_OpenGzip( FT_Stream stream, |
|
|
|
|
FT_Stream source ) |
|
|
|
|
{ |
|
|
|
|
FT_UNUSED( stream ); |
|
|
|
|
FT_UNUSED( source ); |
|
|
|
@ -562,3 +578,6 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* END */ |
|
|
|
|