]>
git.saurik.com Git - wxWidgets.git/blob - utils/Install/sfxace/uac_dcpr.c
1 /* ------------------------------------------------------------------------ */
3 /* These are the decompression algorithms. */
4 /* Don't change here anything (apart from memory allocation perhaps). */
5 /* Any changes will very likely cause bugs! */
7 /* ------------------------------------------------------------------------ */
12 #include <string.h> // mem*()
14 #if defined(DOS) || defined(WIN16) || defined(WINNT) || defined(OS2) || defined(UNIX)
15 #if !defined(__CYGWIN__)
16 #include <mem.h> // mem*()
20 #include <stdio.h> // printf()
21 #include <stdlib.h> // malloc()
36 //------------------------------ QUICKSORT ---------------------------------//
37 #define xchg_def(v1,v2) {INT dummy;\
42 void sortrange(INT left
, INT right
)
48 hyphen
= sort_freq
[right
];
50 //divides by hyphen the given range into 2 parts
53 while (sort_freq
[zl
] > hyphen
)
55 while (sort_freq
[zr
] < hyphen
)
57 //found a too small (left side) and
58 //a too big (right side) element-->exchange them
61 xchg_def(sort_freq
[zl
], sort_freq
[zr
]);
62 xchg_def(sort_org
[zl
], sort_org
[zr
]);
69 //sort partial ranges - when very small, sort directly
74 else if (sort_freq
[left
] < sort_freq
[zr
])
76 xchg_def(sort_freq
[left
], sort_freq
[zr
]);
77 xchg_def(sort_org
[left
], sort_org
[zr
]);
85 else if (sort_freq
[zl
] < sort_freq
[right
])
87 xchg_def(sort_freq
[zl
], sort_freq
[right
]);
88 xchg_def(sort_org
[zl
], sort_org
[right
]);
102 //------------------------------ read bits ---------------------------------//
107 i
= (size_rdb
- 2) << 2;
108 rpos
-= size_rdb
- 2;
109 buf_rd
[0] = buf_rd
[size_rdb
- 2];
110 buf_rd
[1] = buf_rd
[size_rdb
- 1];
111 read_adds_blk((CHAR
*) & buf_rd
[2], i
);
112 #ifdef HI_LO_BYTE_ORDER
115 i
>>=2; // count LONGs not BYTEs
126 #define addbits(bits) \
128 rpos+=(bits_rd+=bits)>>5; \
130 if (rpos==(size_rdb-2)) readdat(); \
131 code_rd=(buf_rd[rpos] << bits_rd) \
132 +((buf_rd[rpos+1] >> (32-bits_rd))&(!bits_rd-1)); \
136 //---------------------- COMMENT DECOMPRESSION -----------------------------//
138 #define comm_cpr_hf(a,b) (a+b)
140 void dcpr_comm_init(void)
144 i
= comm_cpr_size
> size_rdb
* sizeof(LONG
) ? size_rdb
* sizeof(LONG
) : comm_cpr_size
;
146 memcpy(buf_rd
, comm
, i
);
147 #ifdef HI_LO_BYTE_ORDER
150 i
>>=2; // count LONGs not BYTEs
163 void dcpr_comm(INT comm_size
)
165 SHORT hash
[comm_cpr_hf(255, 255) + 1];
172 memset(&hash
, 0, sizeof(hash
));
176 len
= code_rd
>> (32 - 15);
178 if (len
>= comm_size
)
180 if (read_wd(maxwd_mn
, dcpr_code_mn
, dcpr_wd_mn
, max_cd_mn
))
185 pos
= hash
[hs
= comm_cpr_hf(comm
[dpos
- 1], comm
[dpos
- 2])];
188 addbits(dcpr_wd_mn
[(c
= dcpr_code_mn
[code_rd
>> (32 - maxwd_mn
)])]);
189 if (rpos
== size_rdb
- 3)
196 comm
[dpos
++] = comm
[pos
++];
208 //------------------------- LZW1 DECOMPRESSION -----------------------------//
213 dcpr_text
[dcpr_dpos
] = ch
;
215 dcpr_dpos
&= dcpr_dican
;
218 void copystr(LONG d
, INT l
)
224 mpos
= dcpr_dpos
- d
;
227 if ((mpos
>= dcpr_dicsiz
- maxlength
) || (dcpr_dpos
>= dcpr_dicsiz
- maxlength
))
231 dcpr_text
[dcpr_dpos
] = dcpr_text
[mpos
];
233 dcpr_dpos
&= dcpr_dican
;
241 dcpr_text
[dcpr_dpos
++] = dcpr_text
[mpos
++];
242 dcpr_dpos
&= dcpr_dican
;
246 void decompress(void)
254 while (dcpr_do
< dcpr_do_max
)
260 addbits(dcpr_wd_mn
[(c
= dcpr_code_mn
[code_rd
>> (32 - maxwd_mn
)])]);
268 dist
= (code_rd
>> (33 - c
)) + (1L << (c
- 1));
273 dcpr_olddist
[(dcpr_oldnum
= (dcpr_oldnum
+ 1) & 3)] = dist
;
284 dist
= dcpr_olddist
[(dcpr_oldnum
- (c
&= 255)) & 3];
285 for (k
= c
+ 1; k
--;)
286 dcpr_olddist
[(dcpr_oldnum
- k
) & 3] = dcpr_olddist
[(dcpr_oldnum
- k
+ 1) & 3];
287 dcpr_olddist
[dcpr_oldnum
] = dist
;
292 addbits(dcpr_wd_lg
[(lg
= dcpr_code_lg
[code_rd
>> (32 - maxwd_lg
)])]);
302 //-------------------------- HUFFMAN ROUTINES ------------------------------//
303 INT
makecode(UINT maxwd
, UINT size1_t
, UCHAR
* wd
, USHORT
* code
)
312 memcpy(&sort_freq
, wd
, (size1_t
+ 1) * sizeof(CHAR
));
317 sort_freq
[size1_t
+ 1] = size2_t
= c
= 0;
318 while (sort_freq
[size2_t
])
324 size2_t
+= (size2_t
== 0);
328 max_make_code
= 1 << maxwd
;
329 for (i
= size2_t
+ 1; i
-- && c
< max_make_code
;)
331 maxc
= 1 << (maxwd
- sort_freq
[i
]);
333 if (c
+ maxc
> max_make_code
)
335 dcpr_do
= dcpr_do_max
;
338 memset16(&code
[c
], l
, maxc
);
344 INT
read_wd(UINT maxwd
, USHORT
* code
, UCHAR
* wd
, INT max_el
)
354 memset(wd
, 0, max_el
* sizeof(CHAR
));
355 memset(code
, 0, (1 << maxwd
) * sizeof(SHORT
));
357 num_el
= code_rd
>> (32 - 9);
362 lolim
= code_rd
>> (32 - 4);
364 uplim
= code_rd
>> (32 - 4);
367 for (i
= -1; ++i
<= uplim
;)
369 wd_svwd
[i
] = code_rd
>> (32 - 3);
372 if (!makecode(maxwd_svwd
, uplim
, wd_svwd
, code
))
377 c
= code
[code_rd
>> (32 - maxwd_svwd
)];
383 l
= (code_rd
>> 28) + 4;
385 while (l
-- && j
<= num_el
)
390 for (i
= 0; ++i
<= num_el
;)
391 wd
[i
] = (wd
[i
] + wd
[i
- 1]) % uplim
;
392 for (i
= -1; ++i
<= num_el
;)
396 return (makecode(maxwd
, num_el
, wd
, code
));
400 INT
calc_dectabs(void)
402 if (!read_wd(maxwd_mn
, dcpr_code_mn
, dcpr_wd_mn
, max_cd_mn
)
403 || !read_wd(maxwd_lg
, dcpr_code_lg
, dcpr_wd_lg
, max_cd_lg
))
406 blocksize
= code_rd
>> (32 - 15);
412 //---------------------------- BLOCK ROUTINES ------------------------------//
413 INT
decompress_blk(CHAR
* buf
, UINT len
)
415 LONG old_pos
= dcpr_dpos
;
419 if ((dcpr_do_max
= len
- maxlength
) > dcpr_size
)
420 dcpr_do_max
= dcpr_size
;
421 if ((LONG
) dcpr_size
> 0 && dcpr_do_max
)
424 if (old_pos
+ dcpr_do
> dcpr_dicsiz
)
426 i
= dcpr_dicsiz
- old_pos
;
427 memcpy(buf
, &dcpr_text
[old_pos
], i
);
428 memcpy(&buf
[i
], dcpr_text
, dcpr_do
- i
);
431 memcpy(buf
, &dcpr_text
[old_pos
], dcpr_do
);
433 dcpr_size
-= dcpr_do
;
437 INT
unstore(CHAR
* buf
, UINT len
)
444 len
= crypt_len(len
- 8); /* because of decryption */
447 while ((i
= read_adds_blk((CHAR
*) buf_rd
, (INT
) ((i
= ((len
> dcpr_size
) ? dcpr_size
: len
)) > size_rdb
? size_rdb
: i
))) != 0)
451 memcpy(&buf
[pos
], buf_rd
, i
);
455 for (i
= 0; i
< rd
; i
++)
457 dcpr_text
[dcpr_dpos
] = buf
[i
];
459 dcpr_dpos
&= dcpr_dican
;
464 INT
dcpr_adds_blk(CHAR
* buf
, UINT len
)
468 switch (fhead
.TECH
.TYPE
)
471 r
= unstore(buf
, len
);
474 r
= decompress_blk(buf
, len
);
477 error("\nFile compressed with unknown method. Decompression not possible.\n");
481 rd_crc
= getcrc(rd_crc
, (UCHAR
*)buf
, r
);
486 //----------------------------- INIT ROUTINES ------------------------------//
492 while ((dcpr_text
= malloc(dcpr_dicsiz
= (LONG
) 1 << dcpr_dic
))==NULL
)
494 dcpr_dican
= dcpr_dicsiz
- 1;
497 void dcpr_init_file(void)
507 if (head
.HEAD_FLAGS
& ACE_PASSW
)
509 error("\nFound passworded file. Decryption not supported.\n");
517 dcpr_size
= fhead
.SIZE
;
518 if (fhead
.TECH
.TYPE
== TYPE_LZW1
)
520 if ((fhead
.TECH
.PARM
& 15) + 10 > dcpr_dic
)
522 error("\nNot enough memory or dictionary of archive too large.\n");
527 i
= size_rdb
* sizeof(LONG
);
528 read_adds_blk((CHAR
*) buf_rd
, i
);
529 #ifdef HI_LO_BYTE_ORDER
532 i
>>=2; // count LONGs not BYTEs
546 if (!adat
.sol
|| dcpr_frst_file
)
550 memset(&dcpr_olddist
, 0, sizeof(dcpr_olddist
));