char os_id;
};
+struct lha_method methods[] = {
+ /* id, dicbit, pbit, maxmatch */
+ /* note: dicbit == 0 means no compress */
+ /*0*/ {"-lh0-", 0, 0, 0}, /* no compress */
+ /*1*/ {"-lh1-", 12, 0, 60}, /* 2^12 = 4KB dynamic huffman (LHarc) */
+ /*2*/ {"-lh2-", 13, 0,256}, /* 2^13 = 8KB dynamic huffman */
+ /*3*/ {"-lh3-", 13, 0,256}, /* 2^13 = 8KB static huffman */
+ /*4*/ {"-lh4-", 12, 4,256}, /* 2^12 = 4KB static huffman (pos and len)*/
+ /*5*/ {"-lh5-", 13, 4,256}, /* 2^13 = 8KB static huffman (pos and len)*/
+ /*6*/ {"-lh6-", 15, 5,256}, /* 2^15 = 32KB static huffman (pos and len)*/
+ /*7*/ {"-lh7-", 16, 5,256}, /* 2^16 = 64KB static huffman (pos and len)*/
+ /*8*/ {"-lzs-", 11, 0, 17}, /* 2^11 = 2KB (LArc) */
+ /*9*/ {"-lz5-", 12, 0, 17}, /* 2^12 = 4KB (LArc) */
+ /*10*/{"-lz4-", 0, 0, 0}, /* no compress (LArc) */
+ /*11*/{"-lzd-", 0, 0, 0}, /* directory */
+};
+
struct lha_opts opts;
+struct lha_method *
+which_method(char *id)
+{
+ int i;
+
+ for (i = 0; i < sizeof(methods)/sizeof(methods[0]); i++) {
+ if (strncmp(id, methods[i].id, sizeof(methods[0].id)) == 0) {
+ return &methods[i];
+ }
+ }
+ return NULL;
+}
+
init_opts()
{
opts.nocompress = 0;
opts.outdir = NULL;
opts.quiet = 0;
+
+ /* default is the -lh5- method */
+ opts.method = &methods[5];
}
#define FNAME_MAX (255 - 25) /* max strlen(filename) */
h.namelen = strlen(filename);
headersize = 25 + h.namelen;
- memcpy(h.method, "-lh5-", 5); /* compress */
+ memcpy(h.method, opts.method->id, sizeof(h.method)); /* compress */
headerpos = ftell(outfile);
write_header(outfile, headersize, &h);
static void
extract(int to_file, struct lzh_header *h)
{
- int n, method;
+ int n;
uint ext_headersize;
uchar buffer[DICSIZ];
printf("===== %s =====\n", h->filename);
}
crc = INIT_CRC;
- method = h->method[3]; /* -lh*5*- */
- h->method[3] = ' ';
- if (!strchr("045", method) || memcmp("-lh -", h->method, 5)) {
- fprintf(stderr, "Unknown method: %u\n", method);
+ opts.method = which_method(h->method);
+ if (opts.method == NULL) {
+ fprintf(stderr, "Unknown method: %.5s\n", h->method);
skip(arcfile, h);
}
else {
crc = INIT_CRC;
- if (method != '0')
+ if (opts.method->dicbit != 0)
decode_start();
while (h->origsize != 0) {
n = (uint) ((h->origsize > DICSIZ) ? DICSIZ : h->origsize);
- if (method != '0')
+ if (opts.method->dicbit != 0)
decode(n, buffer);
else if (fread((char *) buffer, 1, n, arcfile) != n)
error("Can't read");
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "q[012]w:z", long_options, &option_index);
+ c = getopt_long(argc, argv, "o[567]q[012]w:z",
+ long_options, &option_index);
if (c == -1) break;
switch (c) {
case 0: /* set vallue by long option */
break;
+ case 'o': /* compress method */
+ {
+ int idx;
+
+ if (optarg)
+ idx = *optarg - '0'; /* -lh[567]- method */
+ else
+ idx = 1; /* -lh1- method */
+
+ opts.method = &methods[idx];
+ }
+ break;
case 'q': /* quiet mode */
opts.quiet = 2; /* level 2 */
if (optarg)
char *archive_file;
struct lzh_header h;
+ init_opts();
+
if (argv[1] == 0)
print_usage();
static ushort c_freq[2 * NC - 1], c_table[4096], c_code[NC],
p_freq[2 * NP - 1], pt_table[256], pt_code[NPT], t_freq[2 * NT - 1];
+static int np;
+static int pbit;
+
+static void
+init_parameter(struct lha_method *m)
+{
+ np = m->dicbit + 1;
+ pbit = m->pbit;
+}
+
/***** encoding *****/
static void
putbits(CBIT, 0);
putbits(CBIT, root);
}
- root = make_tree(NP, p_freq, pt_len, pt_code);
- if (root >= NP) {
- write_pt_len(NP, PBIT, -1);
+ root = make_tree(np, p_freq, pt_len, pt_code);
+ if (root >= np) {
+ write_pt_len(np, pbit, -1);
}
else {
- putbits(PBIT, 0);
- putbits(PBIT, root);
+ putbits(pbit, 0);
+ putbits(pbit, root);
}
pos = 0;
for (i = 0; i < size; i++) {
}
for (i = 0; i < NC; i++)
c_freq[i] = 0;
- for (i = 0; i < NP; i++)
+ for (i = 0; i < np; i++)
p_freq[i] = 0;
}
}
void
-huf_encode_start(void)
+huf_encode_start(struct lha_method *m)
{
int i;
+ init_parameter(m);
+
if (bufsiz == 0) {
bufsiz = 16 * 1024U;
while ((buf = malloc(bufsiz)) == NULL) {
buf[0] = 0;
for (i = 0; i < NC; i++)
c_freq[i] = 0;
- for (i = 0; i < NP; i++)
+ for (i = 0; i < np; i++)
p_freq[i] = 0;
output_pos = output_mask = 0;
init_putbits();
blocksize = getbits(16);
read_pt_len(NT, TBIT, 3);
read_c_len();
- read_pt_len(NP, PBIT, -1);
+ read_pt_len(np, pbit, -1);
}
blocksize--;
j = c_table[bitbuf >> (BITBUFSIZ - 12)];
uint j, mask;
j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
- if (j >= NP) {
+ if (j >= np) {
mask = 1U << (BITBUFSIZ - 1 - 8);
do {
if (bitbuf & mask)
else
j = left[j];
mask >>= 1;
- } while (j >= NP);
+ } while (j >= np);
}
fillbuf(pt_len[j]);
if (j != 0)
}
void
-huf_decode_start(void)
+huf_decode_start(struct lha_method *m)
{
+ init_parameter(m);
init_getbits();
blocksize = 0;
}
# check $? $LINENO
$lha v test-tmp-m5.lzh | grep lh5
check $? $LINENO
-# $lha v test-tmp-m6.lzh | grep lh6
-# check $? $LINENO
-# $lha v test-tmp-m7.lzh | grep lh7
-# check $? $LINENO
+$lha v test-tmp-m6.lzh | grep lh6
+ check $? $LINENO
+$lha v test-tmp-m7.lzh | grep lh7
+ check $? $LINENO
$lha xw=test-tmp-m0 test-tmp-m0.lzh
check $? $LINENO
# $lha xw=test-tmp-m1 test-tmp-m1.lzh
# check $? $LINENO
$lha xw=test-tmp-m5 test-tmp-m5.lzh
check $? $LINENO
-# $lha xw=test-tmp-m6 test-tmp-m6.lzh
-# check $? $LINENO
-# $lha xw=test-tmp-m7 test-tmp-m7.lzh
-# check $? $LINENO
+$lha xw=test-tmp-m6 test-tmp-m6.lzh
+ check $? $LINENO
+$lha xw=test-tmp-m7 test-tmp-m7.lzh
+ check $? $LINENO
diff -r test-1 test-tmp-m0
check $? $LINENO
# check $? $LINENO
diff -r test-1 test-tmp-m5
check $? $LINENO
-# diff -r test-1 test-tmp-m6
-# check $? $LINENO
-# diff -r test-1 test-tmp-m7
-# check $? $LINENO
+diff -r test-1 test-tmp-m6
+ check $? $LINENO
+diff -r test-1 test-tmp-m7
+ check $? $LINENO
$lha pq test-tmp-m0.lzh test-a | diff test-a -
check $? $LINENO
# check $? $LINENO
$lha pq test-tmp-m5.lzh test-a | diff test-a -
check $? $LINENO
-# $lha pq test-tmp-m6.lzh test-a | diff test-a -
-# check $? $LINENO
-# $lha pq test-tmp-m7.lzh test-a | diff test-a -
-# check $? $LINENO
+$lha pq test-tmp-m6.lzh test-a | diff test-a -
+ check $? $LINENO
+$lha pq test-tmp-m7.lzh test-a | diff test-a -
+ check $? $LINENO
cat test-[abc] > test-tmp-abc
$lha pq test-tmp-m0.lzh | diff test-tmp-abc -
# check $? $LINENO
$lha pq test-tmp-m5.lzh | diff test-tmp-abc -
check $? $LINENO
-# $lha pq test-tmp-m6.lzh | diff test-tmp-abc -
-# check $? $LINENO
-# $lha pq test-tmp-m7.lzh | diff test-tmp-abc -
-# check $? $LINENO
+$lha pq test-tmp-m6.lzh | diff test-tmp-abc -
+ check $? $LINENO
+$lha pq test-tmp-m7.lzh | diff test-tmp-abc -
+ check $? $LINENO
# empty file should be frozen with the -lh0- method.
touch test-tmp-0byte