#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#include <strings.h>
#include <conio.h>
#include <msdos.cf>
#include "tifflib.h"

#define LOADBUFSIZE	 150	/* ファイル読み込みバッファ */
#define EXPBUFSIZE   10	/* 展開用バッファ */
/* ここでは，ライブラリが扱うバッファの大きさを指定している｡(KByte単位)
 * 当然どちらのバッファも大きいほうが，高速にデータを表示できる。
 * ここでは，ファイルバッファを大きめ(16色フル画面TIFFの大きさ分)
 * にとり，展開バッファは少なめに定義してある。
 * この値を変えることにより，展開のされかたが違うことがわかる。
 */

void setegb(), err() ;

extern char gwork[1540];	/* グラフィックワ−ク */
extern char palt[] ;		/* パレット設定用 */

int  mode ;		/* 画面モ−ド */
int x,y ;
int px, py;		/* 移動位置	*/
FILE *fp;

void TIFF_loadScreen( char *filename, int *ret_mode, int ix, int iy)
{
	char *lbp, *dbp, *cbuf ;
	int lbsize, dbsize,bpp, d_line ;
	int comp,fill ;
	long strip, clut, dw ;

	lbsize = LOADBUFSIZE * 1024 ; 	/* それぞれのバッファのサイズ */
	dbsize = EXPBUFSIZE * 1024;
	/* ロードバッファの取得 */
	lbp = malloc( lbsize ) ;
	/* 展開バッファの取得 */
	dbp = malloc( dbsize ) ;
	/* 圧縮展開用ワークの取得 */
	cbuf = malloc( DECOMP_WORK_SIZE ) ;	

	if( (fp = fopen( filename, "rb" )) == NULL ){
		printf("Fail to inputopen tiff %s\n", filename);
		exit( -1 ) ;
	}

	fread( lbp, 1, lbsize, fp ) ;	/* 最初のデータロード */

	/* ヘッダの解析 */
	if( TIFF_getHead( lbp, lbsize ) < 0 )
		err() ;
	/* タグの内容のチェック */
	if( ( bpp = TIFF_checkMode( &x,&y,&comp,&fill,&strip,&clut )) < 0 ) 
		err() ;

	dw = x ;

	switch( bpp ){
	case 24:
		err() ;		/* このプログラムではフルカラーデータは扱わない */
		break ;
	case 16:
		px = ix/2;
		py = iy/2;
		break;
	case 4:
		if( dw & 7 )
			dw += 8 - (dw & 7) ;
	default:
		px = ix;
		py = iy;
	}
	/* 画面モードの設定 */
	setegb( bpp,x,y ) ;
	mode = bpp ;
	*ret_mode = bpp ;

	/* 展開用バッファに何行分のデータが入るかの計算  */
	d_line = dbsize / ((dw * bpp + 7)/ 8) ;

	/* パレットの設定 */
	if( TIFF_getPal( palt ) != 0 )  {
		EGB_palette( gwork, 0, palt ) ;
	}

	/* TIFFデータのロード&表示  */
	TIFF_loadImage( bpp, x,y, strip,  fill, comp, dbp, dw, d_line, cbuf ) ;

	free( lbp ) ;
	free( dbp ) ;
	free( cbuf ) ;
	fclose( fp ) ;
}

/*	TIFFライブラリの中から呼ばれる関数	*/
/* バッファにデータをロードする 					*/
/*    ファイルからロードする場合は freadだけでよい	*/
read_data( char *bp, int size )
{

	fread( bp, 1, size, fp ) ; 
	if( ferror(fp) != 0 ) {
		return -1 ;
	}
	return 0 ;
}

/* バッファにデータをロードする。オフセット指定付き */
read_file( char *bp, int size, int ofs )
{
	int ret ;

	fseek( fp, ofs ,SEEK_SET ) ;
	ret = fread( bp, 1, size, fp ) ;
	if( ferror(fp) != 0 ) {
		ret =  -1 ;
	}
	return ret ;
}

/* 展開されたものを表示する								*/
/*    そのまま表示する場合は, EGB_putBlockを使えばよい　*/
put_data( char *buf, int lofs, int lines ) 
{
	struct {
		char *bp ;
		short sel ;
		short sx,sy,ex,ey ;
	} p ;		/* EGB_putBlockのパラメータ */

	p.bp = buf ;
	p.sel = getds() ;
	p.sx = px ;
	p.ex = px + x -1 ;
	p.sy = py + lofs ;
	p.ey = py + lofs + lines -1 ;
	if( mode == 1 ) {
		EGB_putBlockColor( gwork, 0, (char *)&p ) ;	/* 2値TIFFの場合 */
	} else {
		EGB_putBlock( gwork , 0, (char *)&p ) ;
	}
	return 0 ;
}


/* 
	下請け関数群
*/
/* 画面モードの設定 */
void setegb( int bpp, int x, int y ) 
{
	EGB_init( gwork,1536) ;
	EGB_displayPage( gwork, 0, 3 ) ;
	switch( bpp ) {
	case 1:		/* 2値 */
	case 4:		/* 16色 */
		EGB_resolution( gwork, 0, 3 ) ;
		EGB_color( gwork, 0, 0 ) ;
		EGB_color( gwork, 1, 15 ) ;
		break ;
	case 8:		/* 256色 */
		EGB_resolution( gwork, 0, 12 ) ;
		break ;
	case 16:	/* 32K色 */
		if( x > 320 ) {	/* 高解像度モードにする */
			EGB_resolution( gwork, 0, 17 ) ;
			EGB_displayStart( gwork, 3, 512, 480 ) ;
		} else {
			EGB_resolution( gwork, 0, 10 ) ;
			EGB_displayStart( gwork, 2, 2,2 ) ;
			EGB_displayStart( gwork, 3, 320,240 ) ;
		}
		break ;
	default: ;
	}
	if( bpp == 1 ) 			/* 2値TIFFの場合は画面を白で塗り潰す */
		EGB_clearScreen( gwork ) ;
}

void err()
{
	printf( "ERROR : %d\n", tiff_err ) ;
	exit( -1 ) ;
}
