/**
 **	$Header: /import/dev-vis/image/imtools/v2.0/imtools/src/RCS/imfile.c,v 1.5 92/12/01 18:45:10 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
 **/

#define HEADER	"    $Header: /import/dev-vis/image/imtools/v2.0/imtools/src/RCS/imfile.c,v 1.5 92/12/01 18:45:10 nadeau Exp $"

/**
 **  FILE
 **	imfile.c	-  Image file known format query
 **
 **  PROJECT
 **	IM		-  Image Manipulation Tools
 **
 **  DESCRIPTION
 **	imfile opens the file or files and tries to figure out what kind of
 **	image file they are.
 **
 **  PUBLIC CONTENTS
 **			d =defined constant
 **			f =function
 **			m =defined macro
 **			t =typedef/struct/union
 **			v =variable
 **			? =other
 **
 **	main		f  main program
 **
 **  PRIVATE CONTENTS
 **	toolCommand	g  command info for arg parsing pkg
 **	toolOptions	g  option info for arg parsing pkg
 **
 **  HISTORY
 **	$Log:	imfile.c,v $
 **	Revision 1.5  92/12/01  18:45:10  nadeau
 **	Updated info message printing.
 **	
 **	Revision 1.4  92/08/31  17:06:04  vle
 **	Updated copyright notice.
 **	
 **	Revision 1.3  91/10/03  13:20:21  nadeau
 **	Update to version 2.0 of the Arg parsing package.
 **	
 **	Revision 1.2  91/03/11  14:38:43  nadeau
 **	Updated comments and updated to use new file formats table.
 **	
 **	Revision 1.1  90/07/02  13:16:37  nadeau
 **	Initial revision
 **	
 **	Revision 1.5  90/05/11  14:27:18  nadeau
 **	Removed old ifdefed dispatch table stuff and added more comments.
 **	
 **/

#include "imtools.h"





/*
 *  GLOBALS
 *	toolCommand		-  command info for arg parsing pkg
 *	toolOptions		-  option info for arg parsing pkg
 *
 *  DESCRIPTION
 *	toolCommand describes the command and gives the help text.
 *
 *	toolOptions lists the arg options accepted.
 */

private ArgCommand toolCommand =
{
	/* command name */		"imfile",

	/* major version # */		IMTOOLSMAJOR,
	/* minor version # */		IMTOOLSMINOR,
	/* subminor version # */	IMTOOLSSUBMINOR,

	/* -help pre-option list information				*/
"%command determines the type of image file format used by each file on its\n\
command line and prints it to stdout.\n\
",

	/* -help post-option list information				*/
	NULL,				/* Filled in later on		*/

	/* -fullhelp pre-option list information			*/
	NULL,				/* Use same message as for -help*/
	/* -fullhelp post-option list information			*/
	NULL,				/* Use same message as for -help*/

	ARGFNONE,			/* No special flags		*/
	"[options...] filenames...",
	"[options...] filenames...",
	"SDSC Image Tools, October 1992.",
	"Copyright (c) 1989-1992  San Diego Supercomputer Center (SDSC), CA, USA",
	NULL,				/* filled in later on		*/
	NULL,				/* filled in later on		*/
};

private char *toolHelp = "\n\
Typical Invocations:\n\
    List file formats for all files in the current directory:\n\
        %command *\n\
";

private char *toolFullHelp = "\n\
Output:\n\
    Output is a table giving the file name, its format name, and a description\n\
    of that format.  If %command cannot figure out the type of image file, the\n\
    words 'Unknown image file format' are printed beside the file name.\n\
";

private char *toolNote = "\n\
Additional Help:\n\
    This is an abbreviated help listing.  For a full listing of options,\n\
    including a list of image file formats supported, type:\n\
        %command -fullhelp\n\
";

#define TOOLNOPTIONS	2
private ArgOption toolOptions[TOOLNOPTIONS] =
{
	{ "infile", "filenames...", "Names of files to query",
	  ARGFIMPKEYWORD|ARGFREQUIRED, 1, ARGVNOMAX, ARGTSTRING },

	{ "long", NULL, "Show a long form of the information",
	  ARGFNONE, 0, 0, ARGTNONE },
};

#define TOOLNEQUIVS	0
#if TOOLNEQUIVS == 0
private ArgEquiv *toolEquivs;
#else
private ArgEquiv toolEquivs[TOOLNEQUIVS] =
{
};
#endif





/*
 * GLOBALS
 *	toolsDataTable	- a table for the storage of data read in
 *	toolsFlagsTable	- a table for the storage of read/write flags
 */

private TagTable *toolDataTable;	/* Data tag table		*/
private TagTable *toolFlagsTable;	/* Flags tag table		*/





/*
 *  FUNCTION
 *	imFileInfoHandler	- info handler for imfile
 *
 *  DESCRIPTION
 *	Called on each "info" message printed by the Image Tools file
 *	read routines, this handler prints the message to stdout as part
 *	of the -long option.  Unlike the default ImToolsInfoHandler, this
 *	handler intentionally omitts preceeding each message line with the
 *	program name and input file name.
 */

private int				/* Returns nothing		*/
imFileInfoHandler( program, filename, message )
	char *program;			/* Program name			*/
	char *filename;			/* File name			*/
	char *message;			/* Message to display           */
{
	fprintf( stdout, "		%s", message );
	return ( 0 );
}





/*
 *  FUNCTION
 *	main	-  main program
 *
 *  DESCRIPTION
 *	The incoming argument list is walked and each file checked
 *	to see what kind of image file format it uses.
 */

main( argc, argv )
	int argc;			/* Argument count		*/
	char *argv[];			/* Argument vector		*/
{
	int           i, j;		/* Counters			*/
	int	      n;		/* Number of entries		*/
	int	      numFiles;		/* Number of file names		*/
	char          fileName[1024];	/* Input file name		*/
	char         *formatName;	/* Input file's format		*/
	char        **pNames;		/* Format name list pointer	*/
	ImFileFormat **pFmt;		/* Format list pointer		*/
	ImVfb        *vfb;		/* Image			*/
	ImClt	     *clt;		/* Color lookup table		*/
	int           fd;		/* File descriptor		*/
	char          buffer[1024];	/* Output buffer		*/
	char	     *tmp;		/* Temp string			*/
	int         (*handler)( );	/* Temporary handler func ptr	*/
	boolean	      doLong = FALSE;	/* Do long output?		*/
	TagEntry     *dataEntry;	/* Tag table entry		*/


	/*
	 *  Use the standard Image Tools user registration and feedback forms.
	 */
	toolCommand.arg_register = ImToolsRegister;
	toolCommand.arg_feedback = ImToolsFeedback;


	/*
	 *  Allocate space for the total help string for the tool.  Copy the
	 *  tool-specific help in, then concatenate on the generic help text
	 *  used by most of the image tools.
	 */
	if ( (tmp = (char *)malloc( sizeof( char ) * (strlen( toolNote ) +
		strlen( toolHelp ) + 1) )) == NULL )
	{
		perror( ImToolsProgram );
		exit( 1 );
	}
	strcpy( tmp, toolHelp );
	strcat( tmp, toolNote );
	toolCommand.arg_help2 = tmp;

	if ( (tmp = (char *)malloc( sizeof( char ) * ( strlen( toolHelp ) +
		strlen( toolFullHelp ) + 1) )) == NULL )
	{
		perror( ImToolsProgram );
		exit( 1 );
	}
	strcpy( tmp, toolHelp );
	strcat( tmp, toolFullHelp );
	toolCommand.arg_fullhelp2 = tmp;


	/*
	 *  Parse arguments.
	 */
	ImToolsProgram = argv[0];
	ArgParse( argc, argv, &toolCommand, TOOLNOPTIONS, toolOptions,
		TOOLNEQUIVS, toolEquivs );
	numFiles = ArgQNValue( "infile", 0 );


	if ( ArgQNOccur( "long" ) != 0 )
	{
		/*
		 *  Set up the flags table based upon command-line arguments.
		 *  Also included are flags to direct error messages to stderr
		 *  and, info messages to stderr, a flag giving the program's
		 *  name for later use in error messages.
		 */
		toolFlagsTable = ImToolsBuildFlagsTable( );
		handler = imFileInfoHandler;
		TagTableAppend( toolFlagsTable,
			TagEntryAlloc( "info handler", POINTER, &handler ) );
		doLong = TRUE;
	}


	/*
	 *  List the files and the formats they use.
	 */
	for ( i = 0; i < numFiles; i++ )
	{
		strcpy( fileName, ArgQValue( "infile", 0, i )->arg_s );

		sprintf( buffer, "%s:", fileName );

		if ( (fd = open( fileName, O_RDONLY )) == -1 )
		{
			printf( "%-15s Cannot open file\n", buffer );
			continue;
		}

		formatName = ImFileQFormat( fd, fileName );
		if ( formatName == NULL )
		{
			printf( "%-15s Unknown image file format\n", buffer );
			close( fd );
			continue;
		}

		for ( pFmt = ImFileFormats; *pFmt; pFmt++ )
			if ( strcmp( (*pFmt)->format_names[0], formatName)== 0 )
				break;
		printf( "%-15s '%s', %s, %s\n", buffer, formatName,
			(*pFmt)->format_help, (*pFmt)->format_creator );

		if ( doLong )
		{
			/*
			 *  Make a data table to hold the incomming data.
			 */
			if ( (toolDataTable = TagTableAlloc( )) == TAGTABLENULL)
			{
				TagPError( ImToolsProgram );
				exit( 1 );
			}

			/*
			 *  Update the flags table to include the name of
			 *  the file we're reading.
			 */
			ImToolsChangeTagEntry( toolFlagsTable,
					"file name", fileName );

			/*
			 * Seek to beginning of file
			 */
			lseek( fd, 0, 0 );


			/*
			 *  Read in the file, printing info along the way.
			 */
			if ( ImFileRead( fd, formatName, toolFlagsTable,
				toolDataTable ) == -1 )
			{
				TagPError( ImToolsProgram );
				exit( 1 );
			}


			/*
			 *  Blow away all the VFB's and CLT's in the tag table.
		 	 *  For some file formats, there'll be additional
			 *  allocated space for image file names, hot spots,
			 *  and other things.  Since we don't know what all of
			 *  these are, or how to free their space, we'll just
			 *  let them slide as a memory leak and hope it doesn't
			 *  leak too much.  The VFB and CLT are the most
			 *  likely big memory hogs anyway.
			 */
			n = TagTableQNEntry( toolDataTable, "image vfb" );
			for ( j = 0; j < n; j++ )
			{
				dataEntry = TagTableQDirect( toolDataTable,
					"image vfb", j );
				TagEntryQValue( dataEntry, &vfb );
				if( vfb != IMVFBNULL )
					ImVfbFree( vfb );
			}
			n = TagTableQNEntry( toolDataTable, "image clt" );
			for ( j = 0; j < n; j++ )
			{
				dataEntry = TagTableQDirect( toolDataTable,
					"image clt", j );
				TagEntryQValue( dataEntry, &clt );
				if( clt != IMCLTNULL )
					ImCltFree( clt );
			}


			/*
			 *  And toss the data table itself.
			 */
			TagTableFree( toolDataTable );
		}

		close( fd );
	}
}
