#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <file_dlg.h>
#include <tifflib.h>
#include <egb.h>
#include <mos.h>
#include <snd.h>
#include "tetujin.h"

static FILE *fptif ;
static int xtif, ytif ;
static int colorMode ;
static char *imageBuf ;
static int counter ;

/* tiff check head (stack:4096Byte以上) */

tiffCheckHead( char *name, int *c, int *x, int *y,
			   int *comp, int *fill, long *strip, long *clut )
{
	FILE *fp ;
	char work[4096] ;

	if( ( fp = fopen( name, "rb" ) ) == NULL )return READ_FAIL ;
		/* ファイルオープン */
	fread( work, 1, 4096, fp );	/* 最初のデータロード */
		/* ヘッダの解析 */
	if( TIFF_getHead( work, 4096 ) < 0 ){
		fclose( fp );
		return ILLEGAL_DATA ;
	}
	fclose( fp );
		/* タグの内容のチェック */
	*c = TIFF_checkMode( x, y, comp, fill, strip, clut );
	return NOERR ;
}

/*
	1600万色用 TIFF loader

	32k, 1600万色のtifdataを1600万色データに変換しながら読み込む｡
	workは DECOMP_WORK_SIZE + LOADBUFSIZE + EXPBUFSIZEバイト必要｡
	ファイル名nameのtifをバッファbufferに読み出す｡
	dx, dyに絵の大きさを返す｡
*/

/* ライブラリから呼ばれる，バッファに対する操作の関数 */
static tifLoadGet( bp, size )
char *bp ;
int size ;
{
	if( fread( bp, size, 1, fptif ) < 1 ) 
		return -1 ;
	return NOERR ;
}

static tifLoadPut( buf, lofs, lines ) 
char *buf ;
int lofs, lines ;
{
	int i ;

	if( lofs*xtif + lines*xtif > xtif*ytif )
		return -1 ;

	if( colorMode == 24 )
	{
		for( i=0 ; i<lines*xtif*3 ; i++ )
		{
			BYTE( imageBuf + lofs*xtif*3 + i )
			= BYTE( buf + i ) ;
		}
	}
	else if( colorMode == 16 )
	{
		for( i=0 ; i<lines*xtif ; i++ )
		{
			int temp, r, g, b ;

			temp = WORD( buf + i*2 ) ;
			b = temp & 0x1f ;
			r = ( temp >> 5 ) & 0x1f ;
			g = ( temp >> 10 ) & 0x1f ;
			b <<= 3 ; r <<= 3 ; g <<= 3 ;
			BYTE( imageBuf + lofs*xtif*3 + i*3 ) = r ;
			BYTE( imageBuf + lofs*xtif*3 + i*3 + 1 ) = g ;
			BYTE( imageBuf + lofs*xtif*3 + i*3 + 2 ) = b ;
		}
	}

	return NOERR ;
}

tifLoad16m( char *work, char *name, char *buffer, int *dx, int *dy )
{
	char *lbp, *dbp, *cbuf ;
	int lbsize, dbsize,bpp, d_line ;
	int comp, fill ;
	long strip, clut, dw ;

	imageBuf = buffer ;

	lbsize = LOADBUFSIZE ; 	/* それぞれのバッファのサイズ */
	dbsize = EXPBUFSIZE ;
	lbp = work;			/* ロードバッファ */
	dbp = lbp + lbsize;		/* 展開バッファ */
	cbuf = dbp + dbsize;		/* 圧縮展開用ワーク */
		/* DECOMP_WORK_SIZEがtifflib.hに定義されてるが
		lbsize+dbsize+DECOMP_WORK_SIZEがworkの大きさを
		こえないように注意すること */
	if( ( fptif = fopen( name, "rb" ) ) == NULL )return READ_FAIL ;
		/* ファイルオープン */
	fread( lbp, 1, lbsize, fptif );	/* 最初のデータロード */
		/* lbsize程のデータが無くてもok! */
	/* ヘッダの解析 */
	if( TIFF_getHead( lbp, lbsize ) < 0 ){
		fclose( fptif );
		return ILLEGAL_DATA ;
	}
	/* タグの内容のチェック */
	bpp = TIFF_checkMode( &xtif,&ytif,&comp,&fill,&strip,&clut );
	if( (bpp != 16) && (bpp != 24) ){
		fclose( fptif );
		return ILLEGAL_DATA ;
	}
	colorMode = bpp ;
	*dx = xtif ;
	*dy = ytif ;

	/* バッファ操作関数の登録 */
	TIFF_setLoadFunc(  tifLoadPut, tifLoadGet ) ;
	dw = xtif ;
	/* 16色モードの場合,横方向を8ドット単位で扱うため，一行のデータ
	   サイズを計算する際に，8ドット単位に調整しておく必要がある */
//	if( bpp == 4)
//		if( dw & 7 )
//			dw += 8 - (dw & 7) ;
	/* 展開用バッファに何行分のデータが入るかの計算  */
	d_line = dbsize / ((dw * bpp + 7)/ 8) ;
	/* TIFFデータ読み込み  */
	TIFF_loadImage( bpp,xtif,ytif,strip, fill, comp, dbp, dw, d_line, cbuf );
	fclose( fptif );
	return NOERR ;
}

/* 1600万色から32k色に変換する関数 */

cov16mTo32k( char *sour, char *dest, int n )
{
	int i, r, g, b ;

	for( i=0 ; i<n ; i++ )
	{
		r = BYTE( sour + i*3 ) ;
		g = BYTE( sour + i*3 + 1 ) ;
		b = BYTE( sour + i*3 + 2 ) ;
		r >>= 3 ; g >>= 3 ; b >>= 3 ;
		WORD( dest + i*2 ) = b + (r << 5) + (g << 10) ;
	}
	return NOERR ;
}

/*
	1600万色用 TIFF saver

	1600万色のtifdataをbufferからsave｡
	workは COMP_WORK_SIZE + SAVEBUFSIZE + GETBUFSIZEバイト必要｡
	ファイル名はname｡
	x, yは絵の大きさ｡
*/

/* ライブラリから呼ばれる，バッファに対する操作の関数 */
static tifSavePut( bp, size )
char *bp ;
int size ;
{
	if( fwrite( bp, size, 1, fptif ) < 1 ) 
		return -1 ;
	counter += size ;
	return NOERR ;
}

static tifSaveGet( buf, lofs, lines ) 
char *buf ;
int lofs, lines ;
{
	int i ;

	if( lofs*xtif + lines*xtif > xtif*ytif )
		return -1 ;

	if( colorMode == 24 )
	{
		for( i=0 ; i<lines*xtif*3 ; i++ )
		{
			BYTE( buf + i )
			= BYTE( imageBuf + lofs*xtif*3 + i ) ;
		}
	}
	else if( colorMode == 16 )
	{
		for( i=0 ; i<lines*xtif*2 ; i++ )
		{
			BYTE( buf + i )
			= BYTE( imageBuf + lofs*xtif*2 + i ) ;
		}
	}

	return NOERR ;
}

tifSave32kAnd16m
(
  char *work, char *name, char *buffer, int bpp, int comp, int x, int y 
)
{
	char *sbp, *ibp, *cbuf ;
	int sbsize, ibsize, i_line, compsize, dw ;

	if( (bpp != 16) && (bpp != 24) )
		return ILLEGAL_DATA ;
	colorMode = bpp ;

	imageBuf = buffer ;
	if( comp )comp = 5 ;
	else comp = 1 ;
	xtif = x ;
	ytif = y ;
	counter = 0 ;

	sbsize = SAVEBUFSIZE ; 	/* それぞれのバッファのサイズ */
	ibsize = GETBUFSIZE ;
	sbp = work;			/* ロードバッファ */
	ibp = sbp + sbsize;		/* 展開バッファ */
	cbuf = ibp + ibsize;		/* 圧縮展開用ワーク */
		/* COMP_WORK_SIZEがtifflib.hに定義されてるが
		sbsize+ibsize+DECOMP_WORK_SIZEがworkの大きさを
		こえないように注意すること */

		/* ファイルオープン */
	if( ( fptif = fopen( name, "wb" ) ) == NULL )
		return WRITE_FAIL ;
	fseek( fptif, 512, SEEK_SET );	/* header分開ける */

	/* バッファ操作関数の登録 */
	TIFF_setSaveFunc(  tifSavePut, tifSaveGet ) ;
	dw = xtif ;
	/* 展開用バッファに何行分のデータが入るかの計算  */
	i_line = ibsize / ((dw * bpp + 7)/ 8) ;
	/* TIFFデータsave  */
	if
	(
	  TIFF_saveImage( bpp,xtif,ytif,comp, sbp, sbsize, ibp, dw, i_line, cbuf )
	  <= 0
	)
	{
		fclose( fptif ) ;
		remove( name ) ;		/* del */
		return WRITE_FAIL ;
	}

	/* TIFF head  */
	if( comp == 1 )compsize = 0 ;
	else compsize = counter ;
	TIFF_setHead( ibp, bpp, xtif, ytif, compsize, ibp ) ;
	fseek( fptif, 0, SEEK_SET );
	if( fwrite( ibp, 512, 1, fptif ) < 1 )
	{
		fclose( fptif ) ;
		remove( name ) ;		/* del */
		return WRITE_FAIL ;
	}

	fclose( fptif );
	return NOERR ;
}

