1 /***************************************************************************/
5 /* FreeType support for .Z compressed files. */
7 /* This optional component relies on NetBSD's zopen(). It should mainly */
8 /* be used to parse compressed PCF fonts, as found with many X11 server */
11 /* Copyright 2005, 2006, 2007, 2009 by David Turner. */
13 /* This file is part of the FreeType project, and may only be used, */
14 /* modified, and distributed under the terms of the FreeType project */
15 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
16 /* this file you indicate that you have read the license and */
17 /* understand and accept it fully. */
19 /***************************************************************************/
22 #include FT_INTERNAL_MEMORY_H
23 #include FT_INTERNAL_STREAM_H
24 #include FT_INTERNAL_DEBUG_H
28 ft_lzwstate_refill( FT_LzwState state
)
36 count
= FT_Stream_TryRead( state
->source
,
38 state
->num_bits
); /* WHY? */
40 state
->buf_size
= (FT_UInt
)count
;
41 state
->buf_total
+= count
;
42 state
->in_eof
= FT_BOOL( count
< state
->num_bits
);
43 state
->buf_offset
= 0;
44 state
->buf_size
= ( state
->buf_size
<< 3 ) - ( state
->num_bits
- 1 );
46 if ( count
== 0 ) /* end of file */
54 ft_lzwstate_get_code( FT_LzwState state
)
56 FT_UInt num_bits
= state
->num_bits
;
57 FT_Int offset
= state
->buf_offset
;
62 if ( state
->buf_clear
||
63 offset
>= state
->buf_size
||
64 state
->free_ent
>= state
->free_bits
)
66 if ( state
->free_ent
>= state
->free_bits
)
68 state
->num_bits
= ++num_bits
;
69 state
->free_bits
= state
->num_bits
< state
->max_bits
70 ? (FT_UInt
)( ( 1UL << num_bits
) - 256 )
71 : state
->max_free
+ 1;
74 if ( state
->buf_clear
)
76 state
->num_bits
= num_bits
= LZW_INIT_BITS
;
77 state
->free_bits
= (FT_UInt
)( ( 1UL << num_bits
) - 256 );
81 if ( ft_lzwstate_refill( state
) < 0 )
87 state
->buf_offset
= offset
+ num_bits
;
89 p
= &state
->buf_tab
[offset
>> 3];
91 result
= *p
++ >> offset
;
97 result
|= *p
++ << offset
;
102 result
|= ( *p
& LZW_MASK( num_bits
) ) << offset
;
108 /* grow the character stack */
110 ft_lzwstate_stack_grow( FT_LzwState state
)
112 if ( state
->stack_top
>= state
->stack_size
)
114 FT_Memory memory
= state
->memory
;
116 FT_Offset old_size
= state
->stack_size
;
117 FT_Offset new_size
= old_size
;
119 new_size
= new_size
+ ( new_size
>> 1 ) + 4;
121 if ( state
->stack
== state
->stack_0
)
127 if ( FT_RENEW_ARRAY( state
->stack
, old_size
, new_size
) )
130 state
->stack_size
= new_size
;
136 /* grow the prefix/suffix arrays */
138 ft_lzwstate_prefix_grow( FT_LzwState state
)
140 FT_UInt old_size
= state
->prefix_size
;
141 FT_UInt new_size
= old_size
;
142 FT_Memory memory
= state
->memory
;
146 if ( new_size
== 0 ) /* first allocation -> 9 bits */
149 new_size
+= new_size
>> 2; /* don't grow too fast */
152 * Note that the `suffix' array is located in the same memory block
153 * pointed to by `prefix'.
155 * I know that sizeof(FT_Byte) == 1 by definition, but it is clearer
156 * to write it literally.
159 if ( FT_REALLOC_MULT( state
->prefix
, old_size
, new_size
,
160 sizeof ( FT_UShort
) + sizeof ( FT_Byte
) ) )
163 /* now adjust `suffix' and move the data accordingly */
164 state
->suffix
= (FT_Byte
*)( state
->prefix
+ new_size
);
166 FT_MEM_MOVE( state
->suffix
,
167 state
->prefix
+ old_size
,
168 old_size
* sizeof ( FT_Byte
) );
170 state
->prefix_size
= new_size
;
176 ft_lzwstate_reset( FT_LzwState state
)
179 state
->buf_offset
= 0;
181 state
->buf_clear
= 0;
182 state
->buf_total
= 0;
183 state
->stack_top
= 0;
184 state
->num_bits
= LZW_INIT_BITS
;
185 state
->phase
= FT_LZW_PHASE_START
;
190 ft_lzwstate_init( FT_LzwState state
,
195 state
->source
= source
;
196 state
->memory
= source
->memory
;
198 state
->prefix
= NULL
;
199 state
->suffix
= NULL
;
200 state
->prefix_size
= 0;
202 state
->stack
= state
->stack_0
;
203 state
->stack_size
= sizeof ( state
->stack_0
);
205 ft_lzwstate_reset( state
);
210 ft_lzwstate_done( FT_LzwState state
)
212 FT_Memory memory
= state
->memory
;
215 ft_lzwstate_reset( state
);
217 if ( state
->stack
!= state
->stack_0
)
218 FT_FREE( state
->stack
);
220 FT_FREE( state
->prefix
);
221 state
->suffix
= NULL
;
227 #define FTLZW_STACK_PUSH( c ) \
229 if ( state->stack_top >= state->stack_size && \
230 ft_lzwstate_stack_grow( state ) < 0 ) \
233 state->stack[state->stack_top++] = (FT_Byte)(c); \
237 FT_LOCAL_DEF( FT_ULong
)
238 ft_lzwstate_io( FT_LzwState state
,
244 FT_UInt old_char
= state
->old_char
;
245 FT_UInt old_code
= state
->old_code
;
246 FT_UInt in_code
= state
->in_code
;
252 switch ( state
->phase
)
254 case FT_LZW_PHASE_START
:
260 /* skip magic bytes, and read max_bits + block_flag */
261 if ( FT_Stream_Seek( state
->source
, 2 ) != 0 ||
262 FT_Stream_TryRead( state
->source
, &max_bits
, 1 ) != 1 )
265 state
->max_bits
= max_bits
& LZW_BIT_MASK
;
266 state
->block_mode
= max_bits
& LZW_BLOCK_MASK
;
267 state
->max_free
= (FT_UInt
)( ( 1UL << state
->max_bits
) - 256 );
269 if ( state
->max_bits
> LZW_MAX_BITS
)
272 state
->num_bits
= LZW_INIT_BITS
;
273 state
->free_ent
= ( state
->block_mode
? LZW_FIRST
277 state
->free_bits
= state
->num_bits
< state
->max_bits
278 ? (FT_UInt
)( ( 1UL << state
->num_bits
) - 256 )
279 : state
->max_free
+ 1;
281 c
= ft_lzwstate_get_code( state
);
285 old_code
= old_char
= (FT_UInt
)c
;
288 buffer
[result
] = (FT_Byte
)old_char
;
290 if ( ++result
>= out_size
)
293 state
->phase
= FT_LZW_PHASE_CODE
;
297 case FT_LZW_PHASE_CODE
:
304 c
= ft_lzwstate_get_code( state
);
310 if ( code
== LZW_CLEAR
&& state
->block_mode
)
312 /* why not LZW_FIRST-256 ? */
313 state
->free_ent
= ( LZW_FIRST
- 1 ) - 256;
314 state
->buf_clear
= 1;
315 c
= ft_lzwstate_get_code( state
);
322 in_code
= code
; /* save code for later */
326 /* special case for KwKwKwK */
327 if ( code
- 256U >= state
->free_ent
)
329 FTLZW_STACK_PUSH( old_char
);
333 while ( code
>= 256U )
335 if ( !state
->prefix
)
338 FTLZW_STACK_PUSH( state
->suffix
[code
- 256] );
339 code
= state
->prefix
[code
- 256];
344 FTLZW_STACK_PUSH( old_char
);
346 state
->phase
= FT_LZW_PHASE_STACK
;
350 case FT_LZW_PHASE_STACK
:
352 while ( state
->stack_top
> 0 )
357 buffer
[result
] = state
->stack
[state
->stack_top
];
359 if ( ++result
== out_size
)
363 /* now create new entry */
364 if ( state
->free_ent
< state
->max_free
)
366 if ( state
->free_ent
>= state
->prefix_size
&&
367 ft_lzwstate_prefix_grow( state
) < 0 )
370 FT_ASSERT( state
->free_ent
< state
->prefix_size
);
372 state
->prefix
[state
->free_ent
] = (FT_UShort
)old_code
;
373 state
->suffix
[state
->free_ent
] = (FT_Byte
) old_char
;
375 state
->free_ent
+= 1;
380 state
->phase
= FT_LZW_PHASE_CODE
;
384 default: /* state == EOF */
389 state
->old_code
= old_code
;
390 state
->old_char
= old_char
;
391 state
->in_code
= in_code
;
396 state
->phase
= FT_LZW_PHASE_EOF
;