]> git.saurik.com Git - apple/boot.git/blame_incremental - i386/rcz/rcz_decompress_file.c
boot-132.tar.gz
[apple/boot.git] / i386 / rcz / rcz_decompress_file.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 Library: compressor for executable files.
26
27 R. E. Crandall, July 1995
28
29 Copyright 1995 NeXT Computer, Inc.
30 All rights reserved.
31
32 */
33
34#include "rcz_common.h"
35#include <stdlib.h>
36#include <unistd.h>
37static unsigned short que[QLEN];
38
39#define REWIND -1
40
41// extern int read(int fd, char *buf, int len);
42extern int b_lseek(int fdesc, unsigned int addr, int ptr);
43
44static unsigned char *buf;
45static int buf_count;
46
47#define BUF_SIZE 8192
48
49static void
50alloc_buf(int fd)
51{
52 buf = (unsigned char *)malloc(BUF_SIZE);
53 buf_count = 0;
54}
55
56static unsigned char
57get_byte(int fd)
58{
59 static unsigned char *ptr;
60
61 if (buf_count == 0) {
62 buf_count = read(fd, buf, BUF_SIZE);
63 ptr = buf;
64 if (buf_count <= 0)
65 return 0xFF;
66 }
67 buf_count--;
68 return *ptr++;
69}
70
71static void
72free_buf(void)
73{
74 buf_count = 0;
75 free(buf);
76}
77
78
79int
80rcz_file_size(
81 int in_fd
82)
83{
84 unsigned int version, length;
85
86 alloc_buf(in_fd);
87 b_lseek(in_fd, 0, 0);
88 version = get_byte(in_fd);
89 version = (version<<8) | (get_byte(in_fd));
90 version = (version<<8) | (get_byte(in_fd));
91 version = (version<<8) | (get_byte(in_fd));
92
93 if(version != METHOD_17_JUL_95) {
94 return (-1);
95// fprintf(stderr, "Incompatible version.\n");
96// return(0);
97 }
98
99 length = get_byte(in_fd);
100 length = (length<<8) | (get_byte(in_fd));
101 length = (length<<8) | (get_byte(in_fd));
102 length = (length<<8) | (get_byte(in_fd));
103 free_buf();
104 return length;
105}
106
107int
108rcz_decompress_file(
109 int in_fd,
110 unsigned char *out
111)
112/* Returns actual number of bytes emitted as decompressed stream 'out.'
113 Note that the 'in' stream contains this byte count already.
114
115 Returns -1 if the input stream was not in compressed format.
116 */
117{
118 unsigned int c, j, k, jmatch, jabove;
119 int length;
120 int even_length, word, token;
121 unsigned char *outorigin = out;
122
123 length = rcz_file_size(in_fd);
124 if (length < 0)
125 return length;
126
127 alloc_buf(in_fd);
128 b_lseek(in_fd, 8, 0);
129 for(c=0; c < QLEN; c++) que[c] = c;
130 even_length = 2*(length/2);
131 while((int)(out-outorigin) < even_length) {
132 token = get_byte(in_fd);
133 token = (token<<8) | (get_byte(in_fd));
134 token = (token<<8) | (get_byte(in_fd));
135 token = (token<<8) | (get_byte(in_fd));
136 c = 1<<31;
137 for(k = 0; k<32; k++) {
138 if(c & token) {
139 jmatch = get_byte(in_fd);
140 word = que[jmatch];
141 /* Next, dynamically process the queue for match. */
142 jabove = (F1*jmatch) >> 4;
143 for(j = jmatch; j > jabove; j--) {
144 que[j] = que[j-1];
145 }
146 que[jabove] = word;
147 } else {
148 /* Next, dynamically process the queue for unmatch. */
149 word = get_byte(in_fd);
150 word = (word << 8) | (get_byte(in_fd));
151 for(j=QLEN-1; j > ABOVE; j--) {
152 que[j] = que[j-1];
153 }
154 que[ABOVE] = word;
155 }
156 *out++ = (word >> 8) & 0xff;
157 *out++ = (word) & 0xff;
158 if((int)(out-outorigin) >= even_length) break;
159 c >>= 1;
160 }
161 }
162 if(even_length != length) *out++ = get_byte(in_fd);
163 free_buf();
164 return(length);
165}