syncing 2.3.0

parent b7c7e36d
AM_CPPFLAGS = @UAE_CPPFLAGS@
AM_CPPFLAGS += -I$(top_srcdir)/src/include -I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = libdms.a
libdms_a_SOURCES = crc_csum.c getbits.c maketbl.c pfile.c tables.c \
u_deep.c u_heavy.c u_init.c u_medium.c u_quick.c \
u_rle.c
noinst_HEADERS = cdata.h crc_csum.h getbits.h maketbl.h pfile.h tables.h \
u_deep.h u_heavy.h u_init.h u_medium.h u_quick.h u_rle.h
This diff is collapsed.
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Main types of variables used in xDMS, some implementation
* dependant features and other global stuff
*/
#ifndef UCHAR
#define UCHAR unsigned char
#endif
#ifndef USHORT
#define USHORT unsigned short
#endif
#ifndef SHORT
#define SHORT short
#endif
#ifndef ULONG
#define ULONG unsigned long
#endif
#ifndef INLINE
#ifdef __cplusplus
#define INLINE inline
#else
#ifdef __GNUC__
#define INLINE inline
#else
#ifdef __SASC
#define INLINE __inline
#else
#define INLINE static
#endif
#endif
#endif
#endif
#ifndef UNDER_DOS
#ifdef __MSDOS__
#define UNDER_DOS
#else
#ifdef __MSDOS
#define UNDER_DOS
#else
#ifdef _OS2
#define UNDER_DOS
#else
#ifdef _QC
#define UNDER_DOS
#endif
#endif
#endif
#endif
#endif
#ifndef DIR_CHAR
#ifdef UNDER_DOS
/* running under MSDOS or DOS-like OS */
#define DIR_CHAR '\\'
#else
#define DIR_CHAR '/'
#endif
#endif
#define DIR_SEPARATORS ":\\/"
extern UCHAR *dms_text;
extern USHORT dms_lastlen, dms_np;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* CRC16 & CheckSum16 calculation functions
* CreateCRC was written (aparently) by Bjorn Stenberg
*
*/
#include "cdata.h"
#include "crc_csum.h"
USHORT dms_Calc_CheckSum(UCHAR *mem, ULONG size){
USHORT u=0;
while(size--) u += *mem++;
return (USHORT)(u & 0xffff);
}
USHORT dms_CreateCRC(UCHAR* mem, ULONG size ){
static USHORT CRCTab[256]={
0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
};
register USHORT CRC = 0;
while(size--)
CRC = (USHORT) (CRCTab[((CRC ^ *mem++) & 255)] ^ ((CRC >> 8) & 255));
return CRC;
}
USHORT dms_Calc_CheckSum(UCHAR *, ULONG);
USHORT dms_CreateCRC(UCHAR *, ULONG);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
* Functions/macros to get a variable number of bits
*
*/
#include "cdata.h"
#include "getbits.h"
ULONG dms_mask_bits[]={
0x000000L,0x000001L,0x000003L,0x000007L,0x00000fL,0x00001fL,
0x00003fL,0x00007fL,0x0000ffL,0x0001ffL,0x0003ffL,0x0007ffL,
0x000fffL,0x001fffL,0x003fffL,0x007fffL,0x00ffffL,0x01ffffL,
0x03ffffL,0x07ffffL,0x0fffffL,0x1fffffL,0x3fffffL,0x7fffffL,
0xffffffL
};
UCHAR *dms_indata, dms_bitcount;
ULONG dms_bitbuf;
void initbitbuf(UCHAR *in){
dms_bitbuf = 0;
dms_bitcount = 0;
dms_indata = in;
DROPBITS(0);
}
extern ULONG dms_mask_bits[], dms_bitbuf;
extern UCHAR *dms_indata, dms_bitcount;
#define GETBITS(n) ((USHORT)(dms_bitbuf >> (dms_bitcount-(n))))
#define DROPBITS(n) {dms_bitbuf &= dms_mask_bits[dms_bitcount-=(n)]; while (dms_bitcount<16) {dms_bitbuf = (dms_bitbuf << 8) | *dms_indata++; dms_bitcount += 8;}}
void initbitbuf(UCHAR *);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Makes decoding table for Heavy LZH decompression
* From UNIX LHA made by Masaru Oki
*
*/
#include "cdata.h"
#include "maketbl.h"
static SHORT c;
static USHORT n, tblsiz, len, depth, maxdepth, avail;
static USHORT codeword, bit, *tbl, TabErr;
static UCHAR *blen;
static USHORT mktbl(void);
USHORT dms_make_table(USHORT nchar, UCHAR bitlen[],USHORT tablebits, USHORT table[]){
n = avail = nchar;
blen = bitlen;
tbl = table;
tblsiz = (USHORT) (1U << tablebits);
bit = (USHORT) (tblsiz / 2);
maxdepth = (USHORT)(tablebits + 1);
depth = len = 1;
c = -1;
codeword = 0;
TabErr = 0;
mktbl(); /* left subtree */
if (TabErr) return TabErr;
mktbl(); /* right subtree */
if (TabErr) return TabErr;
if (codeword != tblsiz) return 5;
return 0;
}
static USHORT mktbl(void){
USHORT i=0;
if (TabErr) return 0;
if (len == depth) {
while (++c < n)
if (blen[c] == len) {
i = codeword;
codeword += bit;
if (codeword > tblsiz) {
TabErr=1;
return 0;
}
while (i < codeword) tbl[i++] = (USHORT)c;
return (USHORT)c;
}
c = -1;
len++;
bit >>= 1;
}
depth++;
if (depth < maxdepth) {
mktbl();
mktbl();
} else if (depth > 32) {
TabErr = 2;
return 0;
} else {
if ((i = avail++) >= 2 * n - 1) {
TabErr = 3;
return 0;
}
dms_left[i] = mktbl();
dms_right[i] = mktbl();
if (codeword >= tblsiz) {
TabErr = 4;
return 0;
}
if (depth == maxdepth) tbl[codeword++] = i;
}
depth--;
return i;
}
extern USHORT dms_left[], dms_right[];
USHORT dms_make_table(USHORT nchar, UCHAR bitlen[], USHORT tablebits, USHORT table[]);
This diff is collapsed.
/* Functions return codes */
#define NO_PROBLEM 0
#define DMS_FILE_END 1
#define ERR_NOMEMORY 2
#define ERR_CANTOPENIN 3
#define ERR_CANTOPENOUT 4
#define ERR_NOTDMS 5
#define ERR_SREAD 6
#define ERR_HCRC 7
#define ERR_NOTTRACK 8
#define ERR_BIGTRACK 9
#define ERR_THCRC 10
#define ERR_TDCRC 11
#define ERR_CSUM 12
#define ERR_CANTWRITE 13
#define ERR_BADDECR 14
#define ERR_UNKNMODE 15
#define ERR_NOPASSWD 16
#define ERR_BADPASSWD 17
#define ERR_FMS 18
#define ERR_GZIP 19
#define ERR_READDISK 20
/* Command to execute */
#define CMD_VIEW 1
#define CMD_VIEWFULL 2
#define CMD_SHOWDIZ 3
#define CMD_SHOWBANNER 4
#define CMD_TEST 5
#define CMD_UNPACK 6
#define CMD_UNPKGZ 7
#define CMD_EXTRACT 8
#define OPT_VERBOSE 1
#define OPT_QUIET 2
#define DMS_EXTRA_SIZE 10
USHORT DMS_Process_File(struct zfile *, struct zfile *, USHORT, USHORT, USHORT, USHORT, int, struct zfile **extra);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Tables used in Medium and Deep compression modes
*
*/
#include "cdata.h"
#include "tables.h"
UCHAR d_code[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
};
UCHAR d_len[256] = {
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
};
extern UCHAR d_code[], d_len[];
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Lempel-Ziv-DynamicHuffman decompression functions used in Deep
* mode.
* Most routines ripped from LZHUF written by Haruyasu Yoshizaki
*
*/
#include <string.h>
#include "cdata.h"
#include "tables.h"
#include "u_deep.h"
#include "getbits.h"
INLINE USHORT DecodeChar(void);
INLINE USHORT DecodePosition(void);
INLINE void update(USHORT c);
static void reconst(void);
USHORT dms_deep_text_loc;
int dms_init_deep_tabs=1;
#define DBITMASK 0x3fff /* uses 16Kb dictionary */
#define F 60 /* lookahead buffer size */
#define THRESHOLD 2
#define N_CHAR (256 - THRESHOLD + F) /* kinds of characters (character code = 0..N_CHAR-1) */
#define T (N_CHAR * 2 - 1) /* size of table */
#define R (T - 1) /* position of root */
#define MAX_FREQ 0x8000 /* updates tree when the */
static USHORT freq[T + 1]; /* frequency table */
static USHORT prnt[T + N_CHAR]; /* pointers to parent nodes, except for the */
/* elements [T..T + N_CHAR - 1] which are used to get */
/* the positions of leaves corresponding to the codes. */
static USHORT son[T]; /* pointers to child nodes (son[], son[] + 1) */
void Init_DEEP_Tabs(void){
USHORT i, j;
for (i = 0; i < N_CHAR; i++) {
freq[i] = 1;
son[i] = (USHORT)(i + T);
prnt[i + T] = i;
}
i = 0; j = N_CHAR;
while (j <= R) {
freq[j] = (USHORT) (freq[i] + freq[i + 1]);
son[j] = i;
prnt[i] = prnt[i + 1] = j;
i += 2; j++;
}
freq[T] = 0xffff;
prnt[R] = 0;
dms_init_deep_tabs = 0;
}
USHORT Unpack_DEEP(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT i, j, c;
UCHAR *outend;
initbitbuf(in);
if (dms_init_deep_tabs) Init_DEEP_Tabs();
outend = out+origsize;
while (out < outend) {
c = DecodeChar();
if (c < 256) {
*out++ = dms_text[dms_deep_text_loc++ & DBITMASK] = (UCHAR)c;
} else {
j = (USHORT) (c - 255 + THRESHOLD);
i = (USHORT) (dms_deep_text_loc - DecodePosition() - 1);
while (j--) *out++ = dms_text[dms_deep_text_loc++ & DBITMASK] = dms_text[i++ & DBITMASK];
}
}
dms_deep_text_loc = (USHORT)((dms_deep_text_loc+60) & DBITMASK);
return 0;
}
INLINE USHORT DecodeChar(void){
USHORT c;
c = son[R];
/* travel from root to leaf, */
/* choosing the smaller child node (son[]) if the read bit is 0, */
/* the bigger (son[]+1} if 1 */
while (c < T) {
c = son[c + GETBITS(1)];
DROPBITS(1);
}
c -= T;
update(c);
return c;
}
INLINE USHORT DecodePosition(void){
USHORT i, j, c;
i = GETBITS(8); DROPBITS(8);
c = (USHORT) (d_code[i] << 8);
j = d_len[i];
i = (USHORT) (((i << j) | GETBITS(j)) & 0xff); DROPBITS(j);
return (USHORT) (c | i) ;
}
/* reconstruction of tree */
static void reconst(void){
USHORT i, j, k, f, l;
/* collect leaf nodes in the first half of the table */
/* and replace the freq by (freq + 1) / 2. */
j = 0;
for (i = 0; i < T; i++) {
if (son[i] >= T) {
freq[j] = (USHORT) ((freq[i] + 1) / 2);
son[j] = son[i];
j++;
}
}
/* begin constructing tree by connecting sons */
for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
k = (USHORT) (i + 1);
f = freq[j] = (USHORT) (freq[i] + freq[k]);
for (k = (USHORT)(j - 1); f < freq[k]; k--);
k++;
l = (USHORT)((j - k) * 2);
memmove(&freq[k + 1], &freq[k], (size_t)l);
freq[k] = f;
memmove(&son[k + 1], &son[k], (size_t)l);
son[k] = i;
}
/* connect prnt */
for (i = 0; i < T; i++) {
if ((k = son[i]) >= T) {
prnt[k] = i;
} else {
prnt[k] = prnt[k + 1] = i;
}
}
}
/* increment frequency of given code by one, and update tree */
INLINE void update(USHORT c){
USHORT i, j, k, l;
if (freq[R] == MAX_FREQ) {
reconst();
}
c = prnt[c + T];
do {
k = ++freq[c];
/* if the order is disturbed, exchange nodes */
if (k > freq[l = (USHORT)(c + 1)]) {
while (k > freq[++l]);
l--;
freq[c] = freq[l];
freq[l] = k;
i = son[c];
prnt[i] = l;
if (i < T) prnt[i + 1] = l;
j = son[l];
son[l] = i;
prnt[j] = c;
if (j < T) prnt[j + 1] = c;
son[c] = j;
c = l;
}
} while ((c = prnt[c]) != 0); /* repeat up to root */
}
USHORT Unpack_DEEP(UCHAR *, UCHAR *, USHORT);
extern int dms_init_deep_tabs;
extern USHORT dms_deep_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Lempel-Ziv-Huffman decompression functions used in Heavy 1 & 2
* compression modes. Based on LZH decompression functions from
* UNIX LHA made by Masaru Oki
*
*/
#include "cdata.h"
#include "u_heavy.h"
#include "getbits.h"
#include "maketbl.h"
#define NC 510
#define NPT 20
#define N1 510
#define OFFSET 253
USHORT dms_left[2 * NC - 1], dms_right[2 * NC - 1 + 9];
static UCHAR c_len[NC], pt_len[NPT];
static USHORT c_table[4096], pt_table[256];
USHORT dms_lastlen, dms_np;
USHORT dms_heavy_text_loc;
static USHORT read_tree_c(void);
static USHORT read_tree_p(void);
INLINE USHORT decode_c(void);
INLINE USHORT decode_p(void);
USHORT Unpack_HEAVY(UCHAR *in, UCHAR *out, UCHAR flags, USHORT origsize){
USHORT j, i, c, bitmask;
UCHAR *outend;
/* Heavy 1 uses a 4Kb dictionary, Heavy 2 uses 8Kb */
if (flags & 8) {
dms_np = 15;
bitmask = 0x1fff;
} else {
dms_np = 14;
bitmask = 0x0fff;
}
initbitbuf(in);
if (flags & 2) {
if (read_tree_c()) return 1;
if (read_tree_p()) return 2;
}
outend = out+origsize;
while (out<outend) {
c = decode_c();
if (c < 256) {
*out++ = dms_text[dms_heavy_text_loc++ & bitmask] = (UCHAR)c;
} else {
j = (USHORT) (c - OFFSET);
i = (USHORT) (dms_heavy_text_loc - decode_p() - 1);
while(j--) *out++ = dms_text[dms_heavy_text_loc++ & bitmask] = dms_text[i++ & bitmask];
}
}
return 0;
}
INLINE USHORT decode_c(void){
USHORT i, j, m;
j = c_table[GETBITS(12)];
if (j < N1) {
DROPBITS(c_len[j]);
} else {
DROPBITS(12);
i = GETBITS(16);
m = 0x8000;
do {
if (i & m) j = dms_right[j];
else j = dms_left [j];
m >>= 1;
} while (j >= N1);
DROPBITS(c_len[j] - 12);
}
return j;
}
INLINE USHORT decode_p(void){
USHORT i, j, m;
j = pt_table[GETBITS(8)];
if (j < dms_np) {
DROPBITS(pt_len[j]);
} else {
DROPBITS(8);
i = GETBITS(16);
m = 0x8000;
do {
if (i & m) j = dms_right[j];
else j = dms_left [j];
m >>= 1;
} while (j >= dms_np);
DROPBITS(pt_len[j] - 8);
}
if (j != dms_np-1) {
if (j > 0) {
j = (USHORT)(GETBITS(i=(USHORT)(j-1)) | (1U << (j-1)));
DROPBITS(i);
}
dms_lastlen=j;
}
return dms_lastlen;
}
static USHORT read_tree_c(void){
USHORT i,n;
n = GETBITS(9);
DROPBITS(9);
if (n>0){
for (i=0; i<n; i++) {
c_len[i] = (UCHAR)GETBITS(5);
DROPBITS(5);
}
for (i=n; i<510; i++) c_len[i] = 0;
if (dms_make_table(510,c_len,12,c_table)) return 1;
} else {
n = GETBITS(9);
DROPBITS(9);
for (i=0; i<510; i++) c_len[i] = 0;
for (i=0; i<4096; i++) c_table[i] = n;
}
return 0;
}
static USHORT read_tree_p(void){
USHORT i,n;
n = GETBITS(5);
DROPBITS(5);
if (n>0){
for (i=0; i<n; i++) {
pt_len[i] = (UCHAR)GETBITS(4);
DROPBITS(4);
}
for (i=n; i<dms_np; i++) pt_len[i] = 0;
if (dms_make_table(dms_np,pt_len,8,pt_table)) return 1;
} else {
n = GETBITS(5);
DROPBITS(5);
for (i=0; i<dms_np; i++) pt_len[i] = 0;
for (i=0; i<256; i++) pt_table[i] = n;
}
return 0;
}
USHORT Unpack_HEAVY(UCHAR *, UCHAR *, UCHAR, USHORT);
extern USHORT dms_heavy_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Decruncher reinitialization
*
*/
#include <string.h>
#include "cdata.h"
#include "u_init.h"
#include "u_quick.h"
#include "u_medium.h"
#include "u_deep.h"
#include "u_heavy.h"
void Init_Decrunchers(void){
dms_quick_text_loc = 251;
dms_medium_text_loc = 0x3fbe;
dms_heavy_text_loc = 0;
dms_deep_text_loc = 0x3fc4;
dms_init_deep_tabs = 1;
memset(dms_text,0,0x3fc8);
dms_lastlen = 0;
dms_np = 0;
}
void Init_Decrunchers(void);
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Main decompression functions used in MEDIUM mode
*
*/
#include <string.h>
#include "cdata.h"
#include "u_medium.h"
#include "getbits.h"
#include "tables.h"
#define MBITMASK 0x3fff
USHORT dms_medium_text_loc;
USHORT Unpack_MEDIUM(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT i, j, c;
UCHAR u, *outend;
initbitbuf(in);
outend = out+origsize;
while (out < outend) {
if (GETBITS(1)!=0) {
DROPBITS(1);
*out++ = dms_text[dms_medium_text_loc++ & MBITMASK] = (UCHAR)GETBITS(8);
DROPBITS(8);
} else {
DROPBITS(1);
c = GETBITS(8); DROPBITS(8);
j = (USHORT) (d_code[c]+3);
u = d_len[c];
c = (USHORT) (((c << u) | GETBITS(u)) & 0xff); DROPBITS(u);
u = d_len[c];
c = (USHORT) ((d_code[c] << 8) | (((c << u) | GETBITS(u)) & 0xff)); DROPBITS(u);
i = (USHORT) (dms_medium_text_loc - c - 1);
while(j--) *out++ = dms_text[dms_medium_text_loc++ & MBITMASK] = dms_text[i++ & MBITMASK];
}
}
dms_medium_text_loc = (USHORT)((dms_medium_text_loc+66) & MBITMASK);
return 0;
}
USHORT Unpack_MEDIUM(UCHAR *, UCHAR *, USHORT);
extern USHORT dms_medium_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
*
*/
#include <string.h>
#include "cdata.h"
#include "u_quick.h"
#include "getbits.h"
#define QBITMASK 0xff
USHORT dms_quick_text_loc;
USHORT Unpack_QUICK(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT i, j;
UCHAR *outend;
initbitbuf(in);
outend = out+origsize;
while (out < outend) {
if (GETBITS(1)!=0) {
DROPBITS(1);
*out++ = dms_text[dms_quick_text_loc++ & QBITMASK] = (UCHAR)GETBITS(8); DROPBITS(8);
} else {
DROPBITS(1);
j = (USHORT) (GETBITS(2)+2); DROPBITS(2);
i = (USHORT) (dms_quick_text_loc - GETBITS(8) - 1); DROPBITS(8);
while(j--) {
*out++ = dms_text[dms_quick_text_loc++ & QBITMASK] = dms_text[i++ & QBITMASK];
}
}
}
dms_quick_text_loc = (USHORT)((dms_quick_text_loc+5) & QBITMASK);
return 0;
}
USHORT Unpack_QUICK(UCHAR *, UCHAR *, USHORT);
extern USHORT dms_quick_text_loc;
/*
* xDMS v1.3 - Portable DMS archive unpacker - Public Domain
* Written by Andre Rodrigues de la Rocha <adlroc@usa.net>
*
* Run Length Encoding decompression function used in most
* modes after decompression by other algorithm
*
*/
#include <string.h>
#include "cdata.h"
#include "u_rle.h"
USHORT Unpack_RLE(UCHAR *in, UCHAR *out, USHORT origsize){
USHORT n;
UCHAR a,b, *outend;
outend = out+origsize;
while (out<outend){
if ((a = *in++) != 0x90)
*out++ = a;
else if (!(b = *in++))
*out++ = a;
else {
a = *in++;
if (b == 0xff) {
n = *in++;
n = (USHORT)((n<<8) + *in++);
} else
n = b;
if (out+n > outend) return 1;
memset(out,a,(size_t) n);
out += n;
}
}
return 0;
}
USHORT Unpack_RLE(UCHAR *, UCHAR *, USHORT);
AM_CPPFLAGS = @UAE_CPPFLAGS@
AM_CPPFLAGS += -I$(top_srcdir)/src/include -I$(top_builddir)/src -I$(top_srcdir)/src
AM_CFLAGS = @UAE_CFLAGS@
noinst_LIBRARIES = liblha.a
liblha_a_SOURCES = crcio.c dhuf.c header.c huf.c larc.c \
lhamaketbl.c lharc.c shuf.c slide.c uae_lha.c \
util.c
noinst_HEADERS = lha.h lha_macro.h
This diff is collapsed.
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* crcio.c -- crc input / output */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/* ------------------------------------------------------------------------ */
static unsigned short crctable[UCHAR_MAX + 1];
static unsigned char subbitbuf, bitcount;
#ifdef EUC
static int putc_euc_cache;
#endif
static int getc_euc_cache;
/* ------------------------------------------------------------------------ */
void
make_crctable( /* void */ )
{
unsigned int i, j, r;
for (i = 0; i <= UCHAR_MAX; i++) {
r = i;
for (j = 0; j < CHAR_BIT; j++)
if (r & 1)
r = (r >> 1) ^ CRCPOLY;
else
r >>= 1;
crctable[i] = r;
}
}
/* ------------------------------------------------------------------------ */
#ifdef NEED_INCREMENTAL_INDICATOR
static void
put_indicator(count)
long int count;
{
if (!quiet && indicator_threshold) {
while (count > indicator_count) {
putchar('o');
fflush(stdout);
indicator_count += indicator_threshold;
}
}
}
#endif
/* ------------------------------------------------------------------------ */
unsigned short
calccrc(unsigned char *p, unsigned int n)
{
reading_size += n;
#ifdef NEED_INCREMENTAL_INDICATOR
put_indicator(reading_size);
#endif
while (n-- > 0)
UPDATE_CRC(*p++);
return crc;
}
/* ------------------------------------------------------------------------ */
void
fillbuf(unsigned char n) /* Shift bitbuf n bits left, read n bits */
{
while (n > bitcount) {
n -= bitcount;
lhabitbuf = (lhabitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
if (compsize != 0) {
compsize--;
subbitbuf = (unsigned char) zfile_getc(infile);
}
else
subbitbuf = 0;
bitcount = CHAR_BIT;
}
bitcount -= n;
lhabitbuf = (lhabitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
subbitbuf <<= n;
}
/* ------------------------------------------------------------------------ */
unsigned short
getbits(unsigned char n)
{
unsigned short x;
x = lhabitbuf >> (2 * CHAR_BIT - n);
fillbuf(n);
return x;
}
#if 0
/* ------------------------------------------------------------------------ */
void
putcode(n, x) /* Write rightmost n bits of x */
unsigned char n;
unsigned short x;
{
while (n >= bitcount) {
n -= bitcount;
subbitbuf += x >> (USHRT_BIT - bitcount);
x <<= bitcount;
if (compsize < origsize) {
if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
/* fileerror(WTERR, outfile); */
fatal_error("Write error in crcio.c(putcode)\n");
/* exit(errno); */
}
compsize++;
}
else
unpackable = 1;
subbitbuf = 0;
bitcount = CHAR_BIT;
}
subbitbuf += x >> (USHRT_BIT - bitcount);
bitcount -= n;
}
/* ------------------------------------------------------------------------ */
void
putbits(n, x) /* Write rightmost n bits of x */
unsigned char n;
unsigned short x;
{
x <<= USHRT_BIT - n;
while (n >= bitcount) {
n -= bitcount;
subbitbuf += x >> (USHRT_BIT - bitcount);
x <<= bitcount;
if (compsize < origsize) {
if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
/* fileerror(WTERR, outfile); */
fatal_error("Write error in crcio.c(putbits)\n");
/* exit(errno); */
}
compsize++;
}
else
unpackable = 1;
subbitbuf = 0;
bitcount = CHAR_BIT;
}
subbitbuf += x >> (USHRT_BIT - bitcount);
bitcount -= n;
}
#endif
/* ------------------------------------------------------------------------ */
int
fread_crc(unsigned char *p, int n, struct zfile *fp)
{
n = zfile_fread(p, 1, n, fp);
calccrc(p, n);
return n;
}
/* ------------------------------------------------------------------------ */
void
fwrite_crc(unsigned char *p, int n, struct zfile *fp)
{
calccrc(p, n);
if (verify_mode)
return;
if (fp) {
zfile_fwrite(p, 1, n, fp);
}
}
/* ------------------------------------------------------------------------ */
void
init_code_cache(void)
{ /* called from copyfile() in util.c */
#ifdef EUC
putc_euc_cache = EOF;
#endif
getc_euc_cache = EOF;
}
void
init_getbits(void)
{
lhabitbuf = 0;
subbitbuf = 0;
bitcount = 0;
fillbuf(2 * CHAR_BIT);
#ifdef EUC
putc_euc_cache = EOF;
#endif
}
/* ------------------------------------------------------------------------ */
void
init_putbits( /* void */ )
{
bitcount = CHAR_BIT;
subbitbuf = 0;
getc_euc_cache = EOF;
}
/* ------------------------------------------------------------------------ */
#ifdef EUC
void
putc_euc(c, fd)
int c;
FILE *fd;
{
int d;
if (putc_euc_cache == EOF) {
if (!euc_mode || c < 0x81 || c > 0xFC) {
putc(c, fd);
return;
}
if (c >= 0xA0 && c < 0xE0) {
putc(0x8E, fd); /* single shift */
putc(c, fd);
return;
}
putc_euc_cache = c; /* save first byte */
return;
}
d = putc_euc_cache;
putc_euc_cache = EOF;
if (d >= 0xA0)
d -= 0xE0 - 0xA0;
if (c > 0x9E) {
c = c - 0x9F + 0x21;
d = (d - 0x81) * 2 + 0x22;
}
else {
if (c > 0x7E)
c--;
c -= 0x1F;
d = (d - 0x81) * 2 + 0x21;
}
putc(0x80 | d, fd);
putc(0x80 | c, fd);
}
#endif
/* ------------------------------------------------------------------------ */
int
fwrite_txt(unsigned char *p, int n, FILE *fp)
{
while (--n >= 0) {
if (*p != '\015' && *p != '\032') {
#ifdef EUC
putc_euc(*p, fp);
#else
putc(*p, fp);
#endif
}
prev_char = *p++;
}
return (ferror(fp));
}
/* ------------------------------------------------------------------------ */
int
fread_txt(unsigned char *p, int n, FILE *fp)
{
int c;
int cnt = 0;
while (cnt < n) {
if (getc_euc_cache != EOF) {
c = getc_euc_cache;
getc_euc_cache = EOF;
}
else {
if ((c = fgetc(fp)) == EOF)
break;
if (c == '\n') {
getc_euc_cache = c;
++origsize;
c = '\r';
}
#ifdef EUC
else if (euc_mode && (c == 0x8E || 0xA0 < c && c < 0xFF)) {
int d = fgetc(fp);
if (d == EOF) {
*p++ = c;
cnt++;
break;
}
if (c == 0x8E) { /* single shift (KANA) */
if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
c = d | 0x80;
else
getc_euc_cache = d;
}
else {
if (0xA0 < d && d < 0xFF) { /* if GR */
c &= 0x7F; /* convert to MS-kanji */
d &= 0x7F;
if (!(c & 1)) {
c--;
d += 0x7F - 0x21;
}
if ((d += 0x40 - 0x21) > 0x7E)
d++;
if ((c = (c >> 1) + 0x71) >= 0xA0)
c += 0xE0 - 0xA0;
}
getc_euc_cache = d;
}
}
#endif
}
*p++ = c;
cnt++;
}
return cnt;
}
/* ------------------------------------------------------------------------ */
unsigned short
calc_header_crc(unsigned char *p, unsigned int n) /* Thanks T.Okamoto */
{
crc = 0;
while (n-- > 0)
UPDATE_CRC(*p++);
return crc;
}
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* dhuf.c -- Dynamic Hufffman routine */
/* */
/* Modified H.Yoshizaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/* ------------------------------------------------------------------------ */
static short child[TREESIZE], parent[TREESIZE], block[TREESIZE], edge[TREESIZE], stock[TREESIZE],
s_node[TREESIZE / 2]; /* Changed N.Watazaki */
/* node[..] -> s_node[..] */
static unsigned short freq[TREESIZE];
static unsigned short total_p;
static int avail, n1;
static int most_p, nn;
static unsigned long nextcount;
/* ------------------------------------------------------------------------ */
void
start_c_dyn(void)
{
int i, j, f;
n1 = (n_max >= 256 + maxmatch - THRESHOLD + 1) ? 512 : n_max - 1;
for (i = 0; i < TREESIZE_C; i++) {
stock[i] = i;
block[i] = 0;
}
for (i = 0, j = n_max * 2 - 2; i < n_max; i++, j--) {
freq[j] = 1;
child[j] = ~i;
s_node[i] = j;
block[j] = 1;
}
avail = 2;
edge[1] = n_max - 1;
i = n_max * 2 - 2;
while (j >= 0) {
f = freq[j] = freq[i] + freq[i - 1];
child[j] = i;
parent[i] = parent[i - 1] = j;
if (f == freq[j + 1]) {
edge[block[j] = block[j + 1]] = j;
}
else {
edge[block[j] = stock[avail++]] = j;
}
i -= 2;
j--;
}
}
/* ------------------------------------------------------------------------ */
static void
start_p_dyn(void)
{
freq[ROOT_P] = 1;
child[ROOT_P] = ~(N_CHAR);
s_node[N_CHAR] = ROOT_P;
edge[block[ROOT_P] = stock[avail++]] = ROOT_P;
most_p = ROOT_P;
total_p = 0;
nn = 1 << dicbit;
nextcount = 64;
}
/* ------------------------------------------------------------------------ */
void
decode_start_dyn(void)
{
n_max = 286;
maxmatch = MAXMATCH;
init_getbits();
start_c_dyn();
start_p_dyn();
}
/* ------------------------------------------------------------------------ */
static void
reconst(int start, int end)
{
int i, j, k, l, b;
unsigned int f, g;
for (i = j = start; i < end; i++) {
if ((k = child[i]) < 0) {
freq[j] = (freq[i] + 1) / 2;
child[j] = k;
j++;
}
if (edge[b = block[i]] == i) {
stock[--avail] = b;
}
}
j--;
i = end - 1;
l = end - 2;
while (i >= start) {
while (i >= l) {
freq[i] = freq[j];
child[i] = child[j];
i--, j--;
}
f = freq[l] + freq[l + 1];
for (k = start; f < freq[k]; k++);
while (j >= k) {
freq[i] = freq[j];
child[i] = child[j];
i--, j--;
}
freq[i] = f;
child[i] = l + 1;
i--;
l -= 2;
}
f = 0;
for (i = start; i < end; i++) {
if ((j = child[i]) < 0)
s_node[~j] = i;
else
parent[j] = parent[j - 1] = i;
if ((g = freq[i]) == f) {
block[i] = b;
}
else {
edge[b = block[i] = stock[avail++]] = i;
f = g;
}
}
}
/* ------------------------------------------------------------------------ */
static int
swap_inc(int p)
{
int b, q, r, s;
b = block[p];
if ((q = edge[b]) != p) { /* swap for leader */
r = child[p];
s = child[q];
child[p] = s;
child[q] = r;
if (r >= 0)
parent[r] = parent[r - 1] = q;
else
s_node[~r] = q;
if (s >= 0)
parent[s] = parent[s - 1] = p;
else
s_node[~s] = p;
p = q;
goto Adjust;
}
else if (b == block[p + 1]) {
Adjust:
edge[b]++;
if (++freq[p] == freq[p - 1]) {
block[p] = block[p - 1];
}
else {
edge[block[p] = stock[avail++]] = p; /* create block */
}
}
else if (++freq[p] == freq[p - 1]) {
stock[--avail] = b; /* delete block */
block[p] = block[p - 1];
}
return parent[p];
}
/* ------------------------------------------------------------------------ */
static void
update_c(int p)
{
int q;
if (freq[ROOT_C] == 0x8000) {
reconst(0, n_max * 2 - 1);
}
freq[ROOT_C]++;
q = s_node[p];
do {
q = swap_inc(q);
} while (q != ROOT_C);
}
/* ------------------------------------------------------------------------ */
static void
update_p(int p)
{
int q;
if (total_p == 0x8000) {
reconst(ROOT_P, most_p + 1);
total_p = freq[ROOT_P];
freq[ROOT_P] = 0xffff;
}
q = s_node[p + N_CHAR];
while (q != ROOT_P) {
q = swap_inc(q);
}
total_p++;
}
/* ------------------------------------------------------------------------ */
static void
make_new_node(int p)
{
int q, r;
r = most_p + 1;
q = r + 1;
s_node[~(child[r] = child[most_p])] = r;
child[q] = ~(p + N_CHAR);
child[most_p] = q;
freq[r] = freq[most_p];
freq[q] = 0;
block[r] = block[most_p];
if (most_p == ROOT_P) {
freq[ROOT_P] = 0xffff;
edge[block[ROOT_P]]++;
}
parent[r] = parent[q] = most_p;
edge[block[q] = stock[avail++]] = s_node[p + N_CHAR] = most_p = q;
update_p(p);
}
#if 0
/* ------------------------------------------------------------------------ */
static void
encode_c_dyn(c)
unsigned int c;
{
unsigned int bits;
int p, d, cnt;
d = c - n1;
if (d >= 0) {
c = n1;
}
cnt = bits = 0;
p = s_node[c];
do {
bits >>= 1;
if (p & 1) {
bits |= 0x8000;
}
if (++cnt == 16) {
putcode(16, bits);
cnt = bits = 0;
}
} while ((p = parent[p]) != ROOT_C);
putcode(cnt, bits);
if (d >= 0)
putbits(8, d);
update_c(c);
}
#endif
/* ------------------------------------------------------------------------ */
unsigned short
decode_c_dyn(void)
{
int c;
short buf, cnt;
c = child[ROOT_C];
buf = lhabitbuf;
cnt = 0;
do {
c = child[c - (buf < 0)];
buf <<= 1;
if (++cnt == 16) {
fillbuf(16);
buf = lhabitbuf;
cnt = 0;
}
} while (c > 0);
fillbuf(cnt);
c = ~c;
update_c(c);
if (c == n1)
c += getbits(8);
return c;
}
/* ------------------------------------------------------------------------ */
unsigned short
decode_p_dyn(void)
{
int c;
short buf, cnt;
while (count > nextcount) {
make_new_node(nextcount / 64);
if ((nextcount += 64) >= nn)
nextcount = 0xffffffff;
}
c = child[ROOT_P];
buf = lhabitbuf;
cnt = 0;
while (c > 0) {
c = child[c - (buf < 0)];
buf <<= 1;
if (++cnt == 16) {
fillbuf(16);
buf = lhabitbuf;
cnt = 0;
}
}
fillbuf(cnt);
c = (~c) - N_CHAR;
update_p(c);
return (c << 6) + getbits(6);
}
#if 0
/* ------------------------------------------------------------------------ */
void
output_dyn(code, pos)
unsigned int code;
unsigned int pos;
{
encode_c_dyn(code);
if (code >= 0x100) {
encode_p_st0(pos);
}
}
/* ------------------------------------------------------------------------ */
void
encode_end_dyn( /* void */ )
{
putcode(7, 0);
}
#endif
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
This diff is collapsed.
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* huf.c -- new static Huffman */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14i Support LH7 & Bug Fixed 2000.10. 6 t.okamoto */
/* ------------------------------------------------------------------------ */
#include "lha.h"
#ifdef sony_news
#include <sys/param.h>
#endif
#if defined(__STDC__) || defined(NEWSOS)
#include <stdlib.h>
#endif
/* ------------------------------------------------------------------------ */
unsigned short h_left[2 * NC - 1], h_right[2 * NC - 1];
unsigned char c_len[NC], pt_len[NPT];
unsigned short 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 unsigned char *buf;
static unsigned int bufsiz;
static unsigned short blocksize;
static unsigned short output_pos, output_mask;
static int pbit;
static int np;
/* ------------------------------------------------------------------------ */
/* Encording */
/* ------------------------------------------------------------------------ */
static void count_t_freq(void)
{
short i, k, n, count;
for (i = 0; i < NT; i++)
t_freq[i] = 0;
n = NC;
while (n > 0 && c_len[n - 1] == 0)
n--;
i = 0;
while (i < n) {
k = c_len[i++];
if (k == 0) {
count = 1;
while (i < n && c_len[i] == 0) {
i++;
count++;
}
if (count <= 2)
t_freq[0] += count;
else if (count <= 18)
t_freq[1]++;
else if (count == 19) {
t_freq[0]++;
t_freq[1]++;
}
else
t_freq[2]++;
} else
t_freq[k + 2]++;
}
}
/* ------------------------------------------------------------------------ */
#if 0
static void
write_pt_len(n, nbit, i_special)
short n;
short nbit;
short i_special;
{
short i, k;
while (n > 0 && pt_len[n - 1] == 0)
n--;
putbits(nbit, n);
i = 0;
while (i < n) {
k = pt_len[i++];
if (k <= 6)
putbits(3, k);
else
putbits(k - 3, USHRT_MAX << 1);
if (i == i_special) {
while (i < 6 && pt_len[i] == 0)
i++;
putbits(2, i - 3);
}
}
}
/* ------------------------------------------------------------------------ */
static void
write_c_len(/*void*/)
{
short i, k, n, count;
n = NC;
while (n > 0 && c_len[n - 1] == 0)
n--;
putbits(CBIT, n);
i = 0;
while (i < n) {
k = c_len[i++];
if (k == 0) {
count = 1;
while (i < n && c_len[i] == 0) {
i++;
count++;
}
if (count <= 2) {
for (k = 0; k < count; k++)
putcode(pt_len[0], pt_code[0]);
}
else if (count <= 18) {
putcode(pt_len[1], pt_code[1]);
putbits(4, count - 3);
}
else if (count == 19) {
putcode(pt_len[0], pt_code[0]);
putcode(pt_len[1], pt_code[1]);
putbits(4, 15);
}
else {
putcode(pt_len[2], pt_code[2]);
putbits(CBIT, count - 20);
}
}
else
putcode(pt_len[k + 2], pt_code[k + 2]);
}
}
/* ------------------------------------------------------------------------ */
static void
encode_c(c)
short c;
{
putcode(c_len[c], c_code[c]);
}
/* ------------------------------------------------------------------------ */
static void
encode_p(p)
unsigned short p;
{
unsigned short c, q;
c = 0;
q = p;
while (q) {
q >>= 1;
c++;
}
putcode(pt_len[c], pt_code[c]);
if (c > 1)
putbits(c - 1, p);
}
/* ------------------------------------------------------------------------ */
static void
send_block( /* void */ )
{
unsigned char flags;
unsigned short i, k, root, pos, size;
root = make_tree(NC, c_freq, c_len, c_code);
size = c_freq[root];
putbits(16, size);
if (root >= NC) {
count_t_freq();
root = make_tree(NT, t_freq, pt_len, pt_code);
if (root >= NT) {
write_pt_len(NT, TBIT, 3);
} else {
putbits(TBIT, 0);
putbits(TBIT, root);
}
write_c_len();
} else {
putbits(TBIT, 0);
putbits(TBIT, 0);
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);
}
else {
putbits(pbit, 0);
putbits(pbit, root);
}
pos = 0;
for (i = 0; i < size; i++) {
if (i % CHAR_BIT == 0)
flags = buf[pos++];
else
flags <<= 1;
if (flags & (1 << (CHAR_BIT - 1))) {
encode_c(buf[pos++] + (1 << CHAR_BIT));
k = buf[pos++] << CHAR_BIT;
k += buf[pos++];
encode_p(k);
} else
encode_c(buf[pos++]);
if (unpackable)
return;
}
for (i = 0; i < NC; i++)
c_freq[i] = 0;
for (i = 0; i < np; i++)
p_freq[i] = 0;
}
/* ------------------------------------------------------------------------ */
void
output_st1(c, p)
unsigned short c;
unsigned short p;
{
static unsigned short cpos;
output_mask >>= 1;
if (output_mask == 0) {
output_mask = 1 << (CHAR_BIT - 1);
if (output_pos >= bufsiz - 3 * CHAR_BIT) {
send_block();
if (unpackable)
return;
output_pos = 0;
}
cpos = output_pos++;
buf[cpos] = 0;
}
buf[output_pos++] = (unsigned char) c;
c_freq[c]++;
if (c >= (1 << CHAR_BIT)) {
buf[cpos] |= output_mask;
buf[output_pos++] = (unsigned char) (p >> CHAR_BIT);
buf[output_pos++] = (unsigned char) p;
c = 0;
while (p) {
p >>= 1;
c++;
}
p_freq[c]++;
}
}
#endif
/* ------------------------------------------------------------------------ */
unsigned char *alloc_buf(void)
{
bufsiz = 16 * 1024 *2; /* 65408U; */ /* t.okamoto */
while ((buf = (unsigned char *) malloc(bufsiz)) == NULL) {
bufsiz = (bufsiz / 10) * 9;
if (bufsiz < 4 * 1024)
break;
}
return buf;
}
/* ------------------------------------------------------------------------ */
#if 0
void
encode_start_st1( /* void */ )
{
int i;
#if 0
if (dicbit <= (MAX_DICBIT - 2)) {
pbit = 4; /* lh4,5 etc. */
np = 14;
} else {
pbit = 5; /* lh6 */
np = 16;
}
#endif
if (dicbit <= 13) {
pbit = 4; /* lh4,5 etc. */
np = 14;
} else {
pbit = 5; /* lh6,7 */
if (dicbit == 16)
np = 17;
else
np = 16;
}
for (i = 0; i < NC; i++)
c_freq[i] = 0;
for (i = 0; i < np; i++)
p_freq[i] = 0;
output_pos = output_mask = 0;
init_putbits();
buf[0] = 0;
}
/* ------------------------------------------------------------------------ */
void
encode_end_st1( /* void */ )
{
if (!unpackable) {
send_block();
putbits(CHAR_BIT - 1, 0); /* flush remaining bits */
}
}
#endif
/* ------------------------------------------------------------------------ */
/* decoding */
/* ------------------------------------------------------------------------ */
static void read_pt_len(short nn, short nbit, short i_special)
{
int i, c, n;
n = getbits(nbit);
if (n == 0) {
c = getbits(nbit);
for (i = 0; i < nn; i++)
pt_len[i] = 0;
for (i = 0; i < 256; i++)
pt_table[i] = c;
}
else {
i = 0;
while (i < n) {
c = lhabitbuf >> (16 - 3);
if (c == 7) {
unsigned short mask = 1 << (16 - 4);
while (mask & lhabitbuf) {
mask >>= 1;
c++;
}
}
fillbuf((c < 7) ? 3 : c - 3);
pt_len[i++] = c;
if (i == i_special) {
c = getbits(2);
while (--c >= 0)
pt_len[i++] = 0;
}
}
while (i < nn)
pt_len[i++] = 0;
lha_make_table(nn, pt_len, 8, pt_table);
}
}
/* ------------------------------------------------------------------------ */
static void read_c_len(void)
{
short i, c, n;
n = getbits(CBIT);
if (n == 0) {
c = getbits(CBIT);
for (i = 0; i < NC; i++)
c_len[i] = 0;
for (i = 0; i < 4096; i++)
c_table[i] = c;
} else {
i = 0;
while (i < n) {
c = pt_table[lhabitbuf >> (16 - 8)];
if (c >= NT) {
unsigned short mask = 1 << (16 - 9);
do {
if (lhabitbuf & mask)
c = h_right[c];
else
c = h_left[c];
mask >>= 1;
} while (c >= NT);
}
fillbuf(pt_len[c]);
if (c <= 2) {
if (c == 0)
c = 1;
else if (c == 1)
c = getbits(4) + 3;
else
c = getbits(CBIT) + 20;
while (--c >= 0)
c_len[i++] = 0;
}
else
c_len[i++] = c - 2;
}
while (i < NC)
c_len[i++] = 0;
lha_make_table(NC, c_len, 12, c_table);
}
}
/* ------------------------------------------------------------------------ */
unsigned short decode_c_st1(void)
{
unsigned short j, mask;
if (blocksize == 0) {
blocksize = getbits(16);
read_pt_len(NT, TBIT, 3);
read_c_len();
read_pt_len(np, pbit, -1);
}
blocksize--;
j = c_table[lhabitbuf >> 4];
if (j < NC)
fillbuf(c_len[j]);
else {
fillbuf(12);
mask = 1 << (16 - 1);
do {
if (lhabitbuf & mask)
j = h_right[j];
else
j = h_left[j];
mask >>= 1;
} while (j >= NC);
fillbuf(c_len[j] - 12);
}
return j;
}
/* ------------------------------------------------------------------------ */
unsigned short decode_p_st1(void)
{
unsigned short j, mask;
j = pt_table[lhabitbuf >> (16 - 8)];
if (j < np)
fillbuf(pt_len[j]);
else {
fillbuf(8);
mask = 1 << (16 - 1);
do {
if (lhabitbuf & mask)
j = h_right[j];
else
j = h_left[j];
mask >>= 1;
} while (j >= np);
fillbuf(pt_len[j] - 8);
}
if (j != 0)
j = (1 << (j - 1)) + getbits(j - 1);
return j;
}
/* ------------------------------------------------------------------------ */
void decode_start_st1(void)
{
if (dicbit <= 13) {
np = 14;
pbit = 4;
} else {
if (dicbit == 16) {
np = 17; /* for -lh7- */
} else {
np = 16;
}
pbit = 5;
}
#if 0
if (dicbit <= 13) { /* 13 ... Changed N.Watazaki */
np = 14;
pbit = 4;
} else {
np = 16;
pbit = 5;
}
#endif
init_getbits();
blocksize = 0;
}
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* larc.c -- extra *.lzs */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
/* ------------------------------------------------------------------------ */
static int flag, flagcnt, matchpos;
/* ------------------------------------------------------------------------ */
unsigned short decode_c_lzs(void)
{
if (getbits(1)) {
return getbits(8);
}
else {
matchpos = getbits(11);
return getbits(4) + 0x100;
}
}
/* ------------------------------------------------------------------------ */
unsigned short decode_p_lzs(void)
{
return (loc - matchpos - MAGIC0) & 0x7ff;
}
/* ------------------------------------------------------------------------ */
void decode_start_lzs(void)
{
init_getbits();
}
/* ------------------------------------------------------------------------ */
unsigned short decode_c_lz5(void)
{
int c;
if (flagcnt == 0) {
flagcnt = 8;
flag = zfile_getc(infile);
}
flagcnt--;
c = zfile_getc(infile);
if ((flag & 1) == 0) {
matchpos = c;
c = zfile_getc(infile);
matchpos += (c & 0xf0) << 4;
c &= 0x0f;
c += 0x100;
}
flag >>= 1;
return c;
}
/* ------------------------------------------------------------------------ */
unsigned short decode_p_lz5(void)
{
return (loc - matchpos - MAGIC5) & 0xfff;
}
/* ------------------------------------------------------------------------ */
void decode_start_lz5(void)
{
int i;
flagcnt = 0;
for (i = 0; i < 256; i++)
memset(&text[i * 13 + 18], i, 13);
for (i = 0; i < 256; i++)
text[256 * 13 + 18 + i] = i;
for (i = 0; i < 256; i++)
text[256 * 13 + 256 + 18 + i] = 255 - i;
memset(&text[256 * 13 + 512 + 18], 0, 128);
memset(&text[256 * 13 + 512 + 128 + 18], ' ', 128 - 18);
}
#include "sysconfig.h"
#include "sysdeps.h"
#include "zfile.h"
#define SYSTIME_HAS_NO_TM
#define NODIRECTORY
#define FTIME
#define NOBSTRING
#define NOINDEX
#define MKTIME
/* ------------------------------------------------------------------------ */
/* LHa for UNIX Archiver Driver */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Soruce All chagned 1995.01.14 N.Watazaki */
/* Ver. 1.14i Modified and bug fixed 2000.10.06 t.okamoto */
/* ------------------------------------------------------------------------ */
/*
Included...
lharc.h interface.h slidehuf.h
*/
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include "lha_macro.h"
struct encode_option {
#if 1 || defined(__STDC__) || defined(AIX)
void (*output) ();
void (*encode_start) ();
void (*encode_end) ();
#else
int (*output) ();
int (*encode_start) ();
int (*encode_end) ();
#endif
};
struct decode_option {
unsigned short (*decode_c) ();
unsigned short (*decode_p) ();
#if 1 || defined(__STDC__) || defined(AIX)
void (*decode_start) ();
#else
int (*decode_start) ();
#endif
};
/* ------------------------------------------------------------------------ */
/* LHa File Type Definition */
/* ------------------------------------------------------------------------ */
struct string_pool {
int used;
int size;
int n;
char *buffer;
};
typedef struct LzHeader {
unsigned char header_size;
char method[METHOD_TYPE_STRAGE];
long packed_size;
long original_size;
long last_modified_stamp;
unsigned char attribute;
unsigned char header_level;
char name[256];
unsigned short crc;
bool has_crc;
unsigned char extend_type;
unsigned char minor_version;
/* extend_type == EXTEND_UNIX and convert from other type. */
time_t unix_last_modified_stamp;
unsigned short unix_mode;
unsigned short unix_uid;
unsigned short unix_gid;
} LzHeader;
struct interfacing {
struct zfile *infile;
struct zfile *outfile;
unsigned long original;
unsigned long packed;
int dicbit;
int method;
};
/* ------------------------------------------------------------------------ */
/* Option switch variable */
/* ------------------------------------------------------------------------ */
/* command line options (common options) */
EXTERN bool quiet;
EXTERN bool text_mode;
EXTERN bool verbose;
EXTERN bool noexec; /* debugging option */
EXTERN bool force;
EXTERN bool prof;
EXTERN bool delete_after_append;
EXTERN int compress_method;
EXTERN int header_level;
/* EXTERN int quiet_mode; */ /* 1996.8.13 t.okamoto */
#ifdef EUC
EXTERN bool euc_mode;
#endif
/* list command flags */
EXTERN bool verbose_listing;
/* extract/print command flags */
EXTERN bool output_to_stdout;
/* add/update/delete command flags */
EXTERN bool new_archive;
EXTERN bool update_if_newer;
EXTERN bool generic_format;
EXTERN bool remove_temporary_at_error;
EXTERN bool recover_archive_when_interrupt;
EXTERN bool remove_extracting_file_when_interrupt;
EXTERN bool get_filename_from_stdin;
EXTERN bool ignore_directory;
EXTERN bool verify_mode;
/* Indicator flag */
EXTERN int quiet_mode;
/* ------------------------------------------------------------------------ */
/* Globale Variable */
/* ------------------------------------------------------------------------ */
EXTERN char **cmd_filev;
EXTERN int cmd_filec;
EXTERN char *archive_name;
EXTERN char expanded_archive_name[FILENAME_LENGTH];
EXTERN char temporary_name[FILENAME_LENGTH];
EXTERN char backup_archive_name[FILENAME_LENGTH];
EXTERN char *reading_filename, *writting_filename;
/* 1996.8.13 t.okamoto */
#if 0
EXTERN bool remove_temporary_at_error;
EXTERN bool recover_archive_when_interrupt;
EXTERN bool remove_extracting_file_when_interrupt;
#endif
EXTERN int archive_file_mode;
EXTERN int archive_file_gid;
EXTERN node *next;
/* EXTERN unsigned short crc; */ /* 1996.8.13 t.okamoto */
EXTERN int noconvertcase; /* 2000.10.6 */
/* slide.c */
EXTERN int unpackable;
EXTERN unsigned long origsize, compsize;
EXTERN unsigned short dicbit;
EXTERN unsigned short maxmatch;
EXTERN unsigned long count;
EXTERN unsigned long loc; /* short -> long .. Changed N.Watazaki */
EXTERN unsigned char *text;
EXTERN int prev_char;
/* huf.c */
#ifndef LHA_MAIN_SRC /* t.okamoto 96/2/20 */
EXTERN unsigned short h_left[], h_right[];
EXTERN unsigned char c_len[], pt_len[];
EXTERN unsigned short c_freq[], c_table[], c_code[];
EXTERN unsigned short p_freq[], pt_table[], pt_code[], t_freq[];
#endif
/* append.c */
#ifdef NEED_INCREMENTAL_INDICATOR
EXTERN long indicator_count;
EXTERN long indicator_threshold;
#endif
/* crcio.c */
EXTERN struct zfile *infile, *outfile;
EXTERN unsigned short crc, lhabitbuf;
EXTERN int dispflg;
EXTERN long reading_size;
/* from dhuf.c */
EXTERN unsigned int n_max;
/* lhadd.c */
EXTERN FILE *temporary_fp;
/* ------------------------------------------------------------------------ */
/* Functions */
/* ------------------------------------------------------------------------ */
/* from lharc.c */
extern int patmatch();
extern void interrupt();
extern void message();
extern void warning();
extern void error();
extern void fatal_error();
extern bool need_file();
extern int inquire();
extern FILE *xfopen();
extern bool find_files();
extern void free_files();
extern void init_sp();
extern void add_sp();
extern void finish_sp();
extern void free_sp();
extern void cleaning_files();
extern void build_temporary_name();
extern void build_backup_file_name();
extern void build_standard_archive_name();
extern FILE *open_old_archive();
extern void init_header();
extern bool get_header(struct zfile *fp, LzHeader *hdr);
extern bool archive_is_msdos_sfx1();
extern bool skip_msdos_sfx1_code();
extern void write_header();
extern void write_archive_tail();
extern void copy_old_one();
extern unsigned char *convdelim(unsigned char *path, unsigned char delim);
extern long copyfile();
extern void cmd_list(), cmd_extract(), cmd_add(), cmd_delete();
extern char *extract_directory;
/* from slide.c */
extern int encode_alloc();
extern void encode();
extern int decode(struct interfacing*);
/* from append.c */
extern void start_indicator();
extern void finish_indicator();
extern void finish_indicator2();
/* slide.c */
extern void output_st1();
extern unsigned char *alloc_buf();
extern void encode_start_st1();
extern void encode_end_st1();
extern unsigned short decode_c_st1();
extern unsigned short decode_p_st1();
extern void decode_start_st1();
/* from shuf.c */
extern void decode_start_st0();
extern void encode_p_st0( /* unsigned short j */ );
extern void encode_start_fix();
extern void decode_start_fix();
extern unsigned short decode_c_st0();
extern unsigned short decode_p_st0();
/* from dhuf.c */
extern void start_c_dyn();
extern void decode_start_dyn();
extern unsigned short decode_c_dyn();
extern unsigned short decode_p_dyn();
extern void output_dyn( /* int code, unsigned int pos */ );
extern void encode_end_dyn();
extern int decode_lzhuf();
/* from larc.c */
extern unsigned short decode_c_lzs();
extern unsigned short decode_p_lzs();
extern unsigned short decode_c_lz5();
extern unsigned short decode_p_lz5();
extern void decode_start_lzs();
extern void decode_start_lz5();
extern void lha_make_table(short nchar, unsigned char bitlen[], short tablebits, unsigned short table[]);
/* from maketree.c */
/*
* void make_code(short n, uchar len[], ushort code[]); short make_tree(short
* nparm, ushort freqparm[], uchar lenparm[], ushort codeparam[]);
*/
extern void make_code( /* int n, uchar len[], ushort code[] */ );
extern short make_tree( /* int nparm, ushort freqparm[], uchar lenparm[],
ushort codeparam[] */ );
/* from crcio.c */
extern void make_crctable();
extern unsigned short calccrc(unsigned char *p, unsigned int n);
extern void fillbuf(unsigned char n);
extern unsigned short getbits(unsigned char n);
extern void putcode(unsigned char n, unsigned short x);
extern void putbits(unsigned char n, unsigned short x);
extern int fread_crc(unsigned char *p, int n, struct zfile *f);
extern void fwrite_crc(unsigned char *p, int n, struct zfile *f);
extern void init_getbits();
extern void init_putbits();
extern void make_crctable();
extern unsigned short calccrc();
/* from lhadd.c */
extern int encode_lzhuf();
extern int encode_stored_crc();
#define warning write_log
#define fatal_error write_log
#define error write_log
This diff is collapsed.
/* ------------------------------------------------------------------------ */
/* LHa for UNIX */
/* maketbl.c -- makes decoding table */
/* */
/* Modified Nobutaka Watazaki */
/* */
/* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
/* ------------------------------------------------------------------------ */
#include "lha.h"
void lha_make_table(short nchar, unsigned char bitlen[], short tablebits, unsigned short table[])
{
unsigned short count[17]; /* count of bitlen */
unsigned short weight[17]; /* 0x10000ul >> bitlen */
unsigned short start[17]; /* first code of bitlen */
unsigned short total;
unsigned int i, l;
int j, k, m, n, avail;
unsigned short *p;
avail = nchar;
/* initialize */
for (i = 1; i <= 16; i++) {
count[i] = 0;
weight[i] = 1 << (16 - i);
}
/* count */
for (i = 0; i < nchar; i++)
count[bitlen[i]]++;
/* calculate first code */
total = 0;
for (i = 1; i <= 16; i++) {
start[i] = total;
total += weight[i] * count[i];
}
if ((total & 0xffff) != 0)
error(L"make_table()", L"Bad table (5)\n");
/* shift data for make table. */
m = 16 - tablebits;
for (i = 1; i <= tablebits; i++) {
start[i] >>= m;
weight[i] >>= m;
}
/* initialize */
j = start[tablebits + 1] >> m;
k = 1 << tablebits;
if (j != 0)
for (i = j; i < k; i++)
table[i] = 0;
/* create table and tree */
for (j = 0; j < nchar; j++) {
k = bitlen[j];
if (k == 0)
continue;
l = start[k] + weight[k];
if (k <= tablebits) {
/* code in table */
for (i = start[k]; i < l; i++)
table[i] = j;
}
else {
/* code not in table */
p = &table[(i = start[k]) >> m];
i <<= tablebits;
n = k - tablebits;
/* make tree (n length) */
while (--n >= 0) {
if (*p == 0) {
h_right[avail] = h_left[avail] = 0;
*p = avail++;
}
if (i & 0x8000)
p = &h_right[*p];
else
p = &h_left[*p];
i <<= 1;
}
*p = j;
}
start[k] = l;
}
}
/* Local Variables: */
/* mode:c */
/* tab-width:4 */
/* End: */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
extern struct zfile *unwarp(struct zfile*);
#include <stdio.h>
void *xmalloc(int v)
{
return malloc(v);
}
void *zfile_fopen(const char *name, const char *mode)
{
return fopen(name, mode);
}
void zfile_fclose(void *z)
{
fclose(z);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment