/***********************************************************************
  This file is part of HA, a general purpose file archiver.
  Copyright (C) 1995 Harri Hirvola

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
************************************************************************
	HA HSC method
***********************************************************************/

#ifndef Included_hsc_h
#define Included_hsc_h

#include "ha.h"
#include "haio.h"
#include "acoder.h"


#define IECLIM		32	       /* initial escape counter upper limit */
#define NECLIM		5	       /* no escape expected counter limit */
#define NECTLIM	4	       /* */
#define NECMAX		10	       /* no escape expected counter maximum */
#define MAXCLEN	4	       /* assumed to be 4 in several places */
#define NUMCON		10000	    /* number of contexts to remember */ 
#define NUMCFB		32760	    /* number of frequencies to remember */
#define ESCTH		3	       /* threshold for escape calculation */
#define MAXTVAL	8000	    /* maximum frequency value */
#define RFMINI		4	       /* initial refresh counter value */
#define HTLEN	   16384	    /* length of hash table */
#define NIL			0xffff	 /* NIL pointer in lists */
#define ESC			256	    /* escape symbol */

typedef unsigned char Context[4];

struct hsc
{
	struct haio *haio;
	struct acoder *ac;

/* model data */
	Context curcon;		      /* current context */
	U16B *ht;						/* hash table */
	U16B *hp;						/* hash list pointer array */
	Context *con;					/* context array */
	unsigned char *cl;	      /* context length array */
	unsigned char *cc;	      /* character counts */
	U16B *ft;						/* total frequency of context */
	unsigned char *fe;	      /* frequencys under ESCTH in context */
	U16B *elp;						/* expire list previous pointer array */
	U16B *eln;						/* expire list next pointer array */
	U16B elf,ell;					/* first and last of expire list */
	unsigned char *rfm;	      /* refresh counter array */
	U16B *fa;						/* frequency array */
	unsigned char *fc;	      /* character for frequency array */
	U16B *nb;						/* next pointer for frequency array */
	U16B fcfbl;						/* pointer to free frequency blocks */
	U16B nrel;						/* context for frequency block release */

/* frequency mask system */
	unsigned char cmask[256];     /* masked characters */
	unsigned char cmstack[256];   /* stack of cmask[] entries to clear */ 
	S16B cmsp;							/* pointer to cmstack */

/* escape propability modifying system variables */
	unsigned char nec;				/* counter for no escape expected */
	unsigned char iec[MAXCLEN+1]; /* initial escape counters */

/* update stack variables */
	U16B usp;						/* stack pointer */
	U16B cps[MAXCLEN+1]; 	   /* context pointers */
	U16B as[MAXCLEN+1];	      /* indexes to frequency array */

/* miscellaneous */
	S16B dropcnt;		      /* counter for context len drop */
	unsigned char maxclen;	/* current maximum length for context */ 
	U16B hrt[HTLEN];		   /* semi random data for hashing */
	U16B hs[MAXCLEN+1]; 	   /* hash stack for context search */ 
	S16B cslen;					/* length of context to search */
};

/*	Setup for HSC method
*/
struct hsc *hsc_setup(void);

/*	HSC method packing function
*/
U32B hsc_pack(struct hsc *hsc, unsigned char *ibuf, U32B ilen, unsigned char *obuf, U32B olen);

/*	HSC method unpacking function
*/
U32B hsc_unpack(struct hsc *hsc, unsigned char *ibuf, U32B ilen, unsigned char *obuf, U32B olen);

/*	Cleanup for HSC method
*/
void hsc_cleanup(struct hsc *hsc);

#endif/* !Included_hsc_h */

