diff options
Diffstat (limited to 'libXfont/src/fontfile/gunzip.c')
-rw-r--r-- | libXfont/src/fontfile/gunzip.c | 452 |
1 files changed, 225 insertions, 227 deletions
diff --git a/libXfont/src/fontfile/gunzip.c b/libXfont/src/fontfile/gunzip.c index 6cf192bb8..52b0a10be 100644 --- a/libXfont/src/fontfile/gunzip.c +++ b/libXfont/src/fontfile/gunzip.c @@ -1,227 +1,225 @@ -/* $Xorg: gunzip.c,v 1.3 2000/08/17 19:46:37 cpqbld Exp $ */ -/* lib/font/fontfile/gunzip.c - written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996. - intended for inclusion in X11 public releases. */ -/* $XFree86: xc/lib/font/fontfile/gunzip.c,v 1.4 2000/09/19 12:46:08 eich Exp $ */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/fonts/fontmisc.h> -#include <X11/fonts/bufio.h> -#include <zlib.h> - -typedef struct _xzip_buf { - z_stream z; - int zstat; - BufChar b[BUFFILESIZE]; - BufChar b_in[BUFFILESIZE]; - BufFilePtr f; -} xzip_buf; - -static int BufZipFileClose ( BufFilePtr f, int flag ); -static int BufZipFileFill ( BufFilePtr f ); -static int BufZipFileSkip ( BufFilePtr f, int c ); -static int BufCheckZipHeader ( BufFilePtr f ); - -BufFilePtr -BufFilePushZIP (BufFilePtr f) -{ - xzip_buf *x; - - x = malloc (sizeof (xzip_buf)); - if (!x) return 0; - /* these are just for raw calloc/free */ - x->z.zalloc = Z_NULL; - x->z.zfree = Z_NULL; - x->z.opaque = Z_NULL; - x->f = f; - - /* force inflateInit to allocate it's own history buffer */ - x->z.next_in = Z_NULL; - x->z.next_out = Z_NULL; - x->z.avail_in = x->z.avail_out = 0; - - /* using negative windowBits sets "nowrap" mode, which turns off - zlib header checking [undocumented, for gzip compatibility only?] */ - x->zstat = inflateInit2(&(x->z), -MAX_WBITS); - if (x->zstat != Z_OK) { - free(x); - return 0; - } - - /* now that the history buffer is allocated, we provide the data buffer */ - x->z.next_out = x->b; - x->z.avail_out = BUFFILESIZE; - x->z.next_out = x->b_in; - x->z.avail_in = 0; - - if (BufCheckZipHeader(x->f)) { - free(x); - return 0; - } - - return BufFileCreate((char *)x, - BufZipFileFill, - 0, - BufZipFileSkip, - BufZipFileClose); -} - -static int -BufZipFileClose(BufFilePtr f, int flag) -{ - xzip_buf *x = (xzip_buf *)f->private; - inflateEnd (&(x->z)); - BufFileClose (x->f, flag); - free (x); - return 1; -} - -/* here's the real work. - -- we need to put stuff in f.buffer, update f.left and f.bufp, - then return the first byte (or BUFFILEEOF). - -- to do this, we need to get stuff into avail_in, and next_in, - and call inflate appropriately. - -- we may also need to add CRC maintenance - if inflate tells us - Z_STREAM_END, we then have 4bytes CRC and 4bytes length... - gzio.c:gzread shows most of the mechanism. - */ -static int -BufZipFileFill (BufFilePtr f) -{ - xzip_buf *x = (xzip_buf *)f->private; - - /* we only get called when left == 0... */ - /* but just in case, deal */ - if (f->left >= 0) { - f->left--; - return *(f->bufp++); - } - /* did we run out last time? */ - switch (x->zstat) { - case Z_OK: - break; - case Z_STREAM_END: - case Z_DATA_ERROR: - case Z_ERRNO: - f->left = 0; - return BUFFILEEOF; - default: - return BUFFILEEOF; - } - /* now we work to consume what we can */ - /* let zlib know what we can handle */ - x->z.next_out = x->b; - x->z.avail_out = BUFFILESIZE; - - /* and try to consume all of it */ - while (x->z.avail_out > 0) { - /* if we don't have anything to work from... */ - if (x->z.avail_in == 0) { - /* ... fill the z buf from underlying file */ - int i, c; - for (i = 0; i < sizeof(x->b_in); i++) { - c = BufFileGet(x->f); - if (c == BUFFILEEOF) break; - x->b_in[i] = c; - } - x->z.avail_in += i; - x->z.next_in = x->b_in; - } - /* so now we have some output space and some input data */ - x->zstat = inflate(&(x->z), Z_NO_FLUSH); - /* the inflation output happens in the f buffer directly... */ - if (x->zstat == Z_STREAM_END) { - /* deal with EOF, crc */ - break; - } - if (x->zstat != Z_OK) { - break; - } - } - f->bufp = x->b; - f->left = BUFFILESIZE - x->z.avail_out; - - if (f->left >= 0) { - f->left--; - return *(f->bufp++); - } else { - return BUFFILEEOF; - } -} - -/* there should be a BufCommonSkip... */ -static int -BufZipFileSkip (BufFilePtr f, int c) -{ - /* BufFileRawSkip returns the count unchanged. - BufCompressedSkip returns 0. - That means it probably never gets called... */ - int retval = c; - while(c--) { - int get = BufFileGet(f); - if (get == BUFFILEEOF) return get; - } - return retval; -} - -/* now we need to duplicate check_header */ -/* contents: - 0x1f, 0x8b -- magic number - 1 byte -- method (Z_DEFLATED) - 1 byte -- flags (mask with RESERVED -> fail) - 4 byte -- time (discard) - 1 byte -- xflags (discard) - 1 byte -- "os" code (discard) - [if flags & EXTRA_FIELD: - 2 bytes -- LSBfirst length n - n bytes -- extra data (discard)] - [if flags & ORIG_NAME: - n bytes -- null terminated name (discard)] - [if flags & COMMENT: - n bytes -- null terminated comment (discard)] - [if flags & HEAD_CRC: - 2 bytes -- crc of headers? (discard)] - */ - -/* gzip flag byte -- from gzio.c */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -#define GET(f) do {c = BufFileGet(f); if (c == BUFFILEEOF) return c;} while(0) -static int -BufCheckZipHeader(BufFilePtr f) -{ - int c, flags; - GET(f); if (c != 0x1f) return 1; /* magic 1 */ - GET(f); if (c != 0x8b) return 2; /* magic 2 */ - GET(f); if (c != Z_DEFLATED) return 3; /* method */ - GET(f); if (c & RESERVED) return 4; /* reserved flags */ - flags = c; - GET(f); GET(f); GET(f); GET(f); /* time */ - GET(f); /* xflags */ - GET(f); /* os code */ - if (flags & EXTRA_FIELD) { - int len; - GET(f); len = c; - GET(f); len += (c<<8); - while (len-- >= 0) { - GET(f); - } - } - if (flags & ORIG_NAME) { - do { GET(f); } while (c != 0); - } - if (flags & COMMENT) { - do { GET(f); } while (c != 0); - } - if (flags & HEAD_CRC) { - GET(f); GET(f); /* header crc */ - } - return 0; -} +/* lib/font/fontfile/gunzip.c
+ written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+ intended for inclusion in X11 public releases. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <zlib.h>
+
+typedef struct _xzip_buf {
+ z_stream z;
+ int zstat;
+ BufChar b[BUFFILESIZE];
+ BufChar b_in[BUFFILESIZE];
+ BufFilePtr f;
+} xzip_buf;
+
+static int BufZipFileClose ( BufFilePtr f, int flag );
+static int BufZipFileFill ( BufFilePtr f );
+static int BufZipFileSkip ( BufFilePtr f, int c );
+static int BufCheckZipHeader ( BufFilePtr f );
+
+BufFilePtr
+BufFilePushZIP (BufFilePtr f)
+{
+ xzip_buf *x;
+
+ x = malloc (sizeof (xzip_buf));
+ if (!x) return 0;
+ /* these are just for raw calloc/free */
+ x->z.zalloc = Z_NULL;
+ x->z.zfree = Z_NULL;
+ x->z.opaque = Z_NULL;
+ x->f = f;
+
+ /* force inflateInit to allocate it's own history buffer */
+ x->z.next_in = Z_NULL;
+ x->z.next_out = Z_NULL;
+ x->z.avail_in = x->z.avail_out = 0;
+
+ /* using negative windowBits sets "nowrap" mode, which turns off
+ zlib header checking [undocumented, for gzip compatibility only?] */
+ x->zstat = inflateInit2(&(x->z), -MAX_WBITS);
+ if (x->zstat != Z_OK) {
+ free(x);
+ return 0;
+ }
+
+ /* now that the history buffer is allocated, we provide the data buffer */
+ x->z.next_out = x->b;
+ x->z.avail_out = BUFFILESIZE;
+ x->z.next_out = x->b_in;
+ x->z.avail_in = 0;
+
+ if (BufCheckZipHeader(x->f)) {
+ free(x);
+ return 0;
+ }
+
+ return BufFileCreate((char *)x,
+ BufZipFileFill,
+ 0,
+ BufZipFileSkip,
+ BufZipFileClose);
+}
+
+static int
+BufZipFileClose(BufFilePtr f, int flag)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+ inflateEnd (&(x->z));
+ BufFileClose (x->f, flag);
+ free (x);
+ return 1;
+}
+
+/* here's the real work.
+ -- we need to put stuff in f.buffer, update f.left and f.bufp,
+ then return the first byte (or BUFFILEEOF).
+ -- to do this, we need to get stuff into avail_in, and next_in,
+ and call inflate appropriately.
+ -- we may also need to add CRC maintenance - if inflate tells us
+ Z_STREAM_END, we then have 4bytes CRC and 4bytes length...
+ gzio.c:gzread shows most of the mechanism.
+ */
+static int
+BufZipFileFill (BufFilePtr f)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+
+ /* we only get called when left == 0... */
+ /* but just in case, deal */
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ }
+ /* did we run out last time? */
+ switch (x->zstat) {
+ case Z_OK:
+ break;
+ case Z_STREAM_END:
+ case Z_DATA_ERROR:
+ case Z_ERRNO:
+ f->left = 0;
+ return BUFFILEEOF;
+ default:
+ return BUFFILEEOF;
+ }
+ /* now we work to consume what we can */
+ /* let zlib know what we can handle */
+ x->z.next_out = x->b;
+ x->z.avail_out = BUFFILESIZE;
+
+ /* and try to consume all of it */
+ while (x->z.avail_out > 0) {
+ /* if we don't have anything to work from... */
+ if (x->z.avail_in == 0) {
+ /* ... fill the z buf from underlying file */
+ int i, c;
+ for (i = 0; i < sizeof(x->b_in); i++) {
+ c = BufFileGet(x->f);
+ if (c == BUFFILEEOF) break;
+ x->b_in[i] = c;
+ }
+ x->z.avail_in += i;
+ x->z.next_in = x->b_in;
+ }
+ /* so now we have some output space and some input data */
+ x->zstat = inflate(&(x->z), Z_NO_FLUSH);
+ /* the inflation output happens in the f buffer directly... */
+ if (x->zstat == Z_STREAM_END) {
+ /* deal with EOF, crc */
+ break;
+ }
+ if (x->zstat != Z_OK) {
+ break;
+ }
+ }
+ f->bufp = x->b;
+ f->left = BUFFILESIZE - x->z.avail_out;
+
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ } else {
+ return BUFFILEEOF;
+ }
+}
+
+/* there should be a BufCommonSkip... */
+static int
+BufZipFileSkip (BufFilePtr f, int c)
+{
+ /* BufFileRawSkip returns the count unchanged.
+ BufCompressedSkip returns 0.
+ That means it probably never gets called... */
+ int retval = c;
+ while(c--) {
+ int get = BufFileGet(f);
+ if (get == BUFFILEEOF) return get;
+ }
+ return retval;
+}
+
+/* now we need to duplicate check_header */
+/* contents:
+ 0x1f, 0x8b -- magic number
+ 1 byte -- method (Z_DEFLATED)
+ 1 byte -- flags (mask with RESERVED -> fail)
+ 4 byte -- time (discard)
+ 1 byte -- xflags (discard)
+ 1 byte -- "os" code (discard)
+ [if flags & EXTRA_FIELD:
+ 2 bytes -- LSBfirst length n
+ n bytes -- extra data (discard)]
+ [if flags & ORIG_NAME:
+ n bytes -- null terminated name (discard)]
+ [if flags & COMMENT:
+ n bytes -- null terminated comment (discard)]
+ [if flags & HEAD_CRC:
+ 2 bytes -- crc of headers? (discard)]
+ */
+
+/* gzip flag byte -- from gzio.c */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+#define GET(f) do {c = BufFileGet(f); if (c == BUFFILEEOF) return c;} while(0)
+static int
+BufCheckZipHeader(BufFilePtr f)
+{
+ int c, flags;
+ GET(f); if (c != 0x1f) return 1; /* magic 1 */
+ GET(f); if (c != 0x8b) return 2; /* magic 2 */
+ GET(f); if (c != Z_DEFLATED) return 3; /* method */
+ GET(f); if (c & RESERVED) return 4; /* reserved flags */
+ flags = c;
+ GET(f); GET(f); GET(f); GET(f); /* time */
+ GET(f); /* xflags */
+ GET(f); /* os code */
+ if (flags & EXTRA_FIELD) {
+ int len;
+ GET(f); len = c;
+ GET(f); len += (c<<8);
+ while (len-- >= 0) {
+ GET(f);
+ }
+ }
+ if (flags & ORIG_NAME) {
+ do { GET(f); } while (c != 0);
+ }
+ if (flags & COMMENT) {
+ do { GET(f); } while (c != 0);
+ }
+ if (flags & HEAD_CRC) {
+ GET(f); GET(f); /* header crc */
+ }
+ return 0;
+}
|