~ubuntu-branches/ubuntu/saucy/emscripten/saucy-proposed

« back to all changes in this revision

Viewing changes to tests/freetype/src/gzip/ftgzip.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
/*  ftgzip.c                                                               */
 
4
/*                                                                         */
 
5
/*    FreeType support for .gz compressed files.                           */
 
6
/*                                                                         */
 
7
/*  This optional component relies on zlib.  It should mainly be used to   */
 
8
/*  parse compressed PCF fonts, as found with many X11 server              */
 
9
/*  distributions.                                                         */
 
10
/*                                                                         */
 
11
/*  Copyright 2002, 2003, 2004, 2005, 2006, 2009, 2010 by                  */
 
12
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 
13
/*                                                                         */
 
14
/*  This file is part of the FreeType project, and may only be used,       */
 
15
/*  modified, and distributed under the terms of the FreeType project      */
 
16
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 
17
/*  this file you indicate that you have read the license and              */
 
18
/*  understand and accept it fully.                                        */
 
19
/*                                                                         */
 
20
/***************************************************************************/
 
21
 
 
22
 
 
23
#include <ft2build.h>
 
24
#include FT_INTERNAL_MEMORY_H
 
25
#include FT_INTERNAL_STREAM_H
 
26
#include FT_INTERNAL_DEBUG_H
 
27
#include FT_GZIP_H
 
28
#include FT_CONFIG_STANDARD_LIBRARY_H
 
29
 
 
30
 
 
31
#include FT_MODULE_ERRORS_H
 
32
 
 
33
#undef __FTERRORS_H__
 
34
 
 
35
#define FT_ERR_PREFIX  Gzip_Err_
 
36
#define FT_ERR_BASE    FT_Mod_Err_Gzip
 
37
 
 
38
#include FT_ERRORS_H
 
39
 
 
40
 
 
41
#ifdef FT_CONFIG_OPTION_USE_ZLIB
 
42
 
 
43
#ifdef FT_CONFIG_OPTION_PIC
 
44
#error "gzip code does not support PIC yet"
 
45
#endif 
 
46
 
 
47
#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB
 
48
 
 
49
#include <zlib.h>
 
50
 
 
51
#else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */
 
52
 
 
53
 /* In this case, we include our own modified sources of the ZLib    */
 
54
 /* within the "ftgzip" component.  The modifications were necessary */
 
55
 /* to #include all files without conflicts, as well as preventing   */
 
56
 /* the definition of "extern" functions that may cause linking      */
 
57
 /* conflicts when a program is linked with both FreeType and the    */
 
58
 /* original ZLib.                                                   */
 
59
 
 
60
#define NO_DUMMY_DECL
 
61
#ifndef USE_ZLIB_ZCALLOC
 
62
#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */
 
63
#endif
 
64
 
 
65
#include "zlib.h"
 
66
 
 
67
#undef  SLOW
 
68
#define SLOW  1  /* we can't use asm-optimized sources here! */
 
69
 
 
70
  /* Urgh.  `inflate_mask' must not be declared twice -- C++ doesn't like
 
71
     this.  We temporarily disable it and load all necessary header files. */
 
72
#define NO_INFLATE_MASK
 
73
#include "zutil.h"
 
74
#include "inftrees.h"
 
75
#include "infblock.h"
 
76
#include "infcodes.h"
 
77
#include "infutil.h"
 
78
#undef  NO_INFLATE_MASK
 
79
 
 
80
  /* infutil.c must be included before infcodes.c */
 
81
#include "zutil.c"
 
82
#include "inftrees.c"
 
83
#include "infutil.c"
 
84
#include "infcodes.c"
 
85
#include "infblock.c"
 
86
#include "inflate.c"
 
87
#include "adler32.c"
 
88
 
 
89
#endif /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */
 
90
 
 
91
 
 
92
/***************************************************************************/
 
93
/***************************************************************************/
 
94
/*****                                                                 *****/
 
95
/*****            Z L I B   M E M O R Y   M A N A G E M E N T          *****/
 
96
/*****                                                                 *****/
 
97
/***************************************************************************/
 
98
/***************************************************************************/
 
99
 
 
100
  /* it is better to use FreeType memory routines instead of raw
 
101
     'malloc/free' */
 
102
 
 
103
  static voidpf
 
104
  ft_gzip_alloc( FT_Memory  memory,
 
105
                 uInt       items,
 
106
                 uInt       size )
 
107
  {
 
108
    FT_ULong    sz = (FT_ULong)size * items;
 
109
    FT_Error    error;
 
110
    FT_Pointer  p  = NULL;
 
111
 
 
112
 
 
113
    (void)FT_ALLOC( p, sz );
 
114
    return p;
 
115
  }
 
116
 
 
117
 
 
118
  static void
 
119
  ft_gzip_free( FT_Memory  memory,
 
120
                voidpf     address )
 
121
  {
 
122
    FT_MEM_FREE( address );
 
123
  }
 
124
 
 
125
 
 
126
#if !defined( FT_CONFIG_OPTION_SYSTEM_ZLIB ) && !defined( USE_ZLIB_ZCALLOC )
 
127
 
 
128
  local voidpf
 
129
  zcalloc ( voidpf    opaque,
 
130
            unsigned  items,
 
131
            unsigned  size )
 
132
  {
 
133
    return ft_gzip_alloc( (FT_Memory)opaque, items, size );
 
134
  }
 
135
 
 
136
  local void
 
137
  zcfree( voidpf  opaque,
 
138
          voidpf  ptr )
 
139
  {
 
140
    ft_gzip_free( (FT_Memory)opaque, ptr );
 
141
  }
 
142
 
 
143
#endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */
 
144
 
 
145
 
 
146
/***************************************************************************/
 
147
/***************************************************************************/
 
148
/*****                                                                 *****/
 
149
/*****               Z L I B   F I L E   D E S C R I P T O R           *****/
 
150
/*****                                                                 *****/
 
151
/***************************************************************************/
 
152
/***************************************************************************/
 
153
 
 
154
#define FT_GZIP_BUFFER_SIZE  4096
 
155
 
 
156
  typedef struct  FT_GZipFileRec_
 
157
  {
 
158
    FT_Stream  source;         /* parent/source stream        */
 
159
    FT_Stream  stream;         /* embedding stream            */
 
160
    FT_Memory  memory;         /* memory allocator            */
 
161
    z_stream   zstream;        /* zlib input stream           */
 
162
 
 
163
    FT_ULong   start;          /* starting position, after .gz header */
 
164
    FT_Byte    input[FT_GZIP_BUFFER_SIZE];   /* input read buffer  */
 
165
 
 
166
    FT_Byte    buffer[FT_GZIP_BUFFER_SIZE];  /* output buffer      */
 
167
    FT_ULong   pos;                          /* position in output */
 
168
    FT_Byte*   cursor;
 
169
    FT_Byte*   limit;
 
170
 
 
171
  } FT_GZipFileRec, *FT_GZipFile;
 
172
 
 
173
 
 
174
  /* gzip flag byte */
 
175
#define FT_GZIP_ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
 
176
#define FT_GZIP_HEAD_CRC     0x02 /* bit 1 set: header CRC present */
 
177
#define FT_GZIP_EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
 
178
#define FT_GZIP_ORIG_NAME    0x08 /* bit 3 set: original file name present */
 
179
#define FT_GZIP_COMMENT      0x10 /* bit 4 set: file comment present */
 
180
#define FT_GZIP_RESERVED     0xE0 /* bits 5..7: reserved */
 
181
 
 
182
 
 
183
  /* check and skip .gz header - we don't support `transparent' compression */
 
184
  static FT_Error
 
185
  ft_gzip_check_header( FT_Stream  stream )
 
186
  {
 
187
    FT_Error  error;
 
188
    FT_Byte   head[4];
 
189
 
 
190
 
 
191
    if ( FT_STREAM_SEEK( 0 )       ||
 
192
         FT_STREAM_READ( head, 4 ) )
 
193
      goto Exit;
 
194
 
 
195
    /* head[0] && head[1] are the magic numbers;    */
 
196
    /* head[2] is the method, and head[3] the flags */
 
197
    if ( head[0] != 0x1f              ||
 
198
         head[1] != 0x8b              ||
 
199
         head[2] != Z_DEFLATED        ||
 
200
        (head[3] & FT_GZIP_RESERVED)  )
 
201
    {
 
202
      error = Gzip_Err_Invalid_File_Format;
 
203
      goto Exit;
 
204
    }
 
205
 
 
206
    /* skip time, xflags and os code */
 
207
    (void)FT_STREAM_SKIP( 6 );
 
208
 
 
209
    /* skip the extra field */
 
210
    if ( head[3] & FT_GZIP_EXTRA_FIELD )
 
211
    {
 
212
      FT_UInt  len;
 
213
 
 
214
 
 
215
      if ( FT_READ_USHORT_LE( len ) ||
 
216
           FT_STREAM_SKIP( len )    )
 
217
        goto Exit;
 
218
    }
 
219
 
 
220
    /* skip original file name */
 
221
    if ( head[3] & FT_GZIP_ORIG_NAME )
 
222
      for (;;)
 
223
      {
 
224
        FT_UInt  c;
 
225
 
 
226
 
 
227
        if ( FT_READ_BYTE( c ) )
 
228
          goto Exit;
 
229
 
 
230
        if ( c == 0 )
 
231
          break;
 
232
      }
 
233
 
 
234
    /* skip .gz comment */
 
235
    if ( head[3] & FT_GZIP_COMMENT )
 
236
      for (;;)
 
237
      {
 
238
        FT_UInt  c;
 
239
 
 
240
 
 
241
        if ( FT_READ_BYTE( c ) )
 
242
          goto Exit;
 
243
 
 
244
        if ( c == 0 )
 
245
          break;
 
246
      }
 
247
 
 
248
    /* skip CRC */
 
249
    if ( head[3] & FT_GZIP_HEAD_CRC )
 
250
      if ( FT_STREAM_SKIP( 2 ) )
 
251
        goto Exit;
 
252
 
 
253
  Exit:
 
254
    return error;
 
255
  }
 
256
 
 
257
 
 
258
  static FT_Error
 
259
  ft_gzip_file_init( FT_GZipFile  zip,
 
260
                     FT_Stream    stream,
 
261
                     FT_Stream    source )
 
262
  {
 
263
    z_stream*  zstream = &zip->zstream;
 
264
    FT_Error   error   = Gzip_Err_Ok;
 
265
 
 
266
 
 
267
    zip->stream = stream;
 
268
    zip->source = source;
 
269
    zip->memory = stream->memory;
 
270
 
 
271
    zip->limit  = zip->buffer + FT_GZIP_BUFFER_SIZE;
 
272
    zip->cursor = zip->limit;
 
273
    zip->pos    = 0;
 
274
 
 
275
    /* check and skip .gz header */
 
276
    {
 
277
      stream = source;
 
278
 
 
279
      error = ft_gzip_check_header( stream );
 
280
      if ( error )
 
281
        goto Exit;
 
282
 
 
283
      zip->start = FT_STREAM_POS();
 
284
    }
 
285
 
 
286
    /* initialize zlib -- there is no zlib header in the compressed stream */
 
287
    zstream->zalloc = (alloc_func)ft_gzip_alloc;
 
288
    zstream->zfree  = (free_func) ft_gzip_free;
 
289
    zstream->opaque = stream->memory;
 
290
 
 
291
    zstream->avail_in = 0;
 
292
    zstream->next_in  = zip->buffer;
 
293
 
 
294
    if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK ||
 
295
         zstream->next_in == NULL                     )
 
296
      error = Gzip_Err_Invalid_File_Format;
 
297
 
 
298
  Exit:
 
299
    return error;
 
300
  }
 
301
 
 
302
 
 
303
  static void
 
304
  ft_gzip_file_done( FT_GZipFile  zip )
 
305
  {
 
306
    z_stream*  zstream = &zip->zstream;
 
307
 
 
308
 
 
309
    inflateEnd( zstream );
 
310
 
 
311
    /* clear the rest */
 
312
    zstream->zalloc    = NULL;
 
313
    zstream->zfree     = NULL;
 
314
    zstream->opaque    = NULL;
 
315
    zstream->next_in   = NULL;
 
316
    zstream->next_out  = NULL;
 
317
    zstream->avail_in  = 0;
 
318
    zstream->avail_out = 0;
 
319
 
 
320
    zip->memory = NULL;
 
321
    zip->source = NULL;
 
322
    zip->stream = NULL;
 
323
  }
 
324
 
 
325
 
 
326
  static FT_Error
 
327
  ft_gzip_file_reset( FT_GZipFile  zip )
 
328
  {
 
329
    FT_Stream  stream = zip->source;
 
330
    FT_Error   error;
 
331
 
 
332
 
 
333
    if ( !FT_STREAM_SEEK( zip->start ) )
 
334
    {
 
335
      z_stream*  zstream = &zip->zstream;
 
336
 
 
337
 
 
338
      inflateReset( zstream );
 
339
 
 
340
      zstream->avail_in  = 0;
 
341
      zstream->next_in   = zip->input;
 
342
      zstream->avail_out = 0;
 
343
      zstream->next_out  = zip->buffer;
 
344
 
 
345
      zip->limit  = zip->buffer + FT_GZIP_BUFFER_SIZE;
 
346
      zip->cursor = zip->limit;
 
347
      zip->pos    = 0;
 
348
    }
 
349
 
 
350
    return error;
 
351
  }
 
352
 
 
353
 
 
354
  static FT_Error
 
355
  ft_gzip_file_fill_input( FT_GZipFile  zip )
 
356
  {
 
357
    z_stream*  zstream = &zip->zstream;
 
358
    FT_Stream  stream  = zip->source;
 
359
    FT_ULong   size;
 
360
 
 
361
 
 
362
    if ( stream->read )
 
363
    {
 
364
      size = stream->read( stream, stream->pos, zip->input,
 
365
                           FT_GZIP_BUFFER_SIZE );
 
366
      if ( size == 0 )
 
367
        return Gzip_Err_Invalid_Stream_Operation;
 
368
    }
 
369
    else
 
370
    {
 
371
      size = stream->size - stream->pos;
 
372
      if ( size > FT_GZIP_BUFFER_SIZE )
 
373
        size = FT_GZIP_BUFFER_SIZE;
 
374
 
 
375
      if ( size == 0 )
 
376
        return Gzip_Err_Invalid_Stream_Operation;
 
377
 
 
378
      FT_MEM_COPY( zip->input, stream->base + stream->pos, size );
 
379
    }
 
380
    stream->pos += size;
 
381
 
 
382
    zstream->next_in  = zip->input;
 
383
    zstream->avail_in = size;
 
384
 
 
385
    return Gzip_Err_Ok;
 
386
  }
 
387
 
 
388
 
 
389
  static FT_Error
 
390
  ft_gzip_file_fill_output( FT_GZipFile  zip )
 
391
  {
 
392
    z_stream*  zstream = &zip->zstream;
 
393
    FT_Error   error   = Gzip_Err_Ok;
 
394
 
 
395
 
 
396
    zip->cursor        = zip->buffer;
 
397
    zstream->next_out  = zip->cursor;
 
398
    zstream->avail_out = FT_GZIP_BUFFER_SIZE;
 
399
 
 
400
    while ( zstream->avail_out > 0 )
 
401
    {
 
402
      int  err;
 
403
 
 
404
 
 
405
      if ( zstream->avail_in == 0 )
 
406
      {
 
407
        error = ft_gzip_file_fill_input( zip );
 
408
        if ( error )
 
409
          break;
 
410
      }
 
411
 
 
412
      err = inflate( zstream, Z_NO_FLUSH );
 
413
 
 
414
      if ( err == Z_STREAM_END )
 
415
      {
 
416
        zip->limit = zstream->next_out;
 
417
        if ( zip->limit == zip->cursor )
 
418
          error = Gzip_Err_Invalid_Stream_Operation;
 
419
        break;
 
420
      }
 
421
      else if ( err != Z_OK )
 
422
      {
 
423
        error = Gzip_Err_Invalid_Stream_Operation;
 
424
        break;
 
425
      }
 
426
    }
 
427
 
 
428
    return error;
 
429
  }
 
430
 
 
431
 
 
432
  /* fill output buffer; `count' must be <= FT_GZIP_BUFFER_SIZE */
 
433
  static FT_Error
 
434
  ft_gzip_file_skip_output( FT_GZipFile  zip,
 
435
                            FT_ULong     count )
 
436
  {
 
437
    FT_Error  error = Gzip_Err_Ok;
 
438
    FT_ULong  delta;
 
439
 
 
440
 
 
441
    for (;;)
 
442
    {
 
443
      delta = (FT_ULong)( zip->limit - zip->cursor );
 
444
      if ( delta >= count )
 
445
        delta = count;
 
446
 
 
447
      zip->cursor += delta;
 
448
      zip->pos    += delta;
 
449
 
 
450
      count -= delta;
 
451
      if ( count == 0 )
 
452
        break;
 
453
 
 
454
      error = ft_gzip_file_fill_output( zip );
 
455
      if ( error )
 
456
        break;
 
457
    }
 
458
 
 
459
    return error;
 
460
  }
 
461
 
 
462
 
 
463
  static FT_ULong
 
464
  ft_gzip_file_io( FT_GZipFile  zip,
 
465
                   FT_ULong     pos,
 
466
                   FT_Byte*     buffer,
 
467
                   FT_ULong     count )
 
468
  {
 
469
    FT_ULong  result = 0;
 
470
    FT_Error  error;
 
471
 
 
472
 
 
473
    /* Reset inflate stream if we're seeking backwards.        */
 
474
    /* Yes, that is not too efficient, but it saves memory :-) */
 
475
    if ( pos < zip->pos )
 
476
    {
 
477
      error = ft_gzip_file_reset( zip );
 
478
      if ( error )
 
479
        goto Exit;
 
480
    }
 
481
 
 
482
    /* skip unwanted bytes */
 
483
    if ( pos > zip->pos )
 
484
    {
 
485
      error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );
 
486
      if ( error )
 
487
        goto Exit;
 
488
    }
 
489
 
 
490
    if ( count == 0 )
 
491
      goto Exit;
 
492
 
 
493
    /* now read the data */
 
494
    for (;;)
 
495
    {
 
496
      FT_ULong  delta;
 
497
 
 
498
 
 
499
      delta = (FT_ULong)( zip->limit - zip->cursor );
 
500
      if ( delta >= count )
 
501
        delta = count;
 
502
 
 
503
      FT_MEM_COPY( buffer, zip->cursor, delta );
 
504
      buffer      += delta;
 
505
      result      += delta;
 
506
      zip->cursor += delta;
 
507
      zip->pos    += delta;
 
508
 
 
509
      count -= delta;
 
510
      if ( count == 0 )
 
511
        break;
 
512
 
 
513
      error = ft_gzip_file_fill_output( zip );
 
514
      if ( error )
 
515
        break;
 
516
    }
 
517
 
 
518
  Exit:
 
519
    return result;
 
520
  }
 
521
 
 
522
 
 
523
/***************************************************************************/
 
524
/***************************************************************************/
 
525
/*****                                                                 *****/
 
526
/*****               G Z   E M B E D D I N G   S T R E A M             *****/
 
527
/*****                                                                 *****/
 
528
/***************************************************************************/
 
529
/***************************************************************************/
 
530
 
 
531
  static void
 
532
  ft_gzip_stream_close( FT_Stream  stream )
 
533
  {
 
534
    FT_GZipFile  zip    = (FT_GZipFile)stream->descriptor.pointer;
 
535
    FT_Memory    memory = stream->memory;
 
536
 
 
537
 
 
538
    if ( zip )
 
539
    {
 
540
      /* finalize gzip file descriptor */
 
541
      ft_gzip_file_done( zip );
 
542
 
 
543
      FT_FREE( zip );
 
544
 
 
545
      stream->descriptor.pointer = NULL;
 
546
    }
 
547
  }
 
548
 
 
549
 
 
550
  static FT_ULong
 
551
  ft_gzip_stream_io( FT_Stream  stream,
 
552
                     FT_ULong   pos,
 
553
                     FT_Byte*   buffer,
 
554
                     FT_ULong   count )
 
555
  {
 
556
    FT_GZipFile  zip = (FT_GZipFile)stream->descriptor.pointer;
 
557
 
 
558
 
 
559
    return ft_gzip_file_io( zip, pos, buffer, count );
 
560
  }
 
561
 
 
562
 
 
563
  static FT_ULong
 
564
  ft_gzip_get_uncompressed_size( FT_Stream  stream )
 
565
  {
 
566
    FT_Error  error;
 
567
    FT_ULong  old_pos;
 
568
    FT_ULong  result = 0;
 
569
 
 
570
 
 
571
    old_pos = stream->pos;
 
572
    if ( !FT_Stream_Seek( stream, stream->size - 4 ) )
 
573
    {
 
574
      result = (FT_ULong)FT_Stream_ReadLong( stream, &error );
 
575
      if ( error )
 
576
        result = 0;
 
577
 
 
578
      (void)FT_Stream_Seek( stream, old_pos );
 
579
    }
 
580
 
 
581
    return result;
 
582
  }
 
583
 
 
584
 
 
585
  FT_EXPORT_DEF( FT_Error )
 
586
  FT_Stream_OpenGzip( FT_Stream  stream,
 
587
                      FT_Stream  source )
 
588
  {
 
589
    FT_Error     error;
 
590
    FT_Memory    memory = source->memory;
 
591
    FT_GZipFile  zip;
 
592
 
 
593
 
 
594
    /*
 
595
     *  check the header right now; this prevents allocating un-necessary
 
596
     *  objects when we don't need them
 
597
     */
 
598
    error = ft_gzip_check_header( source );
 
599
    if ( error )
 
600
      goto Exit;
 
601
 
 
602
    FT_ZERO( stream );
 
603
    stream->memory = memory;
 
604
 
 
605
    if ( !FT_QNEW( zip ) )
 
606
    {
 
607
      error = ft_gzip_file_init( zip, stream, source );
 
608
      if ( error )
 
609
      {
 
610
        FT_FREE( zip );
 
611
        goto Exit;
 
612
      }
 
613
 
 
614
      stream->descriptor.pointer = zip;
 
615
    }
 
616
 
 
617
    /*
 
618
     *  We use the following trick to try to dramatically improve the
 
619
     *  performance while dealing with small files.  If the original stream
 
620
     *  size is less than a certain threshold, we try to load the whole font
 
621
     *  file into memory.  This saves us from using the 32KB buffer needed
 
622
     *  to inflate the file, plus the two 4KB intermediate input/output
 
623
     *  buffers used in the `FT_GZipFile' structure.
 
624
     */
 
625
    {
 
626
      FT_ULong  zip_size = ft_gzip_get_uncompressed_size( source );
 
627
 
 
628
 
 
629
      if ( zip_size != 0 && zip_size < 40 * 1024 )
 
630
      {
 
631
        FT_Byte*  zip_buff;
 
632
 
 
633
 
 
634
        if ( !FT_ALLOC( zip_buff, zip_size ) )
 
635
        {
 
636
          FT_ULong  count;
 
637
 
 
638
 
 
639
          count = ft_gzip_file_io( zip, 0, zip_buff, zip_size );
 
640
          if ( count == zip_size )
 
641
          {
 
642
            ft_gzip_file_done( zip );
 
643
            FT_FREE( zip );
 
644
 
 
645
            stream->descriptor.pointer = NULL;
 
646
 
 
647
            stream->size  = zip_size;
 
648
            stream->pos   = 0;
 
649
            stream->base  = zip_buff;
 
650
            stream->read  = NULL;
 
651
            stream->close = ft_gzip_stream_close;
 
652
 
 
653
            goto Exit;
 
654
          }
 
655
 
 
656
          ft_gzip_file_io( zip, 0, NULL, 0 );
 
657
          FT_FREE( zip_buff );
 
658
        }
 
659
        error = Gzip_Err_Ok;
 
660
      }
 
661
    }
 
662
 
 
663
    stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */
 
664
    stream->pos   = 0;
 
665
    stream->base  = 0;
 
666
    stream->read  = ft_gzip_stream_io;
 
667
    stream->close = ft_gzip_stream_close;
 
668
 
 
669
  Exit:
 
670
    return error;
 
671
  }
 
672
 
 
673
#else  /* !FT_CONFIG_OPTION_USE_ZLIB */
 
674
 
 
675
  FT_EXPORT_DEF( FT_Error )
 
676
  FT_Stream_OpenGzip( FT_Stream  stream,
 
677
                      FT_Stream  source )
 
678
  {
 
679
    FT_UNUSED( stream );
 
680
    FT_UNUSED( source );
 
681
 
 
682
    return Gzip_Err_Unimplemented_Feature;
 
683
  }
 
684
 
 
685
#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
 
686
 
 
687
 
 
688
/* END */