#include <stdio.h>
#include <limits.h>
#include "typedef.h"
#include "errmes.h"

struct encode_option {
	void (*output)();
	void (*encode_start)();
	void (*encode_end)();
};

struct decode_option {
	ushort (*decode_c)();
	ushort (*decode_p)();
	void (*decode_start)();
};

/* from slide.c */
#define MAX_DICBIT    13 
#define MAX_DICSIZ (1U << MAX_DICBIT)
#define MATCHBIT   8    /* bits for MAXMATCH - THRESHOLD */
#define MAXMATCH 256    /* formerly F (not more than UCHAR_MAX + 1) */
#define THRESHOLD  2    /* choose optimal value */

extern int unpackable;
extern ulong origsize, compsize;
extern ushort dicbit;
extern ushort maxmatch;
extern ulong count;
extern ushort loc;
#if 0
extern uchar *text;
#else
extern uchar text[];
#endif

/* from huf.c */
#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
								/* alphabet = {0, 1, 2, ..., NC - 1} */
#define CBIT 9  /* $\lfloor \log_2 NC \rfloor + 1$ */
#define USHRT_BIT 16	/* (CHAR_BIT * sizeof(ushort)) */

extern ushort left[], right[];
extern uchar c_len[], pt_len[];
extern ushort c_freq[], c_table[], c_code[],
			  p_freq[], pt_table[], pt_code[],
			  t_freq[];

void output_st1(ushort c, ushort p);
void far *alloc_buf(void);
void encode_start_st1(void);
void encode_end_st1(void);
ushort decode_c_st1(void);
ushort decode_p_st1(void);
void decode_start_st1(void);

/* from shuf.c */
void decode_start_st0(void);
void encode_p_st0(unsigned short j);
void encode_start_fix(void);
void decode_start_fix(void);
ushort decode_c_st0(void);
ushort decode_p_st0(void);

/* from dhuf.c */
extern uint n_max;

void start_c_dyn(void);
void decode_start_dyn(void);
ushort decode_c_dyn(void);
ushort decode_p_dyn(void);
void output_dyn(int code, unsigned int pos);
void encode_end_dyn(void);

/* from larc.c */
ushort decode_c_lzs(void);
ushort decode_p_lzs(int loc);
ushort decode_c_lz5(void);
ushort decode_p_lz5(int loc);
void decode_start_lzs(void);
void decode_start_lz5(void);

/* from maketbl.c */
void make_table(short nchar, uchar bitlen[],
				short tablebits, ushort table[]);

/* from maketree.c */
void make_code(short n, uchar len[], ushort code[]);
short make_tree(short nparm, ushort freqparm[], 
                uchar lenparm[], ushort codeparam[]);

/* from crcio.c */
extern FILE *infile, *outfile;
extern ushort crc, bitbuf;
extern int dispflg;

void fillbuf(uchar n);
ushort getbits(uchar n);
void putcode(uchar n, ushort x);
void putbits(uchar n, ushort x);
int fread_crc(uchar *p, int n, FILE *f);
void fwrite_crc(uchar *p, int n, FILE *f);
void init_getbits(void);
void init_putbits(void);
