Changeset 1206 for toilet


Ignore:
Timestamp:
Oct 19, 2006, 10:55:44 PM (13 years ago)
Author:
Sam Hocevar
Message:
  • Support for PKZIP-compressed fonts using zlib.
Location:
toilet/trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • toilet/trunk/src/Makefile.am

    r1201 r1206  
    88        figlet.c figlet.h
    99toilet_CFLAGS = `pkg-config --cflags cucul`
    10 toilet_LDFLAGS = `pkg-config --libs cucul` @GETOPT_LIBS@
     10toilet_LDFLAGS = `pkg-config --libs cucul` @GETOPT_LIBS@ @ZLIB_LIBS@
    1111
  • toilet/trunk/src/io.c

    r1202 r1206  
    2020#include <stdio.h>
    2121#include <stdlib.h>
     22#include <stdint.h>
     23#include <string.h>
     24
     25#if defined HAVE_ZLIB_H
     26#   include <zlib.h>
     27#   define READSIZE  128 /* Read buffer size */
     28#   define WRITESIZE 128 /* Inflate buffer size */
     29#endif
    2230
    2331#include "io.h"
    2432
     33#if defined HAVE_ZLIB_H
     34static int zipread(TOIFILE *, void *, unsigned int);
     35#endif
     36
     37struct toifile
     38{
     39#if defined HAVE_ZLIB_H
     40    unsigned char read_buffer[READSIZE];
     41    z_stream stream;
     42    gzFile gz;
     43    int eof, zip;
     44#endif
     45    FILE *f;
     46};
     47
    2548TOIFILE *toiopen(const char *path, const char *mode)
    2649{
    27     TOIFILE *toif;
    28     FILE *f = fopen(path, mode);
     50    TOIFILE *toif = malloc(sizeof(*toif));
     51
     52#if defined HAVE_ZLIB_H
     53    uint8_t buf[4];
     54    unsigned int skip_size = 0;
     55
     56    toif->gz = gzopen(path, "rb");
     57    if(!toif->gz)
     58    {
     59        free(toif);
     60        return NULL;
     61    }
     62
     63    toif->eof = 0;
     64    toif->zip = 0;
     65
     66    /* Parse ZIP file and go to start of first file */
     67    gzread(toif->gz, buf, 4);
     68    if(memcmp(buf, "PK\3\4", 4))
     69    {
     70        gzseek(toif->gz, 0, SEEK_SET);
     71        return toif;
     72    }
     73
     74    toif->zip = 1;
     75
     76    gzseek(toif->gz, 22, SEEK_CUR);
     77
     78    gzread(toif->gz, buf, 2); /* Filename size */
     79    skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
     80    gzread(toif->gz, buf, 2); /* Extra field size */
     81    skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
     82
     83    gzseek(toif->gz, skip_size, SEEK_CUR);
     84
     85    /* Initialise inflate stream */
     86    toif->stream.total_out = 0;
     87    toif->stream.zalloc = NULL;
     88    toif->stream.zfree = NULL;
     89    toif->stream.opaque = NULL;
     90    toif->stream.next_in = NULL;
     91    toif->stream.avail_in = 0;
     92
     93    if(inflateInit2(&toif->stream, -MAX_WBITS))
     94    {
     95        free(toif);
     96        gzclose(toif->gz);
     97        return NULL;
     98    }
     99#else
     100    toif->f = fopen(path, mode);
    29101
    30102    if(!f)
     103    {
     104        free(toif);
    31105        return NULL;
    32 
    33     toif = malloc(sizeof(*toif));
    34     toif->f = f;
     106    }
     107#endif
    35108
    36109    return toif;
     
    39112int toiclose(TOIFILE *toif)
    40113{
     114#if defined HAVE_ZLIB_H
     115    gzFile gz = toif->gz;
     116    if(toif->zip)
     117        inflateEnd(&toif->stream);
     118    free(toif);
     119    return gzclose(gz);
     120#else
    41121    FILE *f = toif->f;
    42122    free(toif);
    43123    return fclose(f);
     124#endif
    44125}
    45126
    46127int toieof(TOIFILE *toif)
    47128{
     129#if defined HAVE_ZLIB_H
     130    return toif->zip ? toif->eof : gzeof(toif->gz);
     131#else
    48132    return feof(toif->f);
     133#endif
    49134}
    50135
    51136char *toigets(char *s, int size, TOIFILE *toif)
    52137{
     138#if defined HAVE_ZLIB_H
     139    if(toif->zip)
     140    {
     141        int i;
     142
     143        for(i = 0; i < size; i++)
     144        {
     145            int ret = zipread(toif, s + i, 1);
     146
     147            if(ret < 0)
     148                return NULL;
     149
     150            if(ret == 0 || s[i] == '\n')
     151            {
     152                if(i + 1 < size)
     153                    s[i + 1] = '\0';
     154                return s;
     155            }
     156        }
     157
     158        return s;
     159    }
     160
     161    return gzgets(toif->gz, s, size);
     162#else
    53163    return fgets(s, size, toif->f);
    54 }
    55 
     164#endif
     165}
     166
     167#if defined HAVE_ZLIB_H
     168static int zipread(TOIFILE *toif, void *buf, unsigned int len)
     169{
     170    unsigned int total_read = 0;
     171
     172    if(len == 0)
     173        return 0;
     174
     175    toif->stream.next_out = buf;
     176    toif->stream.avail_out = len;
     177
     178    while(toif->stream.avail_out > 0)
     179    {
     180        unsigned int tmp;
     181        int ret = 0;
     182
     183        if(toif->stream.avail_in == 0 && !gzeof(toif->gz))
     184        {
     185            int bytes_read;
     186
     187            bytes_read = gzread(toif->gz, toif->read_buffer, READSIZE);
     188            if(bytes_read < 0)
     189                return -1;
     190
     191            toif->stream.next_in = toif->read_buffer;
     192            toif->stream.avail_in = bytes_read;
     193        }
     194
     195        tmp = toif->stream.total_out;
     196        ret = inflate(&toif->stream, Z_SYNC_FLUSH);
     197        total_read += toif->stream.total_out - tmp;
     198
     199        if(ret == Z_STREAM_END)
     200        {
     201            toif->eof = 1;
     202            return total_read;
     203        }
     204
     205        if(ret != Z_OK)
     206            return ret;
     207    }
     208
     209    return total_read;
     210}
     211#endif
     212
  • toilet/trunk/src/io.h

    r1202 r1206  
    1515 * This header defines functions for compressed file I/O.
    1616 */
    17 typedef struct toifile
    18 {
    19     FILE *f;
    20 }
    21 TOIFILE;
     17typedef struct toifile TOIFILE;
    2218
    2319TOIFILE *toiopen(const char *, const char *);
Note: See TracChangeset for help on using the changeset viewer.