~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/freetype/src/lzw/ftlzw.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  ftlzw.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 2004, 2005, 2006, 2009, 2010 by                              */
 
12
/*  Albert Chin-A-Young.                                                   */
 
13
/*                                                                         */
 
14
/*  Based on code in src/gzip/ftgzip.c, Copyright 2004 by                  */
 
15
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 
16
/*                                                                         */
 
17
/*  This file is part of the FreeType project, and may only be used,       */
 
18
/*  modified, and distributed under the terms of the FreeType project      */
 
19
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 
20
/*  this file you indicate that you have read the license and              */
 
21
/*  understand and accept it fully.                                        */
 
22
/*                                                                         */
 
23
/***************************************************************************/
 
24
 
 
25
#include <ft2build.h>
 
26
#include FT_INTERNAL_MEMORY_H
 
27
#include FT_INTERNAL_STREAM_H
 
28
#include FT_INTERNAL_DEBUG_H
 
29
#include FT_LZW_H
 
30
#include FT_CONFIG_STANDARD_LIBRARY_H
 
31
 
 
32
 
 
33
#include FT_MODULE_ERRORS_H
 
34
 
 
35
#undef __FTERRORS_H__
 
36
 
 
37
#define FT_ERR_PREFIX  LZW_Err_
 
38
#define FT_ERR_BASE    FT_Mod_Err_LZW
 
39
 
 
40
#include FT_ERRORS_H
 
41
 
 
42
 
 
43
#ifdef FT_CONFIG_OPTION_USE_LZW
 
44
 
 
45
#ifdef FT_CONFIG_OPTION_PIC
 
46
#error "lzw code does not support PIC yet"
 
47
#endif 
 
48
 
 
49
#include "ftzopen.h"
 
50
 
 
51
 
 
52
/***************************************************************************/
 
53
/***************************************************************************/
 
54
/*****                                                                 *****/
 
55
/*****                  M E M O R Y   M A N A G E M E N T              *****/
 
56
/*****                                                                 *****/
 
57
/***************************************************************************/
 
58
/***************************************************************************/
 
59
 
 
60
/***************************************************************************/
 
61
/***************************************************************************/
 
62
/*****                                                                 *****/
 
63
/*****                   F I L E   D E S C R I P T O R                 *****/
 
64
/*****                                                                 *****/
 
65
/***************************************************************************/
 
66
/***************************************************************************/
 
67
 
 
68
#define FT_LZW_BUFFER_SIZE  4096
 
69
 
 
70
  typedef struct  FT_LZWFileRec_
 
71
  {
 
72
    FT_Stream       source;         /* parent/source stream        */
 
73
    FT_Stream       stream;         /* embedding stream            */
 
74
    FT_Memory       memory;         /* memory allocator            */
 
75
    FT_LzwStateRec  lzw;            /* lzw decompressor state      */
 
76
 
 
77
    FT_Byte         buffer[FT_LZW_BUFFER_SIZE]; /* output buffer      */
 
78
    FT_ULong        pos;                        /* position in output */
 
79
    FT_Byte*        cursor;
 
80
    FT_Byte*        limit;
 
81
 
 
82
  } FT_LZWFileRec, *FT_LZWFile;
 
83
 
 
84
 
 
85
  /* check and skip .Z header */
 
86
  static FT_Error
 
87
  ft_lzw_check_header( FT_Stream  stream )
 
88
  {
 
89
    FT_Error  error;
 
90
    FT_Byte   head[2];
 
91
 
 
92
 
 
93
    if ( FT_STREAM_SEEK( 0 )       ||
 
94
         FT_STREAM_READ( head, 2 ) )
 
95
      goto Exit;
 
96
 
 
97
    /* head[0] && head[1] are the magic numbers */
 
98
    if ( head[0] != 0x1f ||
 
99
         head[1] != 0x9d )
 
100
      error = LZW_Err_Invalid_File_Format;
 
101
 
 
102
  Exit:
 
103
    return error;
 
104
  }
 
105
 
 
106
 
 
107
  static FT_Error
 
108
  ft_lzw_file_init( FT_LZWFile  zip,
 
109
                    FT_Stream   stream,
 
110
                    FT_Stream   source )
 
111
  {
 
112
    FT_LzwState  lzw   = &zip->lzw;
 
113
    FT_Error     error = LZW_Err_Ok;
 
114
 
 
115
 
 
116
    zip->stream = stream;
 
117
    zip->source = source;
 
118
    zip->memory = stream->memory;
 
119
 
 
120
    zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;
 
121
    zip->cursor = zip->limit;
 
122
    zip->pos    = 0;
 
123
 
 
124
    /* check and skip .Z header */
 
125
    error = ft_lzw_check_header( source );
 
126
    if ( error )
 
127
      goto Exit;
 
128
 
 
129
    /* initialize internal lzw variable */
 
130
    ft_lzwstate_init( lzw, source );
 
131
 
 
132
  Exit:
 
133
    return error;
 
134
  }
 
135
 
 
136
 
 
137
  static void
 
138
  ft_lzw_file_done( FT_LZWFile  zip )
 
139
  {
 
140
    /* clear the rest */
 
141
    ft_lzwstate_done( &zip->lzw );
 
142
 
 
143
    zip->memory = NULL;
 
144
    zip->source = NULL;
 
145
    zip->stream = NULL;
 
146
  }
 
147
 
 
148
 
 
149
  static FT_Error
 
150
  ft_lzw_file_reset( FT_LZWFile  zip )
 
151
  {
 
152
    FT_Stream  stream = zip->source;
 
153
    FT_Error   error;
 
154
 
 
155
 
 
156
    if ( !FT_STREAM_SEEK( 0 ) )
 
157
    {
 
158
      ft_lzwstate_reset( &zip->lzw );
 
159
 
 
160
      zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;
 
161
      zip->cursor = zip->limit;
 
162
      zip->pos    = 0;
 
163
    }
 
164
 
 
165
    return error;
 
166
  }
 
167
 
 
168
 
 
169
  static FT_Error
 
170
  ft_lzw_file_fill_output( FT_LZWFile  zip )
 
171
  {
 
172
    FT_LzwState  lzw = &zip->lzw;
 
173
    FT_ULong     count;
 
174
    FT_Error     error = LZW_Err_Ok;
 
175
 
 
176
 
 
177
    zip->cursor = zip->buffer;
 
178
 
 
179
    count = ft_lzwstate_io( lzw, zip->buffer, FT_LZW_BUFFER_SIZE );
 
180
 
 
181
    zip->limit = zip->cursor + count;
 
182
 
 
183
    if ( count == 0 )
 
184
      error = LZW_Err_Invalid_Stream_Operation;
 
185
 
 
186
    return error;
 
187
  }
 
188
 
 
189
 
 
190
  /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */
 
191
  static FT_Error
 
192
  ft_lzw_file_skip_output( FT_LZWFile  zip,
 
193
                           FT_ULong    count )
 
194
  {
 
195
    FT_Error  error = LZW_Err_Ok;
 
196
 
 
197
 
 
198
    /* first, we skip what we can from the output buffer */
 
199
    {
 
200
      FT_ULong  delta = (FT_ULong)( zip->limit - zip->cursor );
 
201
 
 
202
 
 
203
      if ( delta >= count )
 
204
        delta = count;
 
205
 
 
206
      zip->cursor += delta;
 
207
      zip->pos    += delta;
 
208
 
 
209
      count -= delta;
 
210
    }
 
211
 
 
212
    /* next, we skip as many bytes remaining as possible */
 
213
    while ( count > 0 )
 
214
    {
 
215
      FT_ULong  delta = FT_LZW_BUFFER_SIZE;
 
216
      FT_ULong  numread;
 
217
 
 
218
 
 
219
      if ( delta > count )
 
220
        delta = count;
 
221
 
 
222
      numread = ft_lzwstate_io( &zip->lzw, NULL, delta );
 
223
      if ( numread < delta )
 
224
      {
 
225
        /* not enough bytes */
 
226
        error = LZW_Err_Invalid_Stream_Operation;
 
227
        break;
 
228
      }
 
229
 
 
230
      zip->pos += delta;
 
231
      count    -= delta;
 
232
    }
 
233
 
 
234
    return error;
 
235
  }
 
236
 
 
237
 
 
238
  static FT_ULong
 
239
  ft_lzw_file_io( FT_LZWFile  zip,
 
240
                  FT_ULong    pos,
 
241
                  FT_Byte*    buffer,
 
242
                  FT_ULong    count )
 
243
  {
 
244
    FT_ULong  result = 0;
 
245
    FT_Error  error;
 
246
 
 
247
 
 
248
    /* seeking backwards. */
 
249
    if ( pos < zip->pos )
 
250
    {
 
251
      /* If the new position is within the output buffer, simply       */
 
252
      /* decrement pointers, otherwise we reset the stream completely! */
 
253
      if ( ( zip->pos - pos ) <= (FT_ULong)( zip->cursor - zip->buffer ) )
 
254
      {
 
255
        zip->cursor -= zip->pos - pos;
 
256
        zip->pos     = pos;
 
257
      }
 
258
      else
 
259
      {
 
260
        error = ft_lzw_file_reset( zip );
 
261
        if ( error )
 
262
          goto Exit;
 
263
      }
 
264
    }
 
265
 
 
266
    /* skip unwanted bytes */
 
267
    if ( pos > zip->pos )
 
268
    {
 
269
      error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );
 
270
      if ( error )
 
271
        goto Exit;
 
272
    }
 
273
 
 
274
    if ( count == 0 )
 
275
      goto Exit;
 
276
 
 
277
    /* now read the data */
 
278
    for (;;)
 
279
    {
 
280
      FT_ULong  delta;
 
281
 
 
282
 
 
283
      delta = (FT_ULong)( zip->limit - zip->cursor );
 
284
      if ( delta >= count )
 
285
        delta = count;
 
286
 
 
287
      FT_MEM_COPY( buffer + result, zip->cursor, delta );
 
288
      result      += delta;
 
289
      zip->cursor += delta;
 
290
      zip->pos    += delta;
 
291
 
 
292
      count -= delta;
 
293
      if ( count == 0 )
 
294
        break;
 
295
 
 
296
      error = ft_lzw_file_fill_output( zip );
 
297
      if ( error )
 
298
        break;
 
299
    }
 
300
 
 
301
  Exit:
 
302
    return result;
 
303
  }
 
304
 
 
305
 
 
306
/***************************************************************************/
 
307
/***************************************************************************/
 
308
/*****                                                                 *****/
 
309
/*****            L Z W   E M B E D D I N G   S T R E A M              *****/
 
310
/*****                                                                 *****/
 
311
/***************************************************************************/
 
312
/***************************************************************************/
 
313
 
 
314
  static void
 
315
  ft_lzw_stream_close( FT_Stream  stream )
 
316
  {
 
317
    FT_LZWFile  zip    = (FT_LZWFile)stream->descriptor.pointer;
 
318
    FT_Memory   memory = stream->memory;
 
319
 
 
320
 
 
321
    if ( zip )
 
322
    {
 
323
      /* finalize lzw file descriptor */
 
324
      ft_lzw_file_done( zip );
 
325
 
 
326
      FT_FREE( zip );
 
327
 
 
328
      stream->descriptor.pointer = NULL;
 
329
    }
 
330
  }
 
331
 
 
332
 
 
333
  static FT_ULong
 
334
  ft_lzw_stream_io( FT_Stream  stream,
 
335
                    FT_ULong   pos,
 
336
                    FT_Byte*   buffer,
 
337
                    FT_ULong   count )
 
338
  {
 
339
    FT_LZWFile  zip = (FT_LZWFile)stream->descriptor.pointer;
 
340
 
 
341
 
 
342
    return ft_lzw_file_io( zip, pos, buffer, count );
 
343
  }
 
344
 
 
345
 
 
346
  FT_EXPORT_DEF( FT_Error )
 
347
  FT_Stream_OpenLZW( FT_Stream  stream,
 
348
                     FT_Stream  source )
 
349
  {
 
350
    FT_Error    error;
 
351
    FT_Memory   memory = source->memory;
 
352
    FT_LZWFile  zip;
 
353
 
 
354
 
 
355
    /*
 
356
     *  Check the header right now; this prevents allocation of a huge
 
357
     *  LZWFile object (400 KByte of heap memory) if not necessary.
 
358
     *
 
359
     *  Did I mention that you should never use .Z compressed font
 
360
     *  files?
 
361
     */
 
362
    error = ft_lzw_check_header( source );
 
363
    if ( error )
 
364
      goto Exit;
 
365
 
 
366
    FT_ZERO( stream );
 
367
    stream->memory = memory;
 
368
 
 
369
    if ( !FT_NEW( zip ) )
 
370
    {
 
371
      error = ft_lzw_file_init( zip, stream, source );
 
372
      if ( error )
 
373
      {
 
374
        FT_FREE( zip );
 
375
        goto Exit;
 
376
      }
 
377
 
 
378
      stream->descriptor.pointer = zip;
 
379
    }
 
380
 
 
381
    stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */
 
382
    stream->pos   = 0;
 
383
    stream->base  = 0;
 
384
    stream->read  = ft_lzw_stream_io;
 
385
    stream->close = ft_lzw_stream_close;
 
386
 
 
387
  Exit:
 
388
    return error;
 
389
  }
 
390
 
 
391
 
 
392
#include "ftzopen.c"
 
393
 
 
394
 
 
395
#else  /* !FT_CONFIG_OPTION_USE_LZW */
 
396
 
 
397
 
 
398
  FT_EXPORT_DEF( FT_Error )
 
399
  FT_Stream_OpenLZW( FT_Stream  stream,
 
400
                     FT_Stream  source )
 
401
  {
 
402
    FT_UNUSED( stream );
 
403
    FT_UNUSED( source );
 
404
 
 
405
    return LZW_Err_Unimplemented_Feature;
 
406
  }
 
407
 
 
408
 
 
409
#endif /* !FT_CONFIG_OPTION_USE_LZW */
 
410
 
 
411
 
 
412
/* END */