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