/*	:*****************************************************************
	:	アイコンデータを作成する
	:*****************************************************************
*/
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<ctype.h>
#include	<memory.h>

#define	UCHAR	unsigned char
#define	SHORT	short

typedef	struct
{	char	idCode[10];
	SHORT	version;
	SHORT	tblNum;
	SHORT	icnNum;
	long	icnOfs;
	char	rsv[12];
} ICNHEAD_T;

typedef	struct
{	SHORT	id;
	SHORT	icnNum;
	SHORT	typ;
	SHORT	icnSiz;
	long	infOfs;
	long	ptnOfs;
	char	rsv[16];
} ICNTBL_T;

typedef	struct
{	SHORT	id;
	SHORT	xb,	yb;
	SHORT	xs,	ys;
	long	col;
	SHORT	siz;
	char	rsv[4];
	long	ptnOfs;
	long	mskOfs;
	char	rsv2[20];
} ICNINFO_T;

char	MonoFlag = 0;	/* マスクデータ作成用	*/

void	MakeIconDat(char *fn, char *writePath)
{
	int			i, j, k;
	FILE		*rfp, *wfp;
	UCHAR		*buf;
	ICNHEAD_T	icnHead;
	ICNTBL_T	icnTbl;
	ICNINFO_T	icnInfo;

	if ( (rfp = fopen(fn,"rb")) == NULL )
	{	fprintf(stderr,"@ file open error!! (%s)\n", fn);
		exit(1);
	}
	/* ヘッダ情報の読み取り	*/
	fread(&icnHead,sizeof(ICNHEAD_T),1,rfp);
	if ( memcmp(icnHead.idCode, "ICNFILE", 7) != 0 )
	{	fclose(rfp);
		fprintf(stdout,"@ icon file header error!!\n");
		exit(1);
	}
	if ( icnHead.tblNum == 0 || icnHead.icnNum == 0 )
	{	fclose(rfp);
		fprintf(stdout,"@ アイコンデータが存在しません！！\n");
		exit(1);
	}

	if ( writePath == NULL )
		wfp = stdout;
	else
	{	if ( (wfp = fopen(writePath, "wb")) == NULL )
		{	fprintf(stderr,"@ file open error!! (%s)\n", writePath );
			exit(1);
		}
	}
	for ( i = 0; i < icnHead.tblNum; ++i )
	{
		fseek(rfp, (long)sizeof(ICNHEAD_T) + (long)i*(long)sizeof(ICNTBL_T), SEEK_SET);
		fread(&icnTbl, sizeof(ICNTBL_T),1, rfp);

		for ( j = 0; j < icnTbl.icnNum; ++j )
		{
			fprintf(stderr,"icon table offset $%08lX\n", icnTbl.infOfs);
			fseek(rfp,icnTbl.infOfs, SEEK_SET);
			fread(&icnInfo, sizeof(ICNINFO_T),1,rfp);
			icnTbl.infOfs += sizeof(ICNINFO_T);

			fprintf(stderr,"icon pattern offset $%08lX\n", icnInfo.ptnOfs);

			if ( (buf = malloc(icnInfo.siz)) == NULL )
			{	fprintf(stderr,"Memory allocation error!!n");
				exit(1);
			}
			fseek(rfp,icnInfo.ptnOfs,SEEK_SET);
			fread((char *)buf, (size_t)icnInfo.siz, 1, rfp);

			if ( MonoFlag && icnInfo.col == 16 )
			{	/* モノクロデータに変換	*/
				for ( k = 0; k < icnInfo.siz; k += 4)
				{
					UCHAR	dat;
					dat = 0;
					if ( ~(buf[k  ]) & 0x0F )	dat |= 0x80;
					if ( ~(buf[k  ]) & 0xF0 )	dat |= 0x40;
					if ( ~(buf[k+1]) & 0x0F )	dat |= 0x20;
					if ( ~(buf[k+1]) & 0xF0 )	dat |= 0x10;
					if ( ~(buf[k+2]) & 0x0F )	dat |= 0x08;
					if ( ~(buf[k+2]) & 0xF0 )	dat |= 0x04;
					if ( ~(buf[k+3]) & 0x0F )	dat |= 0x02;
					if ( ~(buf[k+3]) & 0xF0 )	dat |= 0x01;
					buf[k/4] = dat;
				}
				icnInfo.siz /= 4;
				icnInfo.col = 1;
			}
			fprintf(wfp,"\n/* ID:%03d,#%03d, icon size (%02d,%02d) %3d bytes %d color(s)*/\n", 
				icnInfo.id>>8, icnInfo.id & 0xFF, icnInfo.xs, icnInfo.ys,
				icnInfo.siz, icnInfo.col );
			for ( k = 0; k < icnInfo.siz; ++k )
			{
				fprintf(wfp,"0x%02X,",buf[k]);
				if ( (k & 7) == 7 )
					fprintf(wfp,"\n");
			}
			if ( (icnInfo.siz & 7) != 0 )
				fprintf(wfp,"\n");
			free(buf);
		}
	}
	fclose(wfp);
	fclose(rfp);
}

void	help(void)
{	exit(1);
}

void	main(int argc,char *argv[])
{
	char	*s;
	int		i;
	char	*fn = NULL;
	char	*writePath = NULL;

	for ( i = 1; i < argc; ++i )
	{	s = argv[i];
		if ( *s == '?' )
			help();
		if ( *s == '-' || *s == '/' )
		{	/* option(s)	*/
			++s;
			if ( *s == '?' )
				help();
			if ( tolower(*s) == 'w' )
			{	writePath = &s[1];
			} else if ( *s == 'm' || *s == 'M' )
				MonoFlag = 1;	/* モノクロ指定	*/
		} else if ( fn == NULL )
			fn = s;
	}
	if ( fn == NULL )
		fn = "towns.icn";

	MakeIconDat( fn, writePath );

	exit(0);
}

