~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/lzw/ftlzw.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

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 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 <string.h>
 
30
#include <stdio.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
#include "zopen.h"
 
46
 
 
47
 
 
48
/***************************************************************************/
 
49
/***************************************************************************/
 
50
/*****                                                                 *****/
 
51
/*****                  M E M O R Y   M A N A G E M E N T              *****/
 
52
/*****                                                                 *****/
 
53
/***************************************************************************/
 
54
/***************************************************************************/
 
55
 
 
56
/***************************************************************************/
 
57
/***************************************************************************/
 
58
/*****                                                                 *****/
 
59
/*****                   F I L E   D E S C R I P T O R                 *****/
 
60
/*****                                                                 *****/
 
61
/***************************************************************************/
 
62
/***************************************************************************/
 
63
 
 
64
#define  FT_LZW_BUFFER_SIZE  4096
 
65
 
 
66
  typedef struct FT_LZWFileRec_
 
67
  {
 
68
    FT_Stream   source;         /* parent/source stream        */
 
69
    FT_Stream   stream;         /* embedding stream            */
 
70
    FT_Memory   memory;         /* memory allocator            */
 
71
    s_zstate_t  zstream;        /* lzw input stream            */
 
72
 
 
73
    FT_ULong    start;          /* starting position, after .Z header */
 
74
    FT_Byte     input[FT_LZW_BUFFER_SIZE];  /* input buffer */
 
75
 
 
76
    FT_Byte     buffer[FT_LZW_BUFFER_SIZE]; /* output buffer */
 
77
    FT_ULong    pos;            /* position in output          */
 
78
    FT_Byte*    cursor;
 
79
    FT_Byte*    limit;
 
80
 
 
81
  } FT_LZWFileRec, *FT_LZWFile;
 
82
 
 
83
 
 
84
  /* check and skip .Z header */
 
85
  static FT_Error
 
86
  ft_lzw_check_header( FT_Stream  stream )
 
87
  {
 
88
    FT_Error  error;
 
89
    FT_Byte   head[2];
 
90
 
 
91
 
 
92
    if ( FT_STREAM_SEEK( 0 )       ||
 
93
         FT_STREAM_READ( head, 2 ) )
 
94
      goto Exit;
 
95
 
 
96
    /* head[0] && head[1] are the magic numbers     */
 
97
    if ( head[0] != 0x1f ||
 
98
         head[1] != 0x9d )
 
99
      error = LZW_Err_Invalid_File_Format;
 
100
 
 
101
  Exit:
 
102
    return error;
 
103
  }
 
104
 
 
105
 
 
106
  static FT_Error
 
107
  ft_lzw_file_init( FT_LZWFile  zip,
 
108
                    FT_Stream   stream,
 
109
                    FT_Stream   source )
 
110
  {
 
111
    s_zstate_t*  zstream = &zip->zstream;
 
112
    FT_Error     error   = LZW_Err_Ok;
 
113
 
 
114
 
 
115
    zip->stream = stream;
 
116
    zip->source = source;
 
117
    zip->memory = stream->memory;
 
118
 
 
119
    zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;
 
120
    zip->cursor = zip->limit;
 
121
    zip->pos    = 0;
 
122
 
 
123
    /* check and skip .Z header */
 
124
    {
 
125
      stream = source;
 
126
 
 
127
      error = ft_lzw_check_header( source );
 
128
      if ( error )
 
129
        goto Exit;
 
130
 
 
131
      zip->start = FT_STREAM_POS();
 
132
    }
 
133
 
 
134
    /* initialize internal lzw variable */
 
135
    zinit( zstream );
 
136
 
 
137
    zstream->avail_in    = 0;
 
138
    zstream->next_in     = zip->buffer;
 
139
    zstream->zs_in_count = source->size - 2;
 
140
 
 
141
    if ( zstream->next_in == NULL )
 
142
      error = LZW_Err_Invalid_File_Format;
 
143
 
 
144
  Exit:
 
145
    return error;
 
146
  }
 
147
 
 
148
 
 
149
  static void
 
150
  ft_lzw_file_done( FT_LZWFile  zip )
 
151
  {
 
152
    s_zstate_t*  zstream = &zip->zstream;
 
153
 
 
154
 
 
155
    /* clear the rest */
 
156
    zstream->next_in   = NULL;
 
157
    zstream->next_out  = NULL;
 
158
    zstream->avail_in  = 0;
 
159
    zstream->avail_out = 0;
 
160
    zstream->total_in  = 0;
 
161
    zstream->total_out = 0;
 
162
 
 
163
    zip->memory = NULL;
 
164
    zip->source = NULL;
 
165
    zip->stream = NULL;
 
166
  }
 
167
 
 
168
 
 
169
  static FT_Error
 
170
  ft_lzw_file_reset( FT_LZWFile  zip )
 
171
  {
 
172
    FT_Stream  stream = zip->source;
 
173
    FT_Error   error;
 
174
 
 
175
 
 
176
    if ( !FT_STREAM_SEEK( zip->start ) )
 
177
    {
 
178
      s_zstate_t*  zstream = &zip->zstream;
 
179
 
 
180
 
 
181
      zinit( zstream );
 
182
 
 
183
      zstream->avail_in    = 0;
 
184
      zstream->next_in     = zip->input;
 
185
      zstream->total_in    = 0;
 
186
      zstream->avail_out   = 0;
 
187
      zstream->next_out    = zip->buffer;
 
188
      zstream->total_out   = 0;
 
189
      zstream->zs_in_count = zip->source->size - 2;
 
190
 
 
191
      zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;
 
192
      zip->cursor = zip->limit;
 
193
      zip->pos    = 0;
 
194
    }
 
195
 
 
196
    return error;
 
197
  }
 
198
 
 
199
 
 
200
  static FT_Error
 
201
  ft_lzw_file_fill_input( FT_LZWFile  zip )
 
202
  {
 
203
    s_zstate_t*  zstream = &zip->zstream;
 
204
    FT_Stream    stream  = zip->source;
 
205
    FT_ULong     size;
 
206
 
 
207
 
 
208
    if ( stream->read )
 
209
    {
 
210
      size = stream->read( stream, stream->pos, zip->input,
 
211
                           FT_LZW_BUFFER_SIZE );
 
212
      if ( size == 0 )
 
213
        return LZW_Err_Invalid_Stream_Operation;
 
214
    }
 
215
    else
 
216
    {
 
217
      size = stream->size - stream->pos;
 
218
      if ( size > FT_LZW_BUFFER_SIZE )
 
219
        size = FT_LZW_BUFFER_SIZE;
 
220
 
 
221
      if ( size == 0 )
 
222
        return LZW_Err_Invalid_Stream_Operation;
 
223
 
 
224
      FT_MEM_COPY( zip->input, stream->base + stream->pos, size );
 
225
    }
 
226
    stream->pos += size;
 
227
 
 
228
    zstream->next_in  = zip->input;
 
229
    zstream->avail_in = size;
 
230
 
 
231
    return LZW_Err_Ok;
 
232
  }
 
233
 
 
234
 
 
235
 
 
236
  static FT_Error
 
237
  ft_lzw_file_fill_output( FT_LZWFile  zip )
 
238
  {
 
239
    s_zstate_t*  zstream = &zip->zstream;
 
240
    FT_Error     error   = 0;
 
241
 
 
242
 
 
243
    zip->cursor        = zip->buffer;
 
244
    zstream->next_out  = zip->cursor;
 
245
    zstream->avail_out = FT_LZW_BUFFER_SIZE;
 
246
 
 
247
    while ( zstream->avail_out > 0 )
 
248
    {
 
249
      int  num_read = 0;
 
250
 
 
251
 
 
252
      if ( zstream->avail_in == 0 )
 
253
      {
 
254
        error = ft_lzw_file_fill_input( zip );
 
255
        if ( error )
 
256
          break;
 
257
      }
 
258
 
 
259
      num_read = zread( zstream );
 
260
 
 
261
      if ( num_read == -1 && zstream->zs_in_count == 0 )
 
262
      {
 
263
        zip->limit = zstream->next_out;
 
264
        if ( zip->limit == zip->cursor )
 
265
          error = LZW_Err_Invalid_Stream_Operation;
 
266
        break;
 
267
      }
 
268
      else if ( num_read == -1 )
 
269
        break;
 
270
      else
 
271
        zstream->avail_out -= num_read;
 
272
    }
 
273
 
 
274
    return error;
 
275
  }
 
276
 
 
277
 
 
278
  /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */
 
279
  static FT_Error
 
280
  ft_lzw_file_skip_output( FT_LZWFile  zip,
 
281
                           FT_ULong    count )
 
282
  {
 
283
    FT_Error  error = LZW_Err_Ok;
 
284
    FT_ULong  delta;
 
285
 
 
286
 
 
287
    for (;;)
 
288
    {
 
289
      delta = (FT_ULong)( zip->limit - zip->cursor );
 
290
      if ( delta >= count )
 
291
        delta = count;
 
292
 
 
293
      zip->cursor += delta;
 
294
      zip->pos    += delta;
 
295
 
 
296
      count -= delta;
 
297
      if ( count == 0 )
 
298
        break;
 
299
 
 
300
      error = ft_lzw_file_fill_output( zip );
 
301
      if ( error )
 
302
        break;
 
303
    }
 
304
 
 
305
    return error;
 
306
  }
 
307
 
 
308
 
 
309
  static FT_ULong
 
310
  ft_lzw_file_io( FT_LZWFile  zip,
 
311
                  FT_ULong    pos,
 
312
                  FT_Byte*    buffer,
 
313
                  FT_ULong    count )
 
314
  {
 
315
    FT_ULong  result = 0;
 
316
    FT_Error  error;
 
317
 
 
318
 
 
319
    /* Teset inflate stream if we're seeking backwards.        */
 
320
    /* Yes, that is not too efficient, but it saves memory :-) */
 
321
    if ( pos < zip->pos )
 
322
    {
 
323
      error = ft_lzw_file_reset( zip );
 
324
      if ( error )
 
325
        goto Exit;
 
326
    }
 
327
 
 
328
    /* skip unwanted bytes */
 
329
    if ( pos > zip->pos )
 
330
    {
 
331
      error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );
 
332
      if ( error )
 
333
        goto Exit;
 
334
    }
 
335
 
 
336
    if ( count == 0 )
 
337
      goto Exit;
 
338
 
 
339
    /* now read the data */
 
340
    for (;;)
 
341
    {
 
342
      FT_ULong  delta;
 
343
 
 
344
 
 
345
      delta = (FT_ULong)( zip->limit - zip->cursor );
 
346
      if ( delta >= count )
 
347
        delta = count;
 
348
 
 
349
      FT_MEM_COPY( buffer, zip->cursor, delta );
 
350
      buffer      += delta;
 
351
      result      += delta;
 
352
      zip->cursor += delta;
 
353
      zip->pos    += delta;
 
354
 
 
355
      count -= delta;
 
356
      if ( count == 0 )
 
357
        break;
 
358
 
 
359
      error = ft_lzw_file_fill_output( zip );
 
360
      if ( error )
 
361
        break;
 
362
    }
 
363
 
 
364
  Exit:
 
365
    return result;
 
366
  }
 
367
 
 
368
 
 
369
/***************************************************************************/
 
370
/***************************************************************************/
 
371
/*****                                                                 *****/
 
372
/*****            L Z W   E M B E D D I N G   S T R E A M              *****/
 
373
/*****                                                                 *****/
 
374
/***************************************************************************/
 
375
/***************************************************************************/
 
376
 
 
377
  static void
 
378
  ft_lzw_stream_close( FT_Stream  stream )
 
379
  {
 
380
    FT_LZWFile  zip    = (FT_LZWFile)stream->descriptor.pointer;
 
381
    FT_Memory   memory = stream->memory;
 
382
 
 
383
 
 
384
    if ( zip )
 
385
    {
 
386
      /* finalize lzw file descriptor */
 
387
      ft_lzw_file_done( zip );
 
388
 
 
389
      FT_FREE( zip );
 
390
 
 
391
      stream->descriptor.pointer = NULL;
 
392
    }
 
393
  }
 
394
 
 
395
 
 
396
  static FT_ULong
 
397
  ft_lzw_stream_io( FT_Stream  stream,
 
398
                    FT_ULong   pos,
 
399
                    FT_Byte*   buffer,
 
400
                    FT_ULong   count )
 
401
  {
 
402
    FT_LZWFile  zip = (FT_LZWFile)stream->descriptor.pointer;
 
403
 
 
404
 
 
405
    return ft_lzw_file_io( zip, pos, buffer, count );
 
406
  }
 
407
 
 
408
 
 
409
  FT_EXPORT_DEF( FT_Error )
 
410
  FT_Stream_OpenLZW( FT_Stream  stream,
 
411
                     FT_Stream  source )
 
412
  {
 
413
    FT_Error    error;
 
414
    FT_Memory   memory = source->memory;
 
415
    FT_LZWFile  zip;
 
416
 
 
417
 
 
418
    FT_ZERO( stream );
 
419
    stream->memory = memory;
 
420
 
 
421
    if ( !FT_NEW( zip ) )
 
422
    {
 
423
      error = ft_lzw_file_init( zip, stream, source );
 
424
      if ( error )
 
425
      {
 
426
        FT_FREE( zip );
 
427
        goto Exit;
 
428
      }
 
429
 
 
430
      stream->descriptor.pointer = zip;
 
431
    }
 
432
 
 
433
    stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */
 
434
    stream->pos   = 0;
 
435
    stream->base  = 0;
 
436
    stream->read  = ft_lzw_stream_io;
 
437
    stream->close = ft_lzw_stream_close;
 
438
 
 
439
  Exit:
 
440
    return error;
 
441
  }
 
442
 
 
443
#include "zopen.c"
 
444
 
 
445
 
 
446
#else  /* !FT_CONFIG_OPTION_USE_LZW */
 
447
 
 
448
 
 
449
  FT_EXPORT_DEF( FT_Error )
 
450
  FT_Stream_OpenLZW( FT_Stream  stream,
 
451
                     FT_Stream  source )
 
452
  {
 
453
    FT_UNUSED( stream );
 
454
    FT_UNUSED( source );
 
455
 
 
456
    return LZW_Err_Unimplemented_Feature;
 
457
  }
 
458
 
 
459
 
 
460
#endif /* !FT_CONFIG_OPTION_USE_LZW */
 
461
 
 
462
 
 
463
/* END */