/**
 **	$Header: /import/dev-vis/image/imtools/v2.0/libim/src/include/RCS/iminternal.h,v 1.9 92/12/03 02:19:42 nadeau Exp $
 **	Copyright (c) 1989-1992  San Diego Supercomputer Center (SDSC)
 **		San Diego, California, USA
 **
 **	Users and possessors of this source code are hereby granted a
 **	nonexclusive, royalty-free copyright and design patent license to
 **	use this code in individual software.  License is not granted for
 **	commercial resale, in whole or in part, without prior written
 **	permission from SDSC.  This source is provided "AS IS" without express
 **	or implied warranty of any kind.
 **
 **	For further information contact:
 **		E-Mail:		info@sds.sdsc.edu
 **
 **		Surface Mail:	Information Center
 **				San Diego Supercomputer Center
 **				P.O. Box 85608
 **				San Diego, CA  92138-5608
 **				(619) 534-5000
 **/

/**
 **  FILE
 **	iminternal.h		-  Internal header definitions for libim
 **
 **  PROJECT
 **	libim	-  SDSC image manipulation library
 **
 **  DESCRIPTION
 **	iminternal.h contains macros common to most file read and
 **	write functions.  It should not be used outside of the scope
 **	of libim read and write routines.
 **
 **  PUBLIC CONTENTS
 **			d =defined constant
 **			f =function
 **			m =defined macro
 **			t =typedef/struct/union
 **			v =variable
 **			? =other
 **
 **
 **	__IMINTERNALH__		d  file inclusion flag
 **	
 **	ImReturnBinError	m  return right error based on Bin call
 **	ImMalloc		m  malloc memory & return on error
 **	ImBinReadStruct		m  binary struct read from fd or fp
 **	ImBinRead		m  binary read from fd or fp
 **	ImBinWrite		m  binary write from fd or fp
 **	ImSeek			m  file seek from fd or fp
 **
 **	ImErrorFatal		m  issue a fatal error
 **	ImErrorWarning		m  issue a warning error
 **	ImErrorInfo		m  issue an info error
 **	ImInfo			m  issue general information message
 **
 **	NULL			d  an empty pointer
 **     xxxxx			d  abbreviations for items in Read/Write maps
 **
 **	ImHist			?  stuff for imvfbhist.c
 **
 **  PRIVATE CONTENTS
 **	none
 **
 **  HISTORY
 **	$Log:	iminternal.h,v $
 **	Revision 1.9  92/12/03  02:19:42  nadeau
 **	Updated histogram information.
 **	
 **	Revision 1.8  92/11/06  17:02:24  groening
 **	added #defines for format reading
 **	
 **	Revision 1.7  92/10/12  16:12:52  vle
 **	Added ImInfo declarations.
 **	
 **	Revision 1.6  92/09/23  15:27:50  groening
 **	Added histogram declarations.
 **	
 **	Revision 1.5  91/10/03  12:57:05  nadeau
 **	Added error code to ImErrorHandler() call.
 **	
 **	Revision 1.4  90/07/23  13:52:38  nadeau
 **	Added curly braces to ImMalloc macro.  Added ImTell macro.
 **	
 **	Revision 1.3  90/07/02  13:24:00  nadeau
 **	Added new error handling macros and globals and updated existing macros
 **	to use them.
 **	
 **	Revision 1.2  90/06/26  09:10:39  todd
 **	Useful macros for writing image file read and write routines.
 **	These should be taken out of imras.c someday.
 ** 
 **	Revision 1.1  90/05/15  14:00:06  todd
 **	Initial revision
 ** 
 **
 **/

#ifndef __IMINTERNALH__
#define __IMINTERNALH__

#include <errno.h>
extern int sys_nerr;
extern char *sys_errlist[];

#include <stdio.h>

#ifndef __SDSCH__
#include "sdsc.h"
#endif /* __SDSCH__ */

#ifndef __IMH__
#include "im.h"
#endif /* __IMH__ */

#ifndef NULL
#define NULL	(0)
#endif /* NULL */





/*
 *  CONSTANTS
 *	XXX	-  abbreviations for Read/Write map fields
 *
 *  DESCRIPTION
 *	These constants are simply shorthands for flags used in initialization
 *	of the file format read/write maps.  They are only provided so that
 *	such initializations don't look too cluttered.
 */
#define C       IMCLTYES                /* CLT included                 */
#define A       IMALPHAYES              /* Alpha plane included         */

#define RLE     IMCOMPRLE               /* RLE compression              */
#define LZW     IMCOMPLZW               /* LZW compression              */
#define PB      IMCOMPPACKBITS          /* Packbits compression         */
#define DCT     IMCOMPDCT               /* DCT compression              */

#define LI      IMINTERLINE             /* Line interleaved             */
#define PI      IMINTERPLANE            /* Plane interleaved            */

#define IN      IMTYPEINDEX             /* Index type of image          */
#define RGB     IMTYPERGB               /* RGB type of image            */





/*
 *  CONSTANTS
 *	IMFILEIO...	-  Image file I/O type
 *
 *  DESCRIPTIONS
 *	These constants are bitwise OR-ed together to create the ioType
 *	argument to the internal per-format read and write routines.
 *	They should never be used by the applications programmer.
 */

#define IMFILEIOFD	0x1		/* Use file descriptor		*/
#define IMFILEIOFP	0x2		/* Use file pointer		*/

#define IMFILEIOFILE	0x10		/* I/O on file			*/
#define IMFILEIOPIPE	0x20		/* I/O on pipe			*/





/*
 *  MACROS
 *	ImReturnBinError	-  return right error based on Bin call
 *	ImMalloc		-  malloc memory & return on error
 *	ImBinReadStruct		-  binary struct read from fd or fp
 *	ImBinRead		-  binary read from fd or fp
 *	ImBinWrite		-  binary write from fd or fp
 *	ImSeek			-  file seek from fd or fp
 *
 *  DESCRIPTION
 *	These actions occur so often in the imfile read/write code that they 
 *	have been turned into macros in order to reduce clutter and make the
 *	algorithms more apparent.
 */

#define ImReturnBinError()						\
{									\
	if ( BinErrNo == BINEMALLOC )					\
	{								\
		ImErrorFatal( BinQError( ), -1, IMEMALLOC );		\
	}								\
	else								\
	{								\
		ImErrorFatal( BinQError( ), -1, IMESYS );		\
	}								\
}

#define ImMalloc(variable,type,nbytes)					\
{									\
	if ( ((variable) = (type)malloc( (nbytes) )) == NULL )		\
	{								\
		ImErrNo = IMEMALLOC;					\
		ImErrorFatal( ImQError( ), -1, IMEMALLOC );		\
	}								\
}

#define ImCalloc(variable,type,nbytes,size)				\
{									\
	if ( ((variable) = (type)calloc( (nbytes),(size) )) == NULL )	\
	{								\
		ImErrNo = IMEMALLOC;					\
		ImErrorFatal( ImQError( ), -1, IMEMALLOC );		\
	}								\
}

#define ImBinReadStruct(ioType,fd,fp,buf,fields)			\
	(((ioType)&IMFILEIOFD) ?					\
		BinReadStruct( (fd), (buf), (fields) )			\
	:								\
		BinFReadStruct( (fp), (buf), (fields) )			\
	)

#define ImBinRead(ioType,fd,fp,buf,type,nbytes,len)			\
	(((ioType)&IMFILEIOFD) ?					\
		BinRead( (fd), (buf), (type), (nbytes), (len) )		\
	:								\
		BinFRead( (fp), (buf), (type), (nbytes), (len) )	\
	)

#define ImBinWriteStruct(ioType,fd,fp,buf,fields)			\
	(((ioType)&IMFILEIOFD) ?					\
		BinWriteStruct( (fd), (buf), (fields) )			\
	:								\
		BinFWriteStruct( (fp), (buf), (fields) )		\
	)

#define ImBinWrite(ioType,fd,fp,buf,type,nbytes,len)			\
	(((ioType)&IMFILEIOFD) ?					\
		BinWrite( (fd), (buf), (type), (nbytes), (len) )	\
	:								\
		BinFWrite( (fp), (buf), (type), (nbytes), (len) )	\
	)

#define ImSeek(ioType,fd,fp,offset,type)				\
	(((ioType)&IMFILEIOFD) ?					\
		lseek( (fd), (offset), (type) )				\
	:								\
		fseek( (fp), (offset), (type) )				\
	)
#define ImTell(ioType,fd,fp)						\
	(((ioType)&IMFILEIOFD) ?					\
		lseek( (fd), 0, 1 )					\
	:								\
		ftell( (fp) )						\
	)





/*
 *  MACROS and CONSTANTS
 *	ImErrorFatal		-  issue a fatal error
 *	ImErrorWarning		-  issue a warning error
 *	ImErrorInfo		-  issue an info error
 *	ImInfo			-  issue an information message
 *	IMINFOMSGWIDTH...	-  Image Info Message Widths
 *	IMINFOMSGLENGTH		-  Image Info Message Length
 *
 *  DESCRIPTION
 *	These macros cover up some of the busy-work of issueing error
 *	and info messages and codes while processing file formats.
 */

extern char *ImErrorProgramName;		/* Program name		    */
extern char *ImErrorFileName;			/* File name		    */
extern int (*ImErrorHandler)( );		/* Error handler	    */
extern FILE *ImErrorStream;			/* Error stream		    */
extern int (*ImInfoHandler)( );			/* Info handler	    	    */
extern FILE *ImInfoStream;			/* Info stream		    */

#define ImErrorFatal(msg,ret,er)					\
{									\
	if ( ImErrorHandler )						\
	{								\
		char errorMessage[500];					\
		sprintf( errorMessage, "%s: %s: %s\n", ImErrorProgramName,\
			ImErrorFileName, (msg) );			\
		(*ImErrorHandler)( IMERRORFATAL, er, errorMessage );	\
		ImErrNo = (er);						\
		return ( ret );						\
	}								\
	else if ( ImErrorStream )					\
	{								\
		fprintf( ImErrorStream, "%s: %s: %s\n", ImErrorProgramName,\
			ImErrorFileName, (msg) );			\
		ImErrNo = (er);						\
		return ( ret );						\
	}								\
	else								\
	{								\
		ImErrNo = (er);						\
		return ( ret );						\
	}								\
}

#define ImErrorWarning(msg,ret,er)					\
{									\
	if ( ImErrorHandler )						\
	{								\
		char errorMessage[500];					\
		sprintf( errorMessage, "%s: %s: %s\n", ImErrorProgramName,\
			ImErrorFileName, (msg) );			\
		if ( (*ImErrorHandler)( IMERRORWARNING, er, errorMessage ) == -1 )\
		{							\
			ImErrNo = (er);					\
			return ( ret );					\
		}							\
	}								\
	else if ( ImErrorStream )					\
		fprintf( ImErrorStream, "%s: %s: %s\n", ImErrorProgramName,\
			ImErrorFileName, (msg) );			\
	else								\
	{								\
		ImErrNo = (er);						\
		return ( ret );						\
	}								\
}

#define ImErrorInfo(msg,ret,er)						\
{									\
	if ( ImErrorHandler )						\
	{								\
		char errorMessage[500];					\
		sprintf( errorMessage, "%s: %s: %s\n", ImErrorProgramName,\
			ImErrorFileName, (msg) );			\
		if ( (*ImErrorHandler)( IMERRORINFO, er, errorMessage ) == -1 )\
		{							\
			ImErrNo = (er);					\
			return ( ret );					\
		}							\
	}								\
	else if ( ImErrorStream )					\
		fprintf( ImErrorStream, "%s: %s: %s\n", ImErrorProgramName,\
			ImErrorFileName, (msg) );			\
}

#define IMINFOMSGWIDTH1 20

#define ImInfo(label,msg)						\
{									\
	char infoMessage[500];						\
	char infoLabel[IMINFOMSGWIDTH1+2];				\
	sprintf( infoLabel, "%s:", label );				\
	sprintf( infoMessage, "%-*s %s\n", IMINFOMSGWIDTH1, infoLabel, msg );\
	if ( ImInfoHandler )						\
		(*ImInfoHandler)( ImErrorProgramName, ImErrorFileName,	\
			infoMessage );					\
	else if ( ImInfoStream )					\
		fprintf( ImInfoStream, "%s: %s: %s", ImErrorProgramName,\
			ImErrorFileName, (infoMessage) );		\
}


#endif /* __IMINTERNALH__ */
