/*
	TIFF image file support routines

		1989/04/26  Version 0.0 by Waku
*/

#include <stdio.h>
#include <stdlib.h>
#include <EGB.h>

#define TIFF 
#include "tiff.h"

short tiff_IFDsize = 15 ;
long tiff_width = 640 ;
long tiff_length = 480 ;
long tiff_bpp = 4 ;
long tiff_fill = 2 ;
long tiff_maxv = 0xF ;
long tiff_iofs = 0 ;
long tiff_xrofs = 0 ;
long tiff_yrofs = 0 ;
int tiff_err = 0 ;

struct {
	long x_c ;
	long x_m ;
	long y_c ;
	long y_m ;
} tiff_resolution  = { 75,1,75,1 } ;

IFD_E *ifd ;

IFD_E *allocIFD( count ) 
int count ;
{
	return( (IFD_E *)malloc( sizeof(IFD_E)*count ) ) ;
}

_freeIFD( ptr )
IFD_E *ptr ;
{
	free( ptr ) ;
}

freeIFD()
{
	free( ifd ) ;
}

storeIFD( p,tag,type,size,value)
IFD_E *p ;
short tag,type ;
long size,value ;
{
	p->tag = tag ;
	p->type = type ;
	p->count = size ;
	p->value = value ;
}

/* make defalut format of IFD */
mkIFD()
{
	int c = 0 ;

	IFD_E *ifdp ;
	if( (ifd = allocIFD(15)) == 0 ) 
		{ tiff_err = TIF_ERR_MEM ;return -1 ; }
	ifdp = ifd ;
	tiff_xrofs = 8 + 2 + tiff_IFDsize * sizeof(IFD_E) + 4 ;
	tiff_yrofs = tiff_xrofs + 8 ;
	tiff_iofs = 0x100 ;
	storeIFD(ifdp++,GeneralDescription,ShortType,1,1) ;
	storeIFD(ifdp++,ImageWidth,ShortType,1,tiff_width) ;
	storeIFD(ifdp++,ImageLength,ShortType,1,tiff_length) ;
	storeIFD(ifdp++,BitsPerSample,ShortType,1,tiff_bpp) ;
	storeIFD(ifdp++,Compression,ShortType,1,1) ;
	storeIFD(ifdp++,PhotometricInterpretation,ShortType,1,1) ;
	storeIFD(ifdp++,FillOrder,ShortType,1,tiff_fill) ;
	storeIFD(ifdp++,StripOffset,LongType,1,tiff_iofs) ;
	storeIFD(ifdp++,Orientation,ShortType,1,1) ;
	storeIFD(ifdp++,SamplesPerPixel,ShortType,1,1) ;
	storeIFD(ifdp++,MinSampleValue,ShortType,1,0 ) ;
	storeIFD(ifdp++,MaxSampleValue,ShortType,1,tiff_maxv ) ;
	storeIFD(ifdp++,XResolution,RationalType,1,tiff_xrofs) ;
	storeIFD(ifdp++,YResolution,RationalType,1,tiff_yrofs) ;
	storeIFD(ifdp  ,PlanarConfigration,ShortType,1,1) ;
	return(0) ;
}

putIFD( fp ) 
FILE *fp ;
{
	long idv,ifdofs,term ;
	idv = ID_VERSION ;
	ifdofs = sizeof(idv) + sizeof(ifdofs) ;

	term = 0 ;

	if( fwrite(&idv,sizeof(idv),1,fp ) == 0 ) return -1 ;
	if( fwrite(&ifdofs,sizeof(ifdofs),1,fp) == 0 ) return -1 ;
	if( fwrite(&tiff_IFDsize,sizeof(tiff_IFDsize),1,fp) == 0 ) return -1;
	if( fwrite(ifd,sizeof(IFD_E),tiff_IFDsize,fp) == 0 ) return -1 ;
	if( fwrite(&term,sizeof(term),1,fp) == 0 ) return -1 ;
	if( fwrite(&tiff_resolution,sizeof(tiff_resolution),1,fp) == 0) return -1 ;
	fseek(fp, tiff_iofs, SEEK_SET ) ;
	return 0 ;
}

setTIFFmode( mode )
int mode ;
{
	switch( mode ) {
	case TIFF_16:
		tiff_width = 640 ;
		tiff_length = 480 ;
		tiff_bpp = 4 ;
		tiff_fill = 2 ;
		tiff_maxv = 0xF ;
		break ;
	case TIFF_32K:
		tiff_width = 320 ;
		tiff_length = 240 ;
		tiff_bpp = 16 ;
		tiff_fill = 1 ;
		tiff_maxv = 0x7FFF ;
		break ;
	case TIFF_256:
		tiff_width = 640 ;
		tiff_length = 480 ;
		tiff_bpp = 8 ;
		tiff_fill = 1 ;
		tiff_maxv = 0xFF ;
		break ;
	}
}


/* tiff head load */

getIFD( fp )
FILE *fp ;
{
	IFD_E *ifdp ;
	long idv,ifdofs ;
	int i ;
	
	if( fread( &idv, 4, 1, fp ) == 0 ) 
		{ tiff_err = TIF_ERR_FR ; return -1 ;}
	if( idv != ID_VERSION ) { tiff_err = TIF_ERR_ID ; return -1 ;}
#ifdef DEBUG
printf( "get header\n" ) ;
#endif
	if( fread( &ifdofs, 4, 1, fp) == 0 )
		{ tiff_err = TIF_ERR_FR ; return -1 ;}
	fseek(fp, ifdofs, SEEK_SET ) ;
#ifdef DEBUG
printf( "seek to IFD header \n" ) ;
#endif
	if( fread( &tiff_IFDsize, 2, 1, fp) == 0  )
		{ tiff_err = TIF_ERR_FR ; return -1 ;}
#ifdef DEBUG
printf( "number of tags = %d \n",tiff_IFDsize ) ;
#endif
	if(( ifd = allocIFD( tiff_IFDsize ) ) == 0 )
		{ tiff_err = TIF_ERR_MEM ; return -1 ;}
	ifdp = ifd ;
	for( i = 0 ; i < tiff_IFDsize ; i++ ) {
		if( fread( ifdp++, sizeof(IFD_E),1, fp ) == 0 )
			{ tiff_err = TIF_ERR_FR ; return -1; } 
#ifdef DEBUG
printf( "get tag #%d\n",(ifdp-1)->tag ) ;
#endif 
	}
	ifdp = ifd ;
	for( i = 0 ; i < tiff_IFDsize ; i++ ) {
		switch( ifdp->tag ) {
		case ImageWidth:
			tiff_width = ifdp->value ;
			break ;
		case ImageLength:
			tiff_length = ifdp->value ;
			break ;
		case BitsPerSample:
			tiff_bpp = ifdp->value ;
			break ;
		case StripOffset:
			tiff_iofs = ifdp->value ;
			break ;
		default: ;
		}
		ifdp++ ;
	}
	return 0 ;		
}

svram(fp,work,sx,sy,wx,wy,mode,n)

FILE *fp;
char *work;
int sx,sy,wx,wy;
int mode,n;
{
	char *bp;
	int size;
	char para[16];
	
	size=(wx*wy*mode+7)/8;
	if (wx & 1) wx++;
	if ((bp=(char *)malloc(size))==0) return(-1);
	
	DWORD(para+0 )=(unsigned int)bp;
	WORD (para+4 )=0x14;
	WORD (para+6 )=sx;
	WORD (para+8 )=sy;
	WORD (para+10)=sx+wx-1;
	WORD (para+12)=sy+wy-1;
	EGB_getBlock(work,para);

	fwrite(bp,1,size,fp);
	free(bp);
}
