/*
*		TOWNS 標準TIFFライブラリサンプル
*
*	VRAMの内容をTIFFにセーブする関数
*
*	TIFF_saveScreen( fp,  mode, sx, sy, ex, ey, comp, egbwork )	
*
*	パラメータ
*			FILE *fp : セーブファイルパス
*			int mode : 画面色数 4 (16色), 8 (256色), 16(32K色)のいずれか
*			int sx,sy: 保存左上座標
*			int ex,ey: 保存右上座標
*			int comp : 圧縮フラグ 0 (圧縮しない), 1 (LZW圧縮する)
*			char *egbwork : T-BIOSのEGBワーク
*	戻り値
*			0 : 正常終了
*			<0: 異常終了(作業用メモリが確保できない)
*
*	機能
*		EGBのライトページに設定されている画面から画像を切り出してTIFFと
*		としてセーブする｡ パラメータで渡す画面色数と，実際の画面モードの
*		色数は一致している必要がある。
*/
#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#include <tifflib.h>
#include <msdos.cf>


#define MALLOC	malloc			/* メモリ取得関数 */
#define FREE	free			/* メモリ開放関数 */
	
#define WBUFSIZE (1024*150)		/* ファイル書き込み用バッファサイズ */
#define LINES 1 				/* 処理単位ライン数 */

static char *egbw ;
static	struct {
		char *ptr ;
		short ds ;
		short sx,sy,ex,ey ;
} p ;
static int tiff_sy ;
static FILE *sfp ;

int save_get_func(), save_put_func() ;

TIFF_saveScreen( FILE *fp, int mode, int sx, int sy, int ex, int ey,
					int comp, char *egbwork )	
{
	int x,y, cmp,ret ;
	int dbs, sw, sl, size, hsize ;
	char  *pal, *cb, *sb, *db, *head ;

	egbw = egbwork ;
	tiff_sy = sy ;
	x = ex - sx + 1 ;
	y = ey - sy + 1 ;
	p.ds = getds() ;
	p.sx = sx ;
	p.ex = ex ;
	sfp = fp ;
	cmp = (comp) ? 5 : 1 ;
	ret = -1 ;
	pal = db = sb = cb = NULL ;

	if( mode == 4 || mode == 8 ) {
		/* パレット 取り出す */
		if( ( pal = MALLOC( (1 << mode) * 8 + 4 )) == NULL )
			goto end ;
		EGB_getPalette( EGB_getWritePage( egbw, getds() ) , (char *)pal ) ;
	}

	TIFF_setSaveFunc( save_put_func, save_get_func ) ;

	/* 圧縮展開用バッファの確保 */
	if( comp ) {
		if( (cb = MALLOC( COMP_WORK_SIZE )) == 0 ) {
			return -1 ;	/* 圧縮メモリ不足 */
		}
	}

	/* ファイル書き込みバッファの確保 */
	dbs = WBUFSIZE ;
	if( (db = MALLOC( dbs )) == 0 )
		 goto end ;
	/* 16色時のバウンダリ調整 */
	sw = ( mode == 4 ) ? (x + 7)/8 * 8 : x ;
	/* 取り込み用バッファの確保 */
	sl = LINES ;
	if( (sb = MALLOC( sw * mode / 8 )) == 0 )
		goto end ;
	/* ヘッダ作成用バッファの確保 */
	hsize = ( mode == 8 ) ? 2048 : 512 ;
	if( ( head = MALLOC( hsize )) == NULL ) 
		goto end ;
	fseek( fp, hsize, SEEK_SET ) ;

	/* TIFF保存 */
	size = TIFF_saveImage( mode, x, y, cmp, db, dbs, sb, sw, sl, cb) ;
	if( size > 0 ) {
		/* ヘッダをファイルに書く */
		TIFF_setHead( head, mode, x, y, (comp)?size:0, pal ) ;
		fseek( sfp, 0, SEEK_SET ) ;
		fwrite( head, 1, hsize, sfp ) ;
		ret = 0 ;
	}

end:
	if( pal ) FREE( pal ) ;
	if( db ) FREE( db ) ;
	if( sb ) FREE( sb ) ;
	if( cb ) FREE( cb ) ;
	if( head ) FREE( head ) ;

	return  ret  ;
}

/* TIFFライブラリから呼ばれる関数 */
/* VRAMから取り出す */
save_get_func( char *buf, int ofs, int lines )
{
	p.ptr = buf ;
	p.sy = tiff_sy + ofs ;
	p.ey = p.sy + lines - 1;
	EGB_getBlock( egbw, (char *)&p ) ;
	return 0 ;
}

/* ファイルに書きだす */
save_put_func( buf, size ) 
char *buf ;
int size ;
{
	fwrite( buf, 1, size, sfp ) ;
	return 0 ;
}
