/* *********************************************************************************

	Filename : EXPAND.C
	Contents : ＬＺＳＳデータ展開

	Comment  : 対象データは、comp.exe によって圧縮されたものです。

	History  : Ver 1.00		2000/12/14		K.Kimura	Base:H.Sato

********************************************************************************* */

#include	"main.h"									/* main.h				*/


#define		EXP_DEBUG		FALSE


static	u_long	ExpSrcSize;
static	u_long	ExpCompSize;
static	char	ebuf[ 32];

/* ******************************************************************************
　関　　数：ExpExpand
　内　　容：COMP.EXE によって圧縮されたデータの展開
　表　　記：u_long	ExpExpand( char far *src, char near *dist)
　引　　数：char far	*src  : 圧縮ﾃﾞｰﾀｱﾄﾞﾚｽ
		　：char far	*dist : 展開先ｱﾄﾞﾚｽ
　返　　値：負数 .. ｴﾗｰ
		　：正数 .. ｿｰｽｻｲｽﾞ
　コメント：
　履　　歴：Ver 1.00	2000/12/14		K.Kimura		初版 (BASE:H.Sato)
****************************************************************************** */
u_long		ExpExpand( char far *src, char near *dist)
{
	int			i, j;
	long		ct,	ofs;
	u_char 	near		*wpfirst, *wp,  *back;
	u_char	far			*now;
	short		flagcount, flagdata;
	short		flag;



	/* ///  各変数の設定  /// */
	now = (u_char far*)src;
	wp  = wpfirst = (u_char near*)dist;

	ExpSrcSize  = (( now[ 0] << 16) | ( now[ 1] << 8) | now[ 2]);
	ExpCompSize = (( now[ 3] << 16) | ( now[ 4] << 8) | now[ 5]);

	now += 6;

	flagcount	= 8;
	flagdata	= 0;
	flag		= 0x01;

	/* ///  ●データ展開処理●  /// */
	while (( wp - wpfirst) < ExpSrcSize)
	{
		if (flagcount >= 8)
		{
			flagcount	= 0;
			flagdata	= *now++;
			flag		= 0x01;
		}

		/* ///  ●圧縮判定●  /// */
		if (flagdata & flag)
		{
			/* ///  ■圧縮されていた場合  /// */
			/* ofs = ((( *now++) << 8) | ( *now++)); */

			ofs = (( now[ 0] << 8) | now[ 1]);
			now += 2;

/*			ct = (( ofs >> 12) & 0x0f);	*/
			ct = ofs;

			for (j = 0; j < 12; j++)
				ct = (ct >> 1);

			ct  &= 0x0f;
			ofs &= 0x0fff;
			ofs ++;

			if (ct == 0x0f)						/* １８バイト以上の場合			*/
			{
				ct = 15 + *now++;
			}

			back = (u_char near*)( (long)wp - ofs);
			ct += 3;							/* もともと 3byte 少ない値なので */

			for (i = 0; i < ct; i++)
			{
				*wp++ = *back++;
			}
		}
		else
		{
			/* ///  ■圧縮無しの場合  /// */
			*wp++ = *now++;
		}

		flagcount ++;
		flag += flag;
	}

	/* ///  展開サイズとソースサイズの比較  /// */
	if (( wp - wpfirst) != ExpSrcSize)
	{
		DbgPrintPort("圧縮または展開がうまくいっていない可能性があります。\r\n");
		return ( -1);
	}

#if	EXP_DEBUG
	sprintf( ebuf, "SRC,COMP::%d,%d\r\n", ExpSrcSize, ExpCompSize);
	DbgPrintPort( ebuf);
	sprintf( ebuf, "%2x,%2x,%2x,%2x\r\n", dist[0], dist[1], dist[2], dist[3]);
	DbgPrintPort( ebuf);
#endif


	return( ExpSrcSize);

}


