/* pnmcatlr.c - concatenate portable anymaps left to right
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation.  This software is provided "as is" without express or
** implied warranty.
*/

#include <stdio.h>
#ifdef	SYSV
#include <string.h>
#else	SYSV
#include <strings.h>
#endif	SYSV
#include "pnm.h"

#define MAXFILES 100
#define max(a,b) ((a) > (b) ? (a) : (b))

main( argc, argv )
int argc;
char *argv[];
    {
    FILE *ifd[MAXFILES];
    xel **xels[MAXFILES], background;
    register xel **newxels;
    xelval maxval[MAXFILES], newmaxval;
    int argn, backdefault, backblack, lrflag, tbflag, nfiles, i;
    int rows[MAXFILES], cols[MAXFILES], format[MAXFILES], newformat, row, col;
    int newrows, newcols, new, pad;
    char *usage = "[-white|-black] pnmfile pnmfile ...";

    pm_progname = argv[0];

    argn = 1;
    backdefault = 1;
    lrflag = tbflag = 0;

    /* Check for flags. */
    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
	{
	if ( strncmp(argv[argn],"-white",max(strlen(argv[argn]),2)) == 0 )
	    {
	    backdefault = 0;
	    backblack = 0;
	    }
	else if ( strncmp(argv[argn],"-black",max(strlen(argv[argn]),2)) == 0 )
	    {
	    backdefault = 0;
	    backblack = 1;
	    }
	else if ( strncmp(argv[argn],"-lr",max(strlen(argv[argn]),2)) == 0 ||
	          strncmp(argv[argn],"-leftright",max(strlen(argv[argn]),2)) == 0 )
	    lrflag = 1;
	else if ( strncmp(argv[argn],"-tb",max(strlen(argv[argn]),2)) == 0 ||
	          strncmp(argv[argn],"-topbottom",max(strlen(argv[argn]),2)) == 0 )
	    tbflag = 1;
	else
	    pm_usage( usage );
	argn++;
	}

    if ( lrflag && tbflag )
	pm_error( "only one of -lr and -tb may be specified", 0,0,0,0,0 );
    if ( ! ( lrflag || tbflag ) )
	pm_error( "one of -lr or -tb must be specified", 0,0,0,0,0 );

    if ( argn < argc )
	{
	nfiles = argc - argn;
	for ( i = 0; i < nfiles; i++ )
	    ifd[i] = pm_openr( argv[argn+i] );
	}
    else
	{
	nfiles = 1;
	ifd[0] = stdin;
	}

    newcols = 0;
    newrows = 0;
    for ( i = 0; i < nfiles; i++ )
	{
	xels[i] =
	    pnm_readpnm( ifd[i], &cols[i], &rows[i], &maxval[i], &format[i] );
	pm_close( ifd[i] );
	if ( i == 0 )
	    {
	    newmaxval = maxval[i];
	    newformat = format[i];
	    }
	else if ( format[i] > newformat )
	    {
	    newmaxval = maxval[i];
	    newformat = format[i];
	    }
	if ( lrflag )
	    {
	    newcols += cols[i];
	    if ( rows[i] > newrows )
		newrows = rows[i];
	    }
	else
	    {
	    newrows += rows[i];
	    if ( cols[i] > newcols )
		newcols = cols[i];
	    }
	}

    for ( i = 0; i < nfiles; i++ )
	pnm_promoteformat(
	    xels[i], cols[i], rows[i], maxval[i], format[i], newmaxval,
	    newformat );

    if ( ! backdefault )
	if ( backblack )
	    background = pnm_blackxel( newmaxval, newformat );
	else
	    background = pnm_whitexel( newmaxval, newformat );

    newxels = pnm_allocarray( newcols, newrows );

    new = 0;

    for ( i = 0; i < nfiles; i++ )
	{
	if ( backdefault )
	    background =
		pnm_backgroundxel(
		    xels[i], cols[i], rows[i], newmaxval, newformat );

	if ( lrflag )
	    {
	    pad = (newrows - rows[i]) / 2;
	    for ( col = 0; col < cols[i]; col++ )
		{
		for ( row = 0; row < pad; row++ )
		    newxels[row][new+col] = background;
		for ( row = 0; row < rows[i]; row++ )
		    newxels[pad+row][new+col] = xels[i][row][col];
		for ( row = pad+rows[i]; row < newrows; row++ )
		    newxels[row][new+col] = background;
		}

	    new += cols[i];
	    }
	else
	    {
	    pad = (newcols - cols[i]) / 2;
	    for ( row = 0; row < rows[i]; row++ )
		{
		for ( col = 0; col < pad; col++ )
		    newxels[new+row][col] = background;
		for ( col = 0; col < cols[i]; col++ )
		    newxels[new+row][pad+col] = xels[i][row][col];
		for ( col = pad+cols[i]; col < newcols; col++ )
		    newxels[new+row][col] = background;
		}

	    new += rows[i];
	    }

	}

    pnm_writepnm( stdout, newxels, newcols, newrows, newmaxval, newformat );

    exit( 0 );
    }
