]> git.saurik.com Git - apple/boot.git/blob - i386/rcz/rcz_decompress_file.c
ad3485c4deaf32d6769d7d94e5d8e334cacbc542
[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 * 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>
37 static unsigned short que[QLEN];
38
39 #define REWIND -1
40
41 // extern int read(int fd, char *buf, int len);
42 extern int b_lseek(int fdesc, unsigned int addr, int ptr);
43
44 static unsigned char *buf;
45 static int buf_count;
46
47 #define BUF_SIZE 8192
48
49 static void
50 alloc_buf(int fd)
51 {
52 buf = (unsigned char *)malloc(BUF_SIZE);
53 buf_count = 0;
54 }
55
56 static unsigned char
57 get_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
71 static void
72 free_buf(void)
73 {
74 buf_count = 0;
75 free(buf);
76 }
77
78
79 int
80 rcz_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
107 int
108 rcz_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 }