/*********************************************************************

		   FM-TOWNS TIFF FILE -> MSX SCREEN12 BSAVE FILE 
   		     by ちにゃと    (NIFTY-Serve ID:GFH01000)

		            1993/12/07       Ver 2.1 L20            

********************************************************************/

                     
#include <io.h>
#include <fcntl.h>
#include <stat.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <mos.h>
#include <math.h>
#include <stat.h>

/* T-BIOS C ﾗｲﾌﾞﾗﾘ ﾍｯﾀﾞｰ */
#include <fmcfrb.h>

char tifheader[512];
char scchead[10] ={
0xfe,0x00,0x00,0xff,0xd3,0x00,0x00
};
char readbuf[2432];
char fname[256];
char filepath[256];
char tifext[10];
char sccdata[256*64][4];
char tifdata[256*64][8];
char wildfname[100][256];
unsigned char r[5];
unsigned char g[5];
unsigned char b[5];
unsigned char y[5];
unsigned char k,kj;
int rshift,gshift,bshift,xshift,yshift;
unsigned long int tif_x_size,tif_y_size,tifsize;
unsigned long int copy_x_size,copy_y_size;
int i,j,wildcard;
int tagp;
int w_ret;
int mode;
int fileno;
int namelen;
int flong;
int findflag;
int wildct;
static struct find_t wildfbuf;
static unsigned long ret,pan;

/************************************************************
【オプション解析】

		概要	ｵﾌﾟｼｮﾝﾊﾟﾗﾒ-ﾀの解析を行い結果を返す
		用法	optionset( argc, *argv[] );
		引数	int		argc
				char	*argv[]
		戻り値 	int		0	正常終了
						-1	ｵﾌﾟｼｮﾝの指定が正しくない
************************************************************/

int optionset( int argc, char *argv[] ){

	int		count;
	char	c;
	ret=0;

	strcpy(tifext,"TIF");
	rshift=0;
	gshift=0;
	bshift=0;	
	ret = 0;
	findflag=0;
	/* ｵﾌﾟｼｮﾝ ﾊﾟﾗﾒｰﾀ 解析 */
	if ( argc == 1 ) {
		ret=-1;
	} 
	else{
		for ( count = 1; count < argc; count++ ){
            c = *argv[count];                        /* 先頭文字 get */
            if ( c == '/' || c == '-' ){
                c = *(argv[count] + 1);                /* 2 文字目 get */
                switch ( c ){
                    case 'h':
                    case 'H':
                    case '?':
                        ret = -1;
                        break;

                    case 'x':
                    case 'X':
    	                xshift = *(argv[count] + 2);
                        xshift -= 0x30; 
                        if ((*(argv[count] + 3)>0x2f) &&
                        		(*(argv[count] + 3)<0x3a)   ){
                        	xshift=xshift*10+(*(argv[count] + 3))-0x30;
                        }
                        if ((*(argv[count] + 4)>0x2f) &&
                        		(*(argv[count] + 4)<0x3a)   ){
                        	xshift=xshift*10+(*(argv[count] + 4))-0x30;
                        }
                        break;

                    case 'y':
                    case 'Y':
    	                yshift = *(argv[count] + 2);
                        yshift -= 0x30; 
                        if ((*(argv[count] + 3)>0x2f) &&
                        		(*(argv[count] + 3)<0x3a)   ){
                        	yshift=yshift*10+(*(argv[count] + 3))-0x30;
                        }
                        if ((*(argv[count] + 4)>0x2f) &&
                        		(*(argv[count] + 4)<0x3a)   ){
                        	yshift=yshift*10+(*(argv[count] + 4))-0x30;
                        }
                        break;

                    case 'r':
                    case 'R':
    	                rshift = *(argv[count] + 2);
                        rshift -= 0x30; 
                        if ((*(argv[count] + 3)>0x30) &&
                        		(*(argv[count] + 3)<0x34)   ){
                        	rshift=rshift*10+(*(argv[count] + 3))-0x30;
                        }
                        break;

                    case 'g':
                    case 'G':
    	                gshift = *(argv[count] + 2);
                        gshift-=0x30;
                        if ((*(argv[count] + 3)>0x30) &&
                        		(*(argv[count] + 3)<0x34)   ){
                        	gshift=gshift*10+(*(argv[count] + 3))-0x30;
                        }
                        break;

                    case 'b':
                    case 'B':
    	                bshift = *(argv[count] + 2);
                        bshift-=0x30;
                        if ((*(argv[count] + 3)>0x30) &&
                        		(*(argv[count] + 3)<0x34)   ){
                        	bshift=bshift*10+(*(argv[count] + 3))-0x30;
                        }
                        break;

  	                /* 無効 ﾊﾟﾗﾒｰﾀ */
    	            default:
                    ret = -1;
                }		/* <switch> */
            }
            else{
               	strcpy(fname, argv[count] );
         	}
        }	/* <for> */
  	}
	if(ret==-1){
		printf("****************************************************\n");
		printf("     FM-TOWNS TIFF FILE ->MSX SCREEN12 BSAVE FILE\n");
		printf("        by ちにゃと    (NIFTY-Serve ID:GFH01000)\n");
		printf("            1993/12/07       Ver 2.1 L20        \n");
		printf("****************************************************\n");
		printf("\n");
		printf("用法) RUN386  TIF2SCC.EXP [-Rx] [-Gx] [-Bx] [-Xx] [-Yx] FILENAME\n");
		printf("\n");
		printf("-Rx -Gx -Bx   RGBの強さを調整  x=0〜31 \n");
		printf("              省略時は -R0 -G0 -B0\n");
		printf("              \n");
		printf("\n");
		printf("-Xx -Yx       取り込み位置の左上角の座標   \n");
		printf("\n");
		printf("\n");
		printf("FILENAME      拡張子が .TIF  のみ\n");
		printf("              ワイルドカ−ドも指定可能\n");
		printf("\n");
		printf("ex1)  RUN386 TIF2SCC.EXP SAMPLE.TIF\n");
		printf("ex2)  RUN386 TIF2SCC.EXP A:*.TIF\n");
		printf("ex3)  RUN386 TIF2SCC.EXP A:\\SCC\\SAMPLE*.TIF\n");
		return(-1);
	}
	namelen=strlen(fname);
	flong=namelen;
	for ( i =namelen-1; (i+1)>0 ;i-- ){
		fname[i]=toupper(fname[i]);
	}
	for ( i =namelen-1; (i+1)>0 ;i-- ){
		if ( fname[i] != 0x5c ){
			flong -= 1;
		}
		else {
			findflag=1;
			break;
		}
	}
	if(findflag==0){
		flong=1;
		for ( i = 0; i <255 ;i ++ ){
			if ( fname[i] != 0x3a ){
				flong += 1;
			}
			else {
				findflag=2;
				break;
			}
		}
	}
	if(findflag!=0){
		strncpy( filepath,fname,flong );
	}
	flong =strlen(fname);
	for (i=0;i<3;i++){
		if(fname[flong-3+i]!=tifext[i]&&fname[flong-3+i]!=(tifext[i]+0x20))
		{
			printf("拡張子が .TIF でありません｡\n");
			return(-1);
		}
	}
	return ret;
}
/************************************************************

						tifload

************************************************************/
int tifload()

{
char fname2[256];

strcpy(fname2,fname);
printf("%s  ",fname);

	clrwork();
	if (_access(fname2,0) !=0 ){
		printf("no tif file");
		return(-1);
	}
	else{
		pan=_open(fname2,_O_BINARY | _O_RDWR );
		if (pan== -1 ){
			return(-1);
		}
		ret=_read(pan,tifheader,512);
		if (ret== -1){
			_close(pan);
			return(-1);
		}
		else{
			if(tifheader[0]!=0x49||tifheader[1]!=0x49||
				tifheader[4]!=0x08						){
				printf("モトロ−ラ−形式TIFFはコンバ−ト出来ません｡\n");
				_close(pan);
				return(-1);
			}
			tagp=0x0a;
			for(i=0;i<tifheader[0x08];i++){
				if(	tifheader[0x0a+i*12]==0x03 && 
					tifheader[0x0b+i*12]==0x01		){
					tagp+=i*12;
					break;
				}
			}
			if(tagp==0x0a){
				printf("Complessタグが見つかりません｡\n");
				_close(pan);
				return(-1);
			}
			tagp+=8;			
			if(tifheader[tagp]!=0x01){
				printf("圧縮TIFFはコンバ−ト出来ません｡\n");
				_close(pan);
				return(-1);
			}
			tagp=0x0a;
			for(i=0;i<tifheader[0x08];i++){
				if(	tifheader[0x0a+i*12]==0x02 && 
					tifheader[0x0b+i*12]==0x01		){
					tagp+=i*12;
					break;
				}
			}
			if(tagp==0x0a){
				printf("BitPerPixelタグが見つかりません｡\n");
				_close(pan);
				return(-1);
			}
			tagp+=8;			
			if(tifheader[tagp]!=0x10){
				printf("32K色TIFF以外はコンバ−ト出来ません｡\n");
				_close(pan);
				return(-1);
			}
			tagp=0x0a;
			for(i=0;i<tifheader[0x08];i++){
				if(	tifheader[0x0a+i*12]==0x00 && 
					tifheader[0x0b+i*12]==0x01		){
					tagp+=i*12;
					break;
				}
			}
			if(tagp==0x0a){
				printf("ImegeWidthタグが見つかりません｡\n");
				_close(pan);
				return(-1);
			}
			tagp+=8;			
			tif_x_size=tifheader[tagp+2]*256*256+
					tifheader[tagp+1]*256+tifheader[tagp];
			tagp=0x0a;
			for(i=0;i<tifheader[0x08];i++){
				if(	tifheader[0x0a+i*12]==0x01 && 
					tifheader[0x0b+i*12]==0x01		){
					tagp+=i*12;
					break;
				}
			}
			if(tagp==0x0a){
				printf("ImegeLengthタグが見つかりません｡\n");
				_close(pan);
				return(-1);
			}
			tagp+=8;			
			tif_y_size=tifheader[tagp+2]*256*256+
					tifheader[tagp+1]*256+tifheader[tagp];

			if(xshift>=tif_x_size || yshift>=tif_y_size ){
				printf("指定座標が大きすぎます。MAX_X=%4d MAX_Y=%4d\n"
						,tif_x_size-1,tif_y_size-1 );
				_close(pan);
				return(-1);
			} 
			tifsize=512;
			copy_x_size=512;
			if((xshift+256)>tif_x_size ){
				copy_x_size=tif_x_size-xshift;
			} 
			copy_y_size=212;
			if( (yshift+212)>tif_y_size ){
				copy_y_size=tif_y_size-yshift;
			} 
			for(i=0 ;i<copy_y_size+yshift ;i++ ){
				ret = _read(pan,&readbuf[0],tif_x_size*2);
				if (ret == -1 ){
					_close(pan);
					printf("読み込みエラ−が発生しました。\n");
					return(-1);
				}
				else{
					if(i>=yshift){
						tifsize+=tif_x_size*2;
						memcpy(&tifdata[64*(i-yshift)][0]
								,&readbuf[xshift*2],copy_x_size*2);
					}	
				}
			}
			_close(pan);
		}
	}
	return(0);
}
/***************************************************************
【ﾃﾞ-ﾀﾌｧｲﾙを作成する】

		概要	
		用法	sccsave();
		引数	無し
***************************************************************/

int sccsave ( void )
{
	char fname2[256];
	int		wsize;
	flong = 0;

	for ( i = 0; i <251 ;i ++ ){
		if ( fname[i] != 0x2e ){
			flong += 1;
		}
		else {
			break;
		}
	}
	strncpy( fname2,fname,flong );
	fname2[flong]=0x00;
	strcat( fname2,".SCC");
	fname2[flong+4]=0x00;



	if ( _access( fname2, 0 ) == 0 ) {
		printf( " 同名のファイルがあります。上書きします。" );
		ret = _unlink ( fname2 );
	}
	ret = 0;
	pan = _open( fname2,_O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE );
	if ( pan == -1) {
		printf("  書き込みのオ−プンに失敗しました。 \n" );
		ret = -1;
	}
	if ( ret == 0 ) {
		wsize = _write( pan, &scchead[0], 7 );
		if ( wsize == -1 || wsize != 7 ) {
			printf("  ヘッダ書き込みに失敗しました。\n" );
			_close( pan );
			return(-1);
		}
		else{

			wsize = _write( pan, &sccdata[0][0], 256*212  );
			if ( wsize == -1 || wsize != 256*212 ) {
				printf("  デ−タ書き込みに失敗しました。\n" );
				_close( pan );
				return(-1);
			}
			else{
				printf("\n");
			}
		}
	}
	return (0);
}


/*********************************************************

			  			clrwork
			  			
*********************************************************/
int clrwork(){
	for(i=0;i<256*64;i++){
		for(j=0;j<8;j++){
			tifdata[i][j]=0;
		}
		for(j=0;j<4;j++){
			sccdata[i][j]=0;
		}
	}
	return(0);
}

/*********************************************************

			  			convert
			  			
*********************************************************/
int convert(){
	for(i=0;i<13568;i++){
		for(j=0;j<4;j++){
			b[j]=(tifdata[i][j*2+0] & 0x1f)+bshift;
			g[j]=(tifdata[i][j*2+1] & 0x7c)/4+gshift;
			r[j]=(tifdata[i][j*2+0]&0xe0)/32+
				 (tifdata[i][j*2+1]&0x03)*8+rshift;
			y[j]=(b[j]+1)/2+(r[j]+1)/4+(g[j]+1)/8;
		}
		g[4]=(g[0]+g[1]+g[2]+g[3])/4;
		r[4]=(r[0]+r[1]+r[2]+r[3])/4;
		b[4]=(b[0]+b[1]+b[2]+b[3])/4;
		y[4]=(b[4]+1)/2+(r[4]+1)/4+(g[4]+1)/8;
		kj=r[4]-y[4];
		k=g[4]-y[4];
		if((kj & 0x80)!=0){
			kj=kj & 0x3f;
		}
		if((k & 0x80)!=0){
			k=k & 0x3f;
		}
		sccdata[i][0]=y[0]*8+(k & 0x07);
		sccdata[i][1]=y[1]*8+(k / 8);
		sccdata[i][2]=y[2]*8+(kj & 0x07);
		sccdata[i][3]=y[3]*8+(kj / 8);
	}
	return(0);
}

/*********************************************************

			  			メイン

*********************************************************/


void main( int argc, char *argv[] ){
	fileno=0;
	mode=0x16;
	if(optionset( argc, argv )!=0){
		exit(-1);
	}
	for ( i = 0; i <251 ;i ++ ){
		if ( fname[i] != 0x2a ){
			flong += 1;
		}
		else {
			wildcard=1;
			break;
		}
	}
	if(wildcard==1){
		w_ret=_dos_findfirst((char*)fname,mode,&wildfbuf);
		if(w_ret){
			printf("指定のワイルドカ−ドが見つかりません\n");
			exit(-1);
		}
		else{
			strcpy(wildfname[fileno],wildfbuf.name);
			fileno++;
			for (;;){
				w_ret=_dos_findnext(&wildfbuf);
				if(w_ret){
					break;
				}
				strcpy(wildfname[fileno],wildfbuf.name);
				fileno++;
			}
		}
		for(wildct=0;wildct<fileno;wildct++){
			strcpy(fname,filepath);
			strcat(fname,wildfname[wildct]);
 			if(tifload()!=0){
				exit(-1);
			}
			if(convert()!=0){
				exit(-1);
			}
			strcpy(fname,wildfname[wildct]);
			if(sccsave()!=0){
				exit(-1);
			}
		}
	}
	else{
	
	
	
		if(tifload()!=0){
			exit(-1);
		}
		if(convert()!=0){
			exit(-1);
		}
		findflag=0;
		namelen=strlen(fname);
		flong=namelen;
		for ( i =namelen-1; (i+1)>0 ;i-- ){
			if ( fname[i] != 0x5c ){
				flong -= 1;
			}
			else {
				findflag=1;
				break;
			}
		}
		if(findflag==0){
			flong=1;
			for ( i = 0; i <255 ;i ++ ){
				if ( fname[i] != 0x3a ){
					flong += 1;
				}
				else {
					findflag=2;
					break;
				}
			}
		}
		if(findflag!=0){
			for(i=flong;i<namelen;i++){
				fname[i-flong]=fname[i];
			}
			fname[i-flong]=0;
		}
		
		if(sccsave()!=0){
			exit(-1);
		}
	}
	exit(0);
}
