4
* Copyright (C) 2005 trog@uncon.org
6
* This code is based on the work of Alexander L. Roshal
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
31
#define rar_dbgmsg printf
33
static void rar_dbgmsg(const char* fmt,...){}
36
void unpack_init_data20(int solid, unpack_data_t *unpack_data)
39
unpack_data->unp_channel_delta = 0;
40
unpack_data->unp_cur_channel = 0;
41
unpack_data->unp_channels = 1;
42
memset(unpack_data->audv, 0, sizeof(unpack_data->audv));
43
memset(unpack_data->unp_old_table20, 0, sizeof(unpack_data->unp_old_table20));
47
static void copy_string20(unpack_data_t *unpack_data, unsigned int length, unsigned int distance)
49
unsigned int dest_ptr;
51
unpack_data->last_dist = unpack_data->old_dist[unpack_data->old_dist_ptr++ & 3] = distance;
52
unpack_data->last_length = length;
53
unpack_data->dest_unp_size -= length;
55
dest_ptr = unpack_data->unp_ptr - distance;
56
if (dest_ptr < MAXWINSIZE-300 && unpack_data->unp_ptr < MAXWINSIZE-300) {
57
unpack_data->window[unpack_data->unp_ptr++] = unpack_data->window[dest_ptr++];
58
unpack_data->window[unpack_data->unp_ptr++] = unpack_data->window[dest_ptr++];
61
unpack_data->window[unpack_data->unp_ptr++] = unpack_data->window[dest_ptr++];
63
} else while (length--) {
64
unpack_data->window[unpack_data->unp_ptr] = unpack_data->window[dest_ptr++ & MAXWINMASK];
65
unpack_data->unp_ptr = (unpack_data->unp_ptr+1) & MAXWINMASK;
69
static int read_tables20(int fd, unpack_data_t *unpack_data)
71
unsigned char bit_length[BC20];
72
unsigned char table[MC20 * 4];
73
int table_size, n, i, number;
74
unsigned int bit_field;
76
rar_dbgmsg("in read_tables20\n");
78
if (unpack_data->in_addr > unpack_data->read_top-25) {
79
if (!unp_read_buf(fd, unpack_data)) {
83
bit_field = getbits(unpack_data);
84
unpack_data->unp_audio_block = (bit_field & 0x8000);
86
if (!(bit_field & 0x4000)) {
87
memset(unpack_data->unp_old_table20, 0, sizeof(unpack_data->unp_old_table20));
89
addbits(unpack_data, 2);
91
if (unpack_data->unp_audio_block) {
92
unpack_data->unp_channels = ((bit_field>>12) & 3) + 1;
93
if (unpack_data->unp_cur_channel >= unpack_data->unp_channels) {
94
unpack_data->unp_cur_channel = 0;
96
addbits(unpack_data, 2);
97
table_size = MC20 * unpack_data->unp_channels;
99
table_size = NC20+DC20+RC20;
102
for (i=0 ; i < BC20 ; i++) {
103
bit_length[i] = (unsigned char) (getbits(unpack_data) >> 12);
104
addbits(unpack_data, 4);
106
make_decode_tables(bit_length, (struct Decode *)&unpack_data->BD, BC20);
108
while (i < table_size) {
109
if (unpack_data->in_addr > unpack_data->read_top-5) {
110
if (!unp_read_buf(fd, unpack_data)) {
114
number = decode_number(unpack_data, (struct Decode *)&unpack_data->BD);
116
table[i] = (number + unpack_data->unp_old_table20[i]) & 0xf;
118
} else if (number == 16) {
119
n = (getbits(unpack_data) >> 14) + 3;
120
addbits(unpack_data, 2);
121
while ((n-- > 0) && (i < table_size)) {
122
table[i] = table[i-1];
127
n = (getbits(unpack_data) >> 13) + 3;
128
addbits(unpack_data, 3);
130
n = (getbits(unpack_data) >> 9) + 11;
131
addbits(unpack_data, 7);
133
while ((n-- > 0) && (i < table_size)) {
138
if (unpack_data->in_addr > unpack_data->read_top) {
141
if (unpack_data->unp_audio_block) {
142
for (i=0 ; i < unpack_data->unp_channels ; i++) {
143
make_decode_tables(&table[i*MC20], (struct Decode *)&unpack_data->MD[i], MC20);
146
make_decode_tables(&table[0], (struct Decode *)&unpack_data->LD, NC20);
147
make_decode_tables(&table[NC20], (struct Decode *)&unpack_data->DD, DC20);
148
make_decode_tables(&table[NC20+DC20], (struct Decode *)&unpack_data->RD, RC20);
150
memcpy(unpack_data->unp_old_table20, table, sizeof(unpack_data->unp_old_table20));
154
static void read_last_tables(int fd, unpack_data_t *unpack_data)
156
if (unpack_data->read_top >= unpack_data->in_addr+5) {
157
if (unpack_data->unp_audio_block) {
158
if (decode_number(unpack_data,
159
(struct Decode *)&unpack_data->MD[unpack_data->unp_cur_channel]) == 256) {
160
read_tables20(fd, unpack_data);
162
} else if (decode_number(unpack_data, (struct Decode *)&unpack_data->LD) == 269) {
163
read_tables20(fd, unpack_data);
168
static unsigned char decode_audio(unpack_data_t *unpack_data, int delta)
170
struct AudioVariables *v;
172
unsigned int ch, mindif, num_min_dif;
174
v = &unpack_data->audv[unpack_data->unp_cur_channel];
178
v->D2 = v->last_delta - v->D1;
179
v->D1 = v->last_delta;
181
pch = 8 * v->last_char + v->K1 * v->D1 + v->K2 * v->D2 + v->K3 *
182
v->D3 + v->K4 * v->D4 + v->K5 * unpack_data->unp_channel_delta;
183
pch = (pch >> 3) & 0xff;
187
d = ((signed char) delta) << 3;
190
v->dif[1] += abs(d - v->D1);
191
v->dif[2] += abs(d + v->D1);
192
v->dif[3] += abs(d - v->D2);
193
v->dif[4] += abs(d + v->D2);
194
v->dif[5] += abs(d - v->D3);
195
v->dif[6] += abs(d + v->D3);
196
v->dif[7] += abs(d - v->D4);
197
v->dif[8] += abs(d + v->D4);
198
v->dif[9] += abs(d - unpack_data->unp_channel_delta);
199
v->dif[10] += abs(d + unpack_data->unp_channel_delta);
201
unpack_data->unp_channel_delta = v->last_delta = (signed char) (ch - v->last_char);
204
if ((v->byte_count & 0x1f) == 0) {
208
for (i = 1 ; i < 11 ; i++) {
209
if (v->dif[i] < mindif) {
213
v->dif[i]=0; /* ?????? looks wrong to me */
215
switch(num_min_dif) {
268
return ((unsigned char) ch);
271
int rar_unpack20(int fd, int solid, unpack_data_t *unpack_data)
273
unsigned char ldecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,
274
32,40,48,56,64,80,96,112,128,160,192,224};
275
unsigned char lbits[]={0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5};
276
int ddecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,
277
768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,
278
32768U,49152U,65536,98304,131072,196608,262144,327680,393216,
279
458752,524288,589824,655360,720896,786432,851968,917504,983040};
280
unsigned char dbits[]={0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,
281
12,12,13,13,14,14,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16};
282
unsigned char sddecode[]={0,4,8,16,32,64,128,192};
283
unsigned char sdbits[]={2,2,3,4,5,6,6,6};
284
unsigned int bits, distance;
285
int retval=TRUE, audio_number, number, length, dist_number, length_number;
287
rar_dbgmsg("in rar_unpack20\n");
289
unpack_init_data(solid, unpack_data);
290
if (!unp_read_buf(fd, unpack_data)) {
291
cli_dbgmsg("unp_read_buf 1 failed\n");
295
if (!read_tables20(fd, unpack_data)) {
296
cli_dbgmsg("read_tables20 failed\n");
300
--unpack_data->dest_unp_size;
302
while (unpack_data->dest_unp_size >= 0) {
303
rar_dbgmsg("dest_unp_size = %ld\n", unpack_data->dest_unp_size);
304
unpack_data->unp_ptr &= MAXWINMASK;
306
if (unpack_data->in_addr > unpack_data->read_top-30) {
307
if (!unp_read_buf(fd, unpack_data)) {
308
cli_dbgmsg("unp_read_buf 2 failed\n");
312
if (((unpack_data->wr_ptr - unpack_data->unp_ptr) & MAXWINMASK) < 270 &&
313
(unpack_data->wr_ptr != unpack_data->unp_ptr)) {
314
unp_write_buf_old(unpack_data);
316
if (unpack_data->unp_audio_block) {
317
audio_number = decode_number(unpack_data,
318
(struct Decode *)&unpack_data->MD[unpack_data->unp_cur_channel]);
319
if (audio_number == 256) {
320
if (!read_tables20(fd, unpack_data)) {
326
unpack_data->window[unpack_data->unp_ptr++] =
327
decode_audio(unpack_data, audio_number);
328
if (++unpack_data->unp_cur_channel == unpack_data->unp_channels) {
329
unpack_data->unp_cur_channel = 0;
331
--unpack_data->dest_unp_size;
335
number = decode_number(unpack_data, (struct Decode *)&unpack_data->LD);
337
unpack_data->window[unpack_data->unp_ptr++] = (unsigned char) number;
338
--unpack_data->dest_unp_size;
342
length = ldecode[number-=270]+3;
343
if ((bits = lbits[number]) > 0) {
344
length += getbits(unpack_data) >> (16-bits);
345
addbits(unpack_data, bits);
348
dist_number = decode_number(unpack_data, (struct Decode *)&unpack_data->DD);
349
distance = ddecode[dist_number] + 1;
350
if ((bits = dbits[dist_number]) > 0) {
351
distance += getbits(unpack_data)>>(16-bits);
352
addbits(unpack_data, bits);
355
if (distance >= 0x2000) {
357
if (distance >= 0x40000L) {
362
copy_string20(unpack_data, length, distance);
366
if (!read_tables20(fd, unpack_data)) {
373
copy_string20(unpack_data, unpack_data->last_length, unpack_data->last_dist);
377
distance = unpack_data->old_dist[(unpack_data->old_dist_ptr-(number-256)) & 3];
378
length_number = decode_number(unpack_data, (struct Decode *)&unpack_data->RD);
379
length = ldecode[length_number]+2;
380
if ((bits = lbits[length_number]) > 0) {
381
length += getbits(unpack_data) >> (16-bits);
382
addbits(unpack_data, bits);
384
if (distance >= 0x101) {
386
if (distance >= 0x2000) {
388
if (distance >= 0x40000) {
393
copy_string20(unpack_data, length, distance);
397
distance = sddecode[number-=261]+1;
398
if ((bits=sdbits[number]) > 0) {
399
distance += getbits(unpack_data) >> (16-bits);
400
addbits(unpack_data, bits);
402
copy_string20(unpack_data, 2, distance);
407
read_last_tables(fd, unpack_data);
408
unp_write_buf_old(unpack_data);