Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
ftzopen.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftzopen.c */
4 /* */
5 /* FreeType support for .Z compressed files. */
6 /* */
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 */
9 /* distributions. */
10 /* */
11 /* Copyright 2005-2007, 2009, 2011 by David Turner. */
12 /* */
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. */
18 /* */
19 /***************************************************************************/
20 
21 #include "ftzopen.h"
22 #include FT_INTERNAL_MEMORY_H
23 #include FT_INTERNAL_STREAM_H
24 #include FT_INTERNAL_DEBUG_H
25 
26 
27  static int
28  ft_lzwstate_refill( FT_LzwState state )
29  {
31 
32 
33  if ( state->in_eof )
34  return -1;
35 
36  count = FT_Stream_TryRead( state->source,
37  state->buf_tab,
38  state->num_bits ); /* WHY? */
39 
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 );
45 
46  if ( count == 0 ) /* end of file */
47  return -1;
48 
49  return 0;
50  }
51 
52 
53  static FT_Int32
54  ft_lzwstate_get_code( FT_LzwState state )
55  {
56  FT_UInt num_bits = state->num_bits;
57  FT_Int offset = state->buf_offset;
58  FT_Byte* p;
59  FT_Int result;
60 
61 
62  if ( state->buf_clear ||
63  offset >= state->buf_size ||
64  state->free_ent >= state->free_bits )
65  {
66  if ( state->free_ent >= state->free_bits )
67  {
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;
72  }
73 
74  if ( state->buf_clear )
75  {
76  state->num_bits = num_bits = LZW_INIT_BITS;
77  state->free_bits = (FT_UInt)( ( 1UL << num_bits ) - 256 );
78  state->buf_clear = 0;
79  }
80 
81  if ( ft_lzwstate_refill( state ) < 0 )
82  return -1;
83 
84  offset = 0;
85  }
86 
87  state->buf_offset = offset + num_bits;
88 
89  p = &state->buf_tab[offset >> 3];
90  offset &= 7;
91  result = *p++ >> offset;
92  offset = 8 - offset;
93  num_bits -= offset;
94 
95  if ( num_bits >= 8 )
96  {
97  result |= *p++ << offset;
98  offset += 8;
99  num_bits -= 8;
100  }
101  if ( num_bits > 0 )
102  result |= ( *p & LZW_MASK( num_bits ) ) << offset;
103 
104  return result;
105  }
106 
107 
108  /* grow the character stack */
109  static int
110  ft_lzwstate_stack_grow( FT_LzwState state )
111  {
112  if ( state->stack_top >= state->stack_size )
113  {
114  FT_Memory memory = state->memory;
115  FT_Error error;
116  FT_Offset old_size = state->stack_size;
117  FT_Offset new_size = old_size;
118 
119  new_size = new_size + ( new_size >> 1 ) + 4;
120 
121  if ( state->stack == state->stack_0 )
122  {
123  state->stack = NULL;
124  old_size = 0;
125  }
126 
127  /* requirement of the character stack larger than 1<<LZW_MAX_BITS */
128  /* implies bug in the decompression code */
129  if ( new_size > ( 1 << LZW_MAX_BITS ) )
130  {
131  new_size = 1 << LZW_MAX_BITS;
132  if ( new_size == old_size )
133  return -1;
134  }
135 
136  if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) )
137  return -1;
138 
139  state->stack_size = new_size;
140  }
141  return 0;
142  }
143 
144 
145  /* grow the prefix/suffix arrays */
146  static int
147  ft_lzwstate_prefix_grow( FT_LzwState state )
148  {
149  FT_UInt old_size = state->prefix_size;
150  FT_UInt new_size = old_size;
151  FT_Memory memory = state->memory;
152  FT_Error error;
153 
154 
155  if ( new_size == 0 ) /* first allocation -> 9 bits */
156  new_size = 512;
157  else
158  new_size += new_size >> 2; /* don't grow too fast */
159 
160  /*
161  * Note that the `suffix' array is located in the same memory block
162  * pointed to by `prefix'.
163  *
164  * I know that sizeof(FT_Byte) == 1 by definition, but it is clearer
165  * to write it literally.
166  *
167  */
168  if ( FT_REALLOC_MULT( state->prefix, old_size, new_size,
169  sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) )
170  return -1;
171 
172  /* now adjust `suffix' and move the data accordingly */
173  state->suffix = (FT_Byte*)( state->prefix + new_size );
174 
175  FT_MEM_MOVE( state->suffix,
176  state->prefix + old_size,
177  old_size * sizeof ( FT_Byte ) );
178 
179  state->prefix_size = new_size;
180  return 0;
181  }
182 
183 
184  FT_LOCAL_DEF( void )
186  {
187  state->in_eof = 0;
188  state->buf_offset = 0;
189  state->buf_size = 0;
190  state->buf_clear = 0;
191  state->buf_total = 0;
192  state->stack_top = 0;
193  state->num_bits = LZW_INIT_BITS;
194  state->phase = FT_LZW_PHASE_START;
195  }
196 
197 
198  FT_LOCAL_DEF( void )
200  FT_Stream source )
201  {
202  FT_ZERO( state );
203 
204  state->source = source;
205  state->memory = source->memory;
206 
207  state->prefix = NULL;
208  state->suffix = NULL;
209  state->prefix_size = 0;
210 
211  state->stack = state->stack_0;
212  state->stack_size = sizeof ( state->stack_0 );
213 
214  ft_lzwstate_reset( state );
215  }
216 
217 
218  FT_LOCAL_DEF( void )
220  {
221  FT_Memory memory = state->memory;
222 
223 
224  ft_lzwstate_reset( state );
225 
226  if ( state->stack != state->stack_0 )
227  FT_FREE( state->stack );
228 
229  FT_FREE( state->prefix );
230  state->suffix = NULL;
231 
232  FT_ZERO( state );
233  }
234 
235 
236 #define FTLZW_STACK_PUSH( c ) \
237  FT_BEGIN_STMNT \
238  if ( state->stack_top >= state->stack_size && \
239  ft_lzwstate_stack_grow( state ) < 0 ) \
240  goto Eof; \
241  \
242  state->stack[state->stack_top++] = (FT_Byte)(c); \
243  FT_END_STMNT
244 
245 
248  FT_Byte* buffer,
249  FT_ULong out_size )
250  {
251  FT_ULong result = 0;
252 
253  FT_UInt old_char = state->old_char;
254  FT_UInt old_code = state->old_code;
255  FT_UInt in_code = state->in_code;
256 
257 
258  if ( out_size == 0 )
259  goto Exit;
260 
261  switch ( state->phase )
262  {
263  case FT_LZW_PHASE_START:
264  {
265  FT_Byte max_bits;
266  FT_Int32 c;
267 
268 
269  /* skip magic bytes, and read max_bits + block_flag */
270  if ( FT_Stream_Seek( state->source, 2 ) != 0 ||
271  FT_Stream_TryRead( state->source, &max_bits, 1 ) != 1 )
272  goto Eof;
273 
274  state->max_bits = max_bits & LZW_BIT_MASK;
275  state->block_mode = max_bits & LZW_BLOCK_MASK;
276  state->max_free = (FT_UInt)( ( 1UL << state->max_bits ) - 256 );
277 
278  if ( state->max_bits > LZW_MAX_BITS )
279  goto Eof;
280 
281  state->num_bits = LZW_INIT_BITS;
282  state->free_ent = ( state->block_mode ? LZW_FIRST
283  : LZW_CLEAR ) - 256;
284  in_code = 0;
285 
286  state->free_bits = state->num_bits < state->max_bits
287  ? (FT_UInt)( ( 1UL << state->num_bits ) - 256 )
288  : state->max_free + 1;
289 
290  c = ft_lzwstate_get_code( state );
291  if ( c < 0 || c > 255 )
292  goto Eof;
293 
294  old_code = old_char = (FT_UInt)c;
295 
296  if ( buffer )
297  buffer[result] = (FT_Byte)old_char;
298 
299  if ( ++result >= out_size )
300  goto Exit;
301 
302  state->phase = FT_LZW_PHASE_CODE;
303  }
304  /* fall-through */
305 
306  case FT_LZW_PHASE_CODE:
307  {
308  FT_Int32 c;
309  FT_UInt code;
310 
311 
312  NextCode:
313  c = ft_lzwstate_get_code( state );
314  if ( c < 0 )
315  goto Eof;
316 
317  code = (FT_UInt)c;
318 
319  if ( code == LZW_CLEAR && state->block_mode )
320  {
321  /* why not LZW_FIRST-256 ? */
322  state->free_ent = ( LZW_FIRST - 1 ) - 256;
323  state->buf_clear = 1;
324 
325  /* not quite right, but at least more predictable */
326  old_code = 0;
327  old_char = 0;
328 
329  goto NextCode;
330  }
331 
332  in_code = code; /* save code for later */
333 
334  if ( code >= 256U )
335  {
336  /* special case for KwKwKwK */
337  if ( code - 256U >= state->free_ent )
338  {
339  /* corrupted LZW stream */
340  if ( code - 256U > state->free_ent )
341  goto Eof;
342 
343  FTLZW_STACK_PUSH( old_char );
344  code = old_code;
345  }
346 
347  while ( code >= 256U )
348  {
349  if ( !state->prefix )
350  goto Eof;
351 
352  FTLZW_STACK_PUSH( state->suffix[code - 256] );
353  code = state->prefix[code - 256];
354  }
355  }
356 
357  old_char = code;
358  FTLZW_STACK_PUSH( old_char );
359 
360  state->phase = FT_LZW_PHASE_STACK;
361  }
362  /* fall-through */
363 
364  case FT_LZW_PHASE_STACK:
365  {
366  while ( state->stack_top > 0 )
367  {
368  --state->stack_top;
369 
370  if ( buffer )
371  buffer[result] = state->stack[state->stack_top];
372 
373  if ( ++result == out_size )
374  goto Exit;
375  }
376 
377  /* now create new entry */
378  if ( state->free_ent < state->max_free )
379  {
380  if ( state->free_ent >= state->prefix_size &&
381  ft_lzwstate_prefix_grow( state ) < 0 )
382  goto Eof;
383 
384  FT_ASSERT( state->free_ent < state->prefix_size );
385 
386  state->prefix[state->free_ent] = (FT_UShort)old_code;
387  state->suffix[state->free_ent] = (FT_Byte) old_char;
388 
389  state->free_ent += 1;
390  }
391 
392  old_code = in_code;
393 
394  state->phase = FT_LZW_PHASE_CODE;
395  goto NextCode;
396  }
397 
398  default: /* state == EOF */
399  ;
400  }
401 
402  Exit:
403  state->old_code = old_code;
404  state->old_char = old_char;
405  state->in_code = in_code;
406 
407  return result;
408 
409  Eof:
410  state->phase = FT_LZW_PHASE_EOF;
411  goto Exit;
412  }
413 
414 
415 /* END */
FT_Stream source
Definition: ftzopen.h:143
#define LZW_CLEAR
Definition: ftzopen.h:41
#define LZW_BLOCK_MASK
Definition: ftzopen.h:45
int FT_Error
Definition: fttypes.h:296
FT_Stream_Seek(FT_Stream stream, FT_ULong pos)
Definition: ftstream.c:57
unsigned long FT_ULong
Definition: fttypes.h:249
FT_Byte * stack
Definition: ftzopen.h:138
GLfloat GLfloat p
#define NextCode(_tif, _sp, _bp, _code, _get)
Definition: tif_lzw.c:176
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
sizeof(AF_ModuleRec)
FT_Stream_TryRead(FT_Stream stream, FT_Byte *buffer, FT_ULong count)
Definition: ftstream.c:164
GLsizei GLsizei GLchar * source
ft_lzwstate_reset(FT_LzwState state)
Definition: ftzopen.c:185
FT_UInt max_bits
Definition: ftzopen.h:123
FT_UInt num_bits
Definition: ftzopen.h:127
#define FTLZW_STACK_PUSH(c)
Definition: ftzopen.c:236
#define LZW_INIT_BITS
Definition: ftzopen.h:38
unsigned char FT_Byte
Definition: fttypes.h:150
FT_Int buf_size
Definition: ftzopen.h:119
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
FT_Byte * suffix
Definition: ftzopen.h:135
FT_Int in_eof
Definition: ftzopen.h:115
#define FT_FREE(ptr)
Definition: ftmemory.h:286
#define LZW_MAX_BITS
Definition: ftzopen.h:39
FT_Offset stack_size
Definition: ftzopen.h:140
FT_UInt free_ent
Definition: ftzopen.h:128
FT_Bool buf_clear
Definition: ftzopen.h:120
FT_Error error
Definition: cffdrivr.c:411
FT_UShort * prefix
Definition: ftzopen.h:134
#define FT_ZERO(p)
Definition: ftmemory.h:210
GLuint buffer
const GLubyte * c
signed int FT_Int32
Definition: ftconfig.h:132
FT_UInt prefix_size
Definition: ftzopen.h:136
FT_Byte stack_0[FT_LZW_DEFAULT_STACK_SIZE]
Definition: ftzopen.h:141
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:293
FT_UInt max_free
Definition: ftzopen.h:125
GLintptr offset
#define LZW_FIRST
Definition: ftzopen.h:42
ft_lzwstate_done(FT_LzwState state)
Definition: ftzopen.c:219
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define FT_BOOL(x)
Definition: fttypes.h:574
FT_Memory memory
Definition: ftzopen.h:144
GLuint64EXT * result
unsigned int FT_UInt
Definition: fttypes.h:227
ft_lzwstate_init(FT_LzwState state, FT_Stream source)
Definition: ftzopen.c:199
FT_UInt free_bits
Definition: ftzopen.h:129
#define LZW_BIT_MASK
Definition: ftzopen.h:44
GLuint GLuint GLsizei count
#define FT_REALLOC_MULT(ptr, oldcnt, newcnt, itmsz)
Definition: ftmemory.h:269
local int * code
Definition: enough.c:174
#define LZW_MASK(n)
Definition: ftzopen.h:46
unsigned short FT_UShort
Definition: fttypes.h:205
#define FT_MEM_MOVE(dest, source, count)
Definition: ftmemory.h:205
FT_Int buf_offset
Definition: ftzopen.h:118
FT_Byte buf_tab[16]
Definition: ftzopen.h:117
FT_Offset buf_total
Definition: ftzopen.h:121
ft_lzwstate_io(FT_LzwState state, FT_Byte *buffer, FT_ULong out_size)
Definition: ftzopen.c:247
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
FT_UInt stack_top
Definition: ftzopen.h:139
size_t FT_Offset
Definition: fttypes.h:320