1f13a03d8SXin LI /* $NetBSD: zuncompress.c,v 1.11 2011/08/16 13:55:02 joerg Exp $ */
29a9ea25fSXin LI
39a9ea25fSXin LI /*-
48a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
58a16b7a1SPedro F. Giffuni *
69a9ea25fSXin LI * Copyright (c) 1985, 1986, 1992, 1993
79a9ea25fSXin LI * The Regents of the University of California. All rights reserved.
89a9ea25fSXin LI *
99a9ea25fSXin LI * This code is derived from software contributed to Berkeley by
109a9ea25fSXin LI * Diomidis Spinellis and James A. Woods, derived from original
119a9ea25fSXin LI * work by Spencer Thomas and Joseph Orost.
129a9ea25fSXin LI *
139a9ea25fSXin LI * Redistribution and use in source and binary forms, with or without
149a9ea25fSXin LI * modification, are permitted provided that the following conditions
159a9ea25fSXin LI * are met:
169a9ea25fSXin LI * 1. Redistributions of source code must retain the above copyright
179a9ea25fSXin LI * notice, this list of conditions and the following disclaimer.
189a9ea25fSXin LI * 2. Redistributions in binary form must reproduce the above copyright
199a9ea25fSXin LI * notice, this list of conditions and the following disclaimer in the
209a9ea25fSXin LI * documentation and/or other materials provided with the distribution.
219a9ea25fSXin LI * 3. Neither the name of the University nor the names of its contributors
229a9ea25fSXin LI * may be used to endorse or promote products derived from this software
239a9ea25fSXin LI * without specific prior written permission.
249a9ea25fSXin LI *
259a9ea25fSXin LI * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
269a9ea25fSXin LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
279a9ea25fSXin LI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
289a9ea25fSXin LI * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
299a9ea25fSXin LI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
309a9ea25fSXin LI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
319a9ea25fSXin LI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
329a9ea25fSXin LI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
339a9ea25fSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
349a9ea25fSXin LI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
359a9ea25fSXin LI * SUCH DAMAGE.
369a9ea25fSXin LI *
379a9ea25fSXin LI * from: NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp
389a9ea25fSXin LI */
399a9ea25fSXin LI
409a9ea25fSXin LI /* This file is #included by gzip.c */
419a9ea25fSXin LI
429a9ea25fSXin LI static int zread(void *, char *, int);
439a9ea25fSXin LI
449a9ea25fSXin LI #define tab_prefixof(i) (zs->zs_codetab[i])
459a9ea25fSXin LI #define tab_suffixof(i) ((char_type *)(zs->zs_htab))[i]
469a9ea25fSXin LI #define de_stack ((char_type *)&tab_suffixof(1 << BITS))
479a9ea25fSXin LI
489a9ea25fSXin LI #define BITS 16 /* Default bits. */
499a9ea25fSXin LI #define HSIZE 69001 /* 95% occupancy */ /* XXX may not need HSIZE */
509a9ea25fSXin LI #define BIT_MASK 0x1f /* Defines for third byte of header. */
519a9ea25fSXin LI #define BLOCK_MASK 0x80
529a9ea25fSXin LI #define CHECK_GAP 10000 /* Ratio check interval. */
539a9ea25fSXin LI #define BUFSIZE (64 * 1024)
549a9ea25fSXin LI
559a9ea25fSXin LI /*
569a9ea25fSXin LI * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
579a9ea25fSXin LI * a fourth header byte (for expansion).
589a9ea25fSXin LI */
599a9ea25fSXin LI #define INIT_BITS 9 /* Initial number of bits/code. */
609a9ea25fSXin LI
619a9ea25fSXin LI /*
629a9ea25fSXin LI * the next two codes should not be changed lightly, as they must not
639a9ea25fSXin LI * lie within the contiguous general code space.
649a9ea25fSXin LI */
659a9ea25fSXin LI #define FIRST 257 /* First free entry. */
669a9ea25fSXin LI #define CLEAR 256 /* Table clear output code. */
679a9ea25fSXin LI
689a9ea25fSXin LI
699a9ea25fSXin LI #define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
709a9ea25fSXin LI
719a9ea25fSXin LI typedef long code_int;
729a9ea25fSXin LI typedef long count_int;
739a9ea25fSXin LI typedef u_char char_type;
749a9ea25fSXin LI
759a9ea25fSXin LI static char_type magic_header[] =
769a9ea25fSXin LI {'\037', '\235'}; /* 1F 9D */
779a9ea25fSXin LI
789a9ea25fSXin LI static char_type rmask[9] =
799a9ea25fSXin LI {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
809a9ea25fSXin LI
81bf70beceSEd Schouten static off_t total_compressed_bytes;
82bf70beceSEd Schouten static size_t compressed_prelen;
83bf70beceSEd Schouten static char *compressed_pre;
849a9ea25fSXin LI
859a9ea25fSXin LI struct s_zstate {
869a9ea25fSXin LI FILE *zs_fp; /* File stream for I/O */
879a9ea25fSXin LI char zs_mode; /* r or w */
889a9ea25fSXin LI enum {
899a9ea25fSXin LI S_START, S_MIDDLE, S_EOF
909a9ea25fSXin LI } zs_state; /* State of computation */
919a9ea25fSXin LI int zs_n_bits; /* Number of bits/code. */
929a9ea25fSXin LI int zs_maxbits; /* User settable max # bits/code. */
939a9ea25fSXin LI code_int zs_maxcode; /* Maximum code, given n_bits. */
949a9ea25fSXin LI code_int zs_maxmaxcode; /* Should NEVER generate this code. */
959a9ea25fSXin LI count_int zs_htab [HSIZE];
969a9ea25fSXin LI u_short zs_codetab [HSIZE];
979a9ea25fSXin LI code_int zs_hsize; /* For dynamic table sizing. */
989a9ea25fSXin LI code_int zs_free_ent; /* First unused entry. */
999a9ea25fSXin LI /*
1009a9ea25fSXin LI * Block compression parameters -- after all codes are used up,
1019a9ea25fSXin LI * and compression rate changes, start over.
1029a9ea25fSXin LI */
1039a9ea25fSXin LI int zs_block_compress;
1049a9ea25fSXin LI int zs_clear_flg;
1059a9ea25fSXin LI long zs_ratio;
1069a9ea25fSXin LI count_int zs_checkpoint;
1079a9ea25fSXin LI int zs_offset;
1089a9ea25fSXin LI long zs_in_count; /* Length of input. */
1099a9ea25fSXin LI long zs_bytes_out; /* Length of compressed output. */
1109a9ea25fSXin LI long zs_out_count; /* # of codes output (for debugging). */
1119a9ea25fSXin LI char_type zs_buf[BITS];
1129a9ea25fSXin LI union {
1139a9ea25fSXin LI struct {
1149a9ea25fSXin LI long zs_fcode;
1159a9ea25fSXin LI code_int zs_ent;
1169a9ea25fSXin LI code_int zs_hsize_reg;
1179a9ea25fSXin LI int zs_hshift;
118c4fadc2bSBenedict Reuschling } w; /* Write parameters */
1199a9ea25fSXin LI struct {
1209a9ea25fSXin LI char_type *zs_stackp;
1219a9ea25fSXin LI int zs_finchar;
1229a9ea25fSXin LI code_int zs_code, zs_oldcode, zs_incode;
1239a9ea25fSXin LI int zs_roffset, zs_size;
1249a9ea25fSXin LI char_type zs_gbuf[BITS];
1259a9ea25fSXin LI } r; /* Read parameters */
1269a9ea25fSXin LI } u;
1279a9ea25fSXin LI };
1289a9ea25fSXin LI
1299a9ea25fSXin LI static code_int getcode(struct s_zstate *zs);
1309a9ea25fSXin LI
1319a9ea25fSXin LI static off_t
zuncompress(FILE * in,FILE * out,char * pre,size_t prelen,off_t * compressed_bytes)1329a9ea25fSXin LI zuncompress(FILE *in, FILE *out, char *pre, size_t prelen,
1339a9ea25fSXin LI off_t *compressed_bytes)
1349a9ea25fSXin LI {
1359a9ea25fSXin LI off_t bin, bout = 0;
1369a9ea25fSXin LI char *buf;
1379a9ea25fSXin LI
1389a9ea25fSXin LI buf = malloc(BUFSIZE);
1399a9ea25fSXin LI if (buf == NULL)
1409a9ea25fSXin LI return -1;
1419a9ea25fSXin LI
1429a9ea25fSXin LI /* XXX */
1439a9ea25fSXin LI compressed_prelen = prelen;
1449a9ea25fSXin LI if (prelen != 0)
1459a9ea25fSXin LI compressed_pre = pre;
1469a9ea25fSXin LI else
1479a9ea25fSXin LI compressed_pre = NULL;
1489a9ea25fSXin LI
14960e56555SXin LI while ((bin = fread(buf, 1, BUFSIZE, in)) != 0) {
150b47ed83dSXin LI if (tflag == 0 && (off_t)fwrite(buf, 1, bin, out) != bin) {
1519a9ea25fSXin LI free(buf);
1529a9ea25fSXin LI return -1;
1539a9ea25fSXin LI }
1549a9ea25fSXin LI bout += bin;
1559a9ea25fSXin LI }
1569a9ea25fSXin LI
1579a9ea25fSXin LI if (compressed_bytes)
1589a9ea25fSXin LI *compressed_bytes = total_compressed_bytes;
1599a9ea25fSXin LI
1609a9ea25fSXin LI free(buf);
1619a9ea25fSXin LI return bout;
1629a9ea25fSXin LI }
1639a9ea25fSXin LI
1649a9ea25fSXin LI static int
zclose(void * zs)1659a9ea25fSXin LI zclose(void *zs)
1669a9ea25fSXin LI {
1679a9ea25fSXin LI free(zs);
1689a9ea25fSXin LI /* We leave the caller to close the fd passed to zdopen() */
1699a9ea25fSXin LI return 0;
1709a9ea25fSXin LI }
1719a9ea25fSXin LI
1729a9ea25fSXin LI FILE *
zdopen(int fd)1739a9ea25fSXin LI zdopen(int fd)
1749a9ea25fSXin LI {
1759a9ea25fSXin LI struct s_zstate *zs;
1769a9ea25fSXin LI
1779a9ea25fSXin LI if ((zs = calloc(1, sizeof(struct s_zstate))) == NULL)
1789a9ea25fSXin LI return (NULL);
1799a9ea25fSXin LI
1809a9ea25fSXin LI zs->zs_state = S_START;
1819a9ea25fSXin LI
1829a9ea25fSXin LI /* XXX we can get rid of some of these */
1839a9ea25fSXin LI zs->zs_hsize = HSIZE; /* For dynamic table sizing. */
1849a9ea25fSXin LI zs->zs_free_ent = 0; /* First unused entry. */
1859a9ea25fSXin LI zs->zs_block_compress = BLOCK_MASK;
1869a9ea25fSXin LI zs->zs_clear_flg = 0; /* XXX we calloc()'d this structure why = 0? */
1879a9ea25fSXin LI zs->zs_ratio = 0;
1889a9ea25fSXin LI zs->zs_checkpoint = CHECK_GAP;
1899a9ea25fSXin LI zs->zs_in_count = 1; /* Length of input. */
1909a9ea25fSXin LI zs->zs_out_count = 0; /* # of codes output (for debugging). */
1919a9ea25fSXin LI zs->u.r.zs_roffset = 0;
1929a9ea25fSXin LI zs->u.r.zs_size = 0;
1939a9ea25fSXin LI
1949a9ea25fSXin LI /*
1959a9ea25fSXin LI * Layering compress on top of stdio in order to provide buffering,
1969a9ea25fSXin LI * and ensure that reads and write work with the data specified.
1979a9ea25fSXin LI */
1989a9ea25fSXin LI if ((zs->zs_fp = fdopen(fd, "r")) == NULL) {
1999a9ea25fSXin LI free(zs);
2009a9ea25fSXin LI return NULL;
2019a9ea25fSXin LI }
2029a9ea25fSXin LI
2039a9ea25fSXin LI return funopen(zs, zread, NULL, NULL, zclose);
2049a9ea25fSXin LI }
2059a9ea25fSXin LI
2069a9ea25fSXin LI /*
2079a9ea25fSXin LI * Decompress read. This routine adapts to the codes in the file building
2089a9ea25fSXin LI * the "string" table on-the-fly; requiring no table to be stored in the
2099a9ea25fSXin LI * compressed file. The tables used herein are shared with those of the
2109a9ea25fSXin LI * compress() routine. See the definitions above.
2119a9ea25fSXin LI */
2129a9ea25fSXin LI static int
zread(void * cookie,char * rbp,int num)2139a9ea25fSXin LI zread(void *cookie, char *rbp, int num)
2149a9ea25fSXin LI {
2159a9ea25fSXin LI u_int count, i;
2169a9ea25fSXin LI struct s_zstate *zs;
2179a9ea25fSXin LI u_char *bp, header[3];
2189a9ea25fSXin LI
2199a9ea25fSXin LI if (num == 0)
2209a9ea25fSXin LI return (0);
2219a9ea25fSXin LI
2229a9ea25fSXin LI zs = cookie;
2239a9ea25fSXin LI count = num;
2249a9ea25fSXin LI bp = (u_char *)rbp;
2259a9ea25fSXin LI switch (zs->zs_state) {
2269a9ea25fSXin LI case S_START:
2279a9ea25fSXin LI zs->zs_state = S_MIDDLE;
2289a9ea25fSXin LI break;
2299a9ea25fSXin LI case S_MIDDLE:
2309a9ea25fSXin LI goto middle;
2319a9ea25fSXin LI case S_EOF:
2329a9ea25fSXin LI goto eof;
2339a9ea25fSXin LI }
2349a9ea25fSXin LI
2359a9ea25fSXin LI /* Check the magic number */
2369a9ea25fSXin LI for (i = 0; i < 3 && compressed_prelen; i++, compressed_prelen--)
2379a9ea25fSXin LI header[i] = *compressed_pre++;
2389a9ea25fSXin LI
2399a9ea25fSXin LI if (fread(header + i, 1, sizeof(header) - i, zs->zs_fp) !=
2409a9ea25fSXin LI sizeof(header) - i ||
2419a9ea25fSXin LI memcmp(header, magic_header, sizeof(magic_header)) != 0) {
2429a9ea25fSXin LI errno = EFTYPE;
2439a9ea25fSXin LI return (-1);
2449a9ea25fSXin LI }
2459a9ea25fSXin LI total_compressed_bytes = 0;
2469a9ea25fSXin LI zs->zs_maxbits = header[2]; /* Set -b from file. */
2479a9ea25fSXin LI zs->zs_block_compress = zs->zs_maxbits & BLOCK_MASK;
2489a9ea25fSXin LI zs->zs_maxbits &= BIT_MASK;
2499a9ea25fSXin LI zs->zs_maxmaxcode = 1L << zs->zs_maxbits;
250a06534c3SBjoern A. Zeeb if (zs->zs_maxbits > BITS || zs->zs_maxbits < 12) {
2519a9ea25fSXin LI errno = EFTYPE;
2529a9ea25fSXin LI return (-1);
2539a9ea25fSXin LI }
2549a9ea25fSXin LI /* As above, initialize the first 256 entries in the table. */
2559a9ea25fSXin LI zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS);
2569a9ea25fSXin LI for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0; zs->u.r.zs_code--) {
2579a9ea25fSXin LI tab_prefixof(zs->u.r.zs_code) = 0;
2589a9ea25fSXin LI tab_suffixof(zs->u.r.zs_code) = (char_type) zs->u.r.zs_code;
2599a9ea25fSXin LI }
2609a9ea25fSXin LI zs->zs_free_ent = zs->zs_block_compress ? FIRST : 256;
2619a9ea25fSXin LI
262a06534c3SBjoern A. Zeeb zs->u.r.zs_oldcode = -1;
2639a9ea25fSXin LI zs->u.r.zs_stackp = de_stack;
2649a9ea25fSXin LI
2659a9ea25fSXin LI while ((zs->u.r.zs_code = getcode(zs)) > -1) {
2669a9ea25fSXin LI
2679a9ea25fSXin LI if ((zs->u.r.zs_code == CLEAR) && zs->zs_block_compress) {
2689a9ea25fSXin LI for (zs->u.r.zs_code = 255; zs->u.r.zs_code >= 0;
2699a9ea25fSXin LI zs->u.r.zs_code--)
2709a9ea25fSXin LI tab_prefixof(zs->u.r.zs_code) = 0;
2719a9ea25fSXin LI zs->zs_clear_flg = 1;
272a06534c3SBjoern A. Zeeb zs->zs_free_ent = FIRST;
273a06534c3SBjoern A. Zeeb zs->u.r.zs_oldcode = -1;
274a06534c3SBjoern A. Zeeb continue;
2759a9ea25fSXin LI }
2769a9ea25fSXin LI zs->u.r.zs_incode = zs->u.r.zs_code;
2779a9ea25fSXin LI
2789a9ea25fSXin LI /* Special case for KwKwK string. */
2799a9ea25fSXin LI if (zs->u.r.zs_code >= zs->zs_free_ent) {
280a06534c3SBjoern A. Zeeb if (zs->u.r.zs_code > zs->zs_free_ent ||
281a06534c3SBjoern A. Zeeb zs->u.r.zs_oldcode == -1) {
282a06534c3SBjoern A. Zeeb /* Bad stream. */
283*216f72f1SXin LI errno = EFTYPE;
284a06534c3SBjoern A. Zeeb return (-1);
285a06534c3SBjoern A. Zeeb }
2869a9ea25fSXin LI *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar;
2879a9ea25fSXin LI zs->u.r.zs_code = zs->u.r.zs_oldcode;
2889a9ea25fSXin LI }
289a06534c3SBjoern A. Zeeb /*
290a06534c3SBjoern A. Zeeb * The above condition ensures that code < free_ent.
291a06534c3SBjoern A. Zeeb * The construction of tab_prefixof in turn guarantees that
292a06534c3SBjoern A. Zeeb * each iteration decreases code and therefore stack usage is
293a06534c3SBjoern A. Zeeb * bound by 1 << BITS - 256.
294a06534c3SBjoern A. Zeeb */
2959a9ea25fSXin LI
2969a9ea25fSXin LI /* Generate output characters in reverse order. */
2979a9ea25fSXin LI while (zs->u.r.zs_code >= 256) {
2989a9ea25fSXin LI *zs->u.r.zs_stackp++ = tab_suffixof(zs->u.r.zs_code);
2999a9ea25fSXin LI zs->u.r.zs_code = tab_prefixof(zs->u.r.zs_code);
3009a9ea25fSXin LI }
3019a9ea25fSXin LI *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar = tab_suffixof(zs->u.r.zs_code);
3029a9ea25fSXin LI
3039a9ea25fSXin LI /* And put them out in forward order. */
3049a9ea25fSXin LI middle: do {
3059a9ea25fSXin LI if (count-- == 0)
3069a9ea25fSXin LI return (num);
3079a9ea25fSXin LI *bp++ = *--zs->u.r.zs_stackp;
3089a9ea25fSXin LI } while (zs->u.r.zs_stackp > de_stack);
3099a9ea25fSXin LI
3109a9ea25fSXin LI /* Generate the new entry. */
311a06534c3SBjoern A. Zeeb if ((zs->u.r.zs_code = zs->zs_free_ent) < zs->zs_maxmaxcode &&
312a06534c3SBjoern A. Zeeb zs->u.r.zs_oldcode != -1) {
3139a9ea25fSXin LI tab_prefixof(zs->u.r.zs_code) = (u_short) zs->u.r.zs_oldcode;
3149a9ea25fSXin LI tab_suffixof(zs->u.r.zs_code) = zs->u.r.zs_finchar;
3159a9ea25fSXin LI zs->zs_free_ent = zs->u.r.zs_code + 1;
3169a9ea25fSXin LI }
3179a9ea25fSXin LI
3189a9ea25fSXin LI /* Remember previous code. */
3199a9ea25fSXin LI zs->u.r.zs_oldcode = zs->u.r.zs_incode;
3209a9ea25fSXin LI }
3219a9ea25fSXin LI zs->zs_state = S_EOF;
3229a9ea25fSXin LI eof: return (num - count);
3239a9ea25fSXin LI }
3249a9ea25fSXin LI
3259a9ea25fSXin LI /*-
3269a9ea25fSXin LI * Read one code from the standard input. If EOF, return -1.
3279a9ea25fSXin LI * Inputs:
3289a9ea25fSXin LI * stdin
3299a9ea25fSXin LI * Outputs:
3309a9ea25fSXin LI * code or -1 is returned.
3319a9ea25fSXin LI */
3329a9ea25fSXin LI static code_int
getcode(struct s_zstate * zs)3339a9ea25fSXin LI getcode(struct s_zstate *zs)
3349a9ea25fSXin LI {
3359a9ea25fSXin LI code_int gcode;
3369a9ea25fSXin LI int r_off, bits, i;
3379a9ea25fSXin LI char_type *bp;
3389a9ea25fSXin LI
3399a9ea25fSXin LI bp = zs->u.r.zs_gbuf;
3409a9ea25fSXin LI if (zs->zs_clear_flg > 0 || zs->u.r.zs_roffset >= zs->u.r.zs_size ||
3419a9ea25fSXin LI zs->zs_free_ent > zs->zs_maxcode) {
3429a9ea25fSXin LI /*
3439a9ea25fSXin LI * If the next entry will be too big for the current gcode
3449a9ea25fSXin LI * size, then we must increase the size. This implies reading
3459a9ea25fSXin LI * a new buffer full, too.
3469a9ea25fSXin LI */
3479a9ea25fSXin LI if (zs->zs_free_ent > zs->zs_maxcode) {
3489a9ea25fSXin LI zs->zs_n_bits++;
3499a9ea25fSXin LI if (zs->zs_n_bits == zs->zs_maxbits) /* Won't get any bigger now. */
3509a9ea25fSXin LI zs->zs_maxcode = zs->zs_maxmaxcode;
3519a9ea25fSXin LI else
3529a9ea25fSXin LI zs->zs_maxcode = MAXCODE(zs->zs_n_bits);
3539a9ea25fSXin LI }
3549a9ea25fSXin LI if (zs->zs_clear_flg > 0) {
3559a9ea25fSXin LI zs->zs_maxcode = MAXCODE(zs->zs_n_bits = INIT_BITS);
3569a9ea25fSXin LI zs->zs_clear_flg = 0;
3579a9ea25fSXin LI }
3589a9ea25fSXin LI /* XXX */
3599a9ea25fSXin LI for (i = 0; i < zs->zs_n_bits && compressed_prelen; i++, compressed_prelen--)
3609a9ea25fSXin LI zs->u.r.zs_gbuf[i] = *compressed_pre++;
3619a9ea25fSXin LI zs->u.r.zs_size = fread(zs->u.r.zs_gbuf + i, 1, zs->zs_n_bits - i, zs->zs_fp);
3629a9ea25fSXin LI zs->u.r.zs_size += i;
3639a9ea25fSXin LI if (zs->u.r.zs_size <= 0) /* End of file. */
3649a9ea25fSXin LI return (-1);
3659a9ea25fSXin LI zs->u.r.zs_roffset = 0;
3669a9ea25fSXin LI
3679a9ea25fSXin LI total_compressed_bytes += zs->u.r.zs_size;
3689a9ea25fSXin LI
3699a9ea25fSXin LI /* Round size down to integral number of codes. */
3709a9ea25fSXin LI zs->u.r.zs_size = (zs->u.r.zs_size << 3) - (zs->zs_n_bits - 1);
3719a9ea25fSXin LI }
3729a9ea25fSXin LI r_off = zs->u.r.zs_roffset;
3739a9ea25fSXin LI bits = zs->zs_n_bits;
3749a9ea25fSXin LI
3759a9ea25fSXin LI /* Get to the first byte. */
3769a9ea25fSXin LI bp += (r_off >> 3);
3779a9ea25fSXin LI r_off &= 7;
3789a9ea25fSXin LI
3799a9ea25fSXin LI /* Get first part (low order bits). */
3809a9ea25fSXin LI gcode = (*bp++ >> r_off);
3819a9ea25fSXin LI bits -= (8 - r_off);
3829a9ea25fSXin LI r_off = 8 - r_off; /* Now, roffset into gcode word. */
3839a9ea25fSXin LI
3849a9ea25fSXin LI /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
3859a9ea25fSXin LI if (bits >= 8) {
3869a9ea25fSXin LI gcode |= *bp++ << r_off;
3879a9ea25fSXin LI r_off += 8;
3889a9ea25fSXin LI bits -= 8;
3899a9ea25fSXin LI }
3909a9ea25fSXin LI
3919a9ea25fSXin LI /* High order bits. */
3929a9ea25fSXin LI gcode |= (*bp & rmask[bits]) << r_off;
3939a9ea25fSXin LI zs->u.r.zs_roffset += zs->zs_n_bits;
3949a9ea25fSXin LI
3959a9ea25fSXin LI return (gcode);
3969a9ea25fSXin LI }
3979a9ea25fSXin LI
398