1 /* Based on src/fontfile/gunzip.c
2 written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
3 intended for inclusion in X11 public releases. */
6 * Copyright © 2008 Sun Microsystems, Inc. All rights reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
31 #include <X11/fonts/fontmisc.h>
32 #include <X11/fonts/bufio.h>
35 typedef struct _xzip_buf {
38 BufChar b[BUFFILESIZE];
39 BufChar b_in[BUFFILESIZE];
43 static int BufBzip2FileClose ( BufFilePtr f, int flag );
44 static int BufBzip2FileFill ( BufFilePtr f );
45 static int BufBzip2FileSkip ( BufFilePtr f, int c );
48 BufFilePushBZIP2 (BufFilePtr f)
52 x = malloc (sizeof (xzip_buf));
55 bzero(&(x->z), sizeof(bz_stream));
58 x->zstat = BZ2_bzDecompressInit(&(x->z),
59 0, /* verbosity: 0 silent, 4 max */
60 0); /* 0: go faster, 1: use less memory */
61 if (x->zstat != BZ_OK) {
66 /* now that the history buffer is allocated, we provide the data buffer */
67 x->z.next_out = (char *) x->b;
68 x->z.avail_out = BUFFILESIZE;
69 x->z.next_in = (char *) x->b_in;
72 return BufFileCreate((char *)x,
80 BufBzip2FileClose(BufFilePtr f, int flag)
82 xzip_buf *x = (xzip_buf *)f->private;
83 BZ2_bzDecompressEnd (&(x->z));
84 BufFileClose (x->f, flag);
89 /* here's the real work.
90 -- we need to put stuff in f.buffer, update f.left and f.bufp,
91 then return the first byte (or BUFFILEEOF).
92 -- to do this, we need to get stuff into avail_in, and next_in,
93 and call BZ2_bzDecompress appropriately.
94 -- we may also need to add CRC maintenance - if BZ2_bzDecompress tells us
95 BZ_STREAM_END, we then have 4bytes CRC and 4bytes length...
98 BufBzip2FileFill (BufFilePtr f)
100 xzip_buf *x = (xzip_buf *)f->private;
102 /* we only get called when left == 0... */
103 /* but just in case, deal */
108 /* did we run out last time? */
114 case BZ_DATA_ERROR_MAGIC:
120 /* now we work to consume what we can */
121 /* let libbz2 know what we can handle */
122 x->z.next_out = (char *) x->b;
123 x->z.avail_out = BUFFILESIZE;
125 /* and try to consume all of it */
126 while (x->z.avail_out > 0) {
127 /* if we don't have anything to work from... */
128 if (x->z.avail_in == 0) {
129 /* ... fill the z buf from underlying file */
131 for (i = 0; i < sizeof(x->b_in); i++) {
132 c = BufFileGet(x->f);
133 if (c == BUFFILEEOF) break;
137 x->z.next_in = (char *) x->b_in;
139 /* so now we have some output space and some input data */
140 x->zstat = BZ2_bzDecompress(&(x->z));
141 /* the inflation output happens in the f buffer directly... */
142 if (x->zstat == BZ_STREAM_END) {
143 /* deal with EOF, crc */
146 if (x->zstat != BZ_OK) {
151 f->left = BUFFILESIZE - x->z.avail_out;
161 /* there should be a BufCommonSkip... */
163 BufBzip2FileSkip (BufFilePtr f, int c)
165 /* BufFileRawSkip returns the count unchanged.
166 BufCompressedSkip returns 0.
167 That means it probably never gets called... */
170 int get = BufFileGet(f);
171 if (get == BUFFILEEOF) return get;