/* Parse ".desc" files from mosaiced images to generate (x,y) offsets for
 * every sub-image. Find all overlap stats and solve balancing with LMS.
 * Regenerate mosaic, with balancing fixed.
 * 
 * 1/12/93 JC
 *	- first version, unfinished!
 * 6/9/95 JC
 *	- LMS fixed, now works, more or less
 * 12/9/95 JC
 *	- now does positions correctly too
 *	- ignores trivial overlaps
 * 19/9/95 JC
 *	- prints correct number of balance factors!
 * 10/11/95 JC
 *	- now tracks im_copy() calls too, so you can save sub-images
 * 12/1/96 JC
 *	- slightly clearer diagnostics
 *	- better centre of factors around 1.0 with log() average
 * 1/3/96 JC
 *	- new im_global_balance_float variant lets our caller adjust factor
 *	  range if output has burn-out
 *	- im_global_balance_search uses the above to produce scaled output ...
 *	  very slow!
 * 11/3/96 JC
 *	- now tries current directory too for input files
 * 22/3/96 JC
 *	- horrible bug in position finding! now fixed
 * 1/8/97 JC
 *	- revised for new mosaic functions and non-square images
 * 12/9/97 JC
 *	- code for im_lrmosaic1() support
 *	- output type == input type, so works for short images too
 * 6/1/99 JC
 *	- new gamma parameter, do scale in linear space
 *	- removed _search version, as can now be done with ip
 *	- renamed _float to f suffix, in line with im_conv()/im_convf()
 * 15/2/00 JC
 *	- balancef() did not scale in linear space
 * 2/2/01 JC
 *	- added tunable max blend width
 * 7/11/01 JC
 *	- global_balance.h broken out for im_remosaic()
 * 25/02/02 JC
 *	- better transform function scheme
 * 21/3/01 JC
 *	- quicker bailout on error
 * 8/11/02 JC
 * 	- add <> around file names so you can have spaces :(
 * 9/12/02 JC
 *	- track original params and always reuse them ... makes us proof
 *	  against geo reconstruct errors
 * 10/3/03 JC
 *	- weed out overlaps which contain only transparent pixels
 * 4/1/07
 * 	- switch to new history thing, switch im_errormsg() too
 */

/*

    This file is part of VIPS.
    
    VIPS is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 */

/*

    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk

 */

/* Strategy: build a tree describing the file
 * relationships in the desc file, then walk that passing constraints
 * back up to the root. Look up file names in symbol_table.
 */

/* Define for debug output.
#define DEBUG
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <math.h>

#include <vips/vips.h>
#include <vips/transform.h>

#include "merge.h"
#include "global_balance.h"

#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/

#define MAX_ITEMS (50)

/* How pix an overlap has to be (in pixels) before we think it's trivial and
 * we ignore it.
 */
#define TRIVIAL (20 * 20)

/* Break a string into a list of strings. Write '\0's into the string. out
 * needs to be MAX_FILES long. -1 for error, otherwise number of args found.

	"<fred> <jim poop> <sn aff le>"

	out[0] = "fred"
	out[1] = "jim poop"
	out[2] = "sn aff le"

 */
static int
break_items( char *line, char **out )
{
	int i;
	char *p;

	for( i = 0; i < MAX_ITEMS; i++ ) {
		/* Skip to first '<'.
		 */
		if( !(p = strchr( line, '<' )) )
			break;

		out[i] = line = p + 1;

		if( !(p = strchr( line, '>' )) ) {
			im_error( "break_files", "%s", _( "no matching '>'" ) );
			return( -1 );
		}

		*p = '\0';
		line = p + 1;
	}

	if( i == MAX_ITEMS ) {
		im_error( "break_files", "%s", _( "too many items" ) );
		return( -1 );
	}

	return( i );
}

/* Try to open a file. If full path fails, try the current directory.
 */
IMAGE *
im__global_open_image( SymbolTable *st, char *name )
{
	IMAGE *im;

	if( (im = im_open_local( st->im, name, "r" )) ) 
		return( im );
	if( (im = im_open_local( st->im, im_skip_dir( name ), "r" )) ) 
		return( im );

	return( NULL );
}

static int
junk_node( JoinNode *node )
{
	IM_FREEF( g_slist_free, node->overlaps );

	return( 0 );
}

/* Hash from a filename to an index into symbol_table.
 */
static int
hash( char *n )
{
	int i;
	int r = 0;
	int l = strlen( n );

	for( i = 0; i < l; i++ )
		r = ((r + n[i]) * 43) & 0xffffff;

	return( r % SYM_TAB_SIZE );
}

/* Make a leaf for a file.
 */
static JoinNode *
build_node( SymbolTable *st, char *name )
{
	JoinNode *node = IM_NEW( st->im, JoinNode );
	int n = hash( name );

	/* Fill fields.
	 */
	if( !node || !(node->name = im_strdup( st->im, name )) )
		return( NULL );

	node->type = JOIN_LEAF;
	node->dirty = 0;
	node->mwidth = -2;
	node->st = st;
	im__transform_init( &node->cumtrn );
	node->trnim = NULL;
	node->arg1 = NULL;
	node->arg2 = NULL;
	node->overlaps = NULL;
	node->im = NULL;
	node->index = 0;

        if( im_add_close_callback( st->im, 
		(im_callback_fn) junk_node, node, NULL ) ) 
                return( NULL );

	/* Try to open.
	 */
	if( (node->im = im__global_open_image( st, name )) ) {
		/* There is a file there - set width and height.
		 */
		node->cumtrn.oarea.width = node->im->Xsize;
		node->cumtrn.oarea.height = node->im->Ysize;
	}
	else {
		/* Clear the error buffer to lessen confusion.
		 */
		im_error_clear();
	}

	st->table[n] = g_slist_prepend( st->table[n], node );

	return( node );
}

/* Make a new overlap struct.
 */
static OverlapInfo *
build_overlap( JoinNode *node, JoinNode *other, Rect *overlap )
{
	OverlapInfo *lap = IM_NEW( node->st->im, OverlapInfo );

	if( !lap )
		return( NULL );

	lap->node = node;
	lap->other = other;
	lap->overlap = *overlap;
	lap->nstats = NULL;
	lap->ostats = NULL;
	node->overlaps = g_slist_prepend( node->overlaps, lap );
	node->st->novl++;

	return( lap );
}

static void
overlap_destroy( OverlapInfo *lap )
{
	JoinNode *node = lap->node;

	node->overlaps = g_slist_remove( node->overlaps, lap );
	assert( node->st->novl > 0 );
	node->st->novl--;
}

static int
junk_table( SymbolTable *st )
{
	int i;

	for( i = 0; i < st->sz; i++ )
		IM_FREEF( g_slist_free, st->table[i] );

	return( 0 );
}

/* Build a new symbol table.
 */
SymbolTable *
im__build_symtab( IMAGE *out, int sz )
{
	SymbolTable *st = IM_NEW( out, SymbolTable );
	int i;

	if( !st )
		return( NULL );
	if( !(st->table = IM_ARRAY( out, sz, GSList * )) )
		return( NULL );
	st->sz = sz;
	st->im = out;
	st->novl = 0;
	st->nim = 0;
	st->njoin = 0;
	st->root = NULL;
	st->leaf = NULL;
	st->fac = NULL;

        if( im_add_close_callback( out, 
		(im_callback_fn) junk_table, st, NULL ) ) 
                return( NULL );

	for( i = 0; i < sz; i++ )
		st->table[i] = NULL;

	return( st );
}

/* Does this node have this file name?
 */
static JoinNode *
test_name( JoinNode *node, char *name )
{
	if( strcmp( node->name, name ) == 0 )
		return( node );
	else
		return( NULL );
}

/* Look up a filename in the symbol_table.
 */
static JoinNode *
find_node( SymbolTable *st, char *name ) 
{
	return( im_slist_map2( st->table[hash( name )],
		(VSListMap2Fn) test_name, name, NULL ) );
}

/* Given a name: return either the existing node for that name, or a new node
 * we have made.
 */
static JoinNode *
add_node( SymbolTable *st, char *name )
{
	JoinNode *node;

	if( !(node = find_node( st, name )) && 
		!(node = build_node( st, name )) )
		return( NULL );

	return( node );
}

/* Map a user function over the whole of the symbol table. 
 */
void *
im__map_table( SymbolTable *st, void *(*fn)(), void *a, void *b )
{
	int i;
	void *r;
	
	for( i = 0; i < st->sz; i++ )
		if( (r = im_slist_map2( st->table[i], 
			(VSListMap2Fn) fn, a, b )) )
			return( r );
	
	return( NULL );
}

/* Set the dirty field on a join.
 */
static void *
set_dirty( JoinNode *node, int state )
{	
	node->dirty = state;

	return( NULL );
}

/* Clean the whole table.
 */
static void
clean_table( SymbolTable *st )
{
	(void) im__map_table( st, set_dirty, (void *) 0, NULL );
}

/* Do geometry calculations on a node, assuming geo is up to date for any 
 * children.
 */
static void
calc_geometry( JoinNode *node )
{
	Rect um;

	switch( node->type ) {
	case JOIN_LR:
	case JOIN_TB:
	case JOIN_LRROTSCALE:
	case JOIN_TBROTSCALE:
		/* Join two areas.
		 */
		im_rect_unionrect( &node->arg1->cumtrn.oarea,
			&node->arg2->cumtrn.oarea, &um );
		node->cumtrn.iarea.left = 0;
		node->cumtrn.iarea.top = 0;
		node->cumtrn.iarea.width = um.width;
		node->cumtrn.iarea.height = um.height;
		im__transform_set_area( &node->cumtrn );
		break;

	case JOIN_CP:
		/* Copy from child.
		 */
		node->cumtrn = node->arg1->cumtrn;
		break;

	case JOIN_LEAF:
		/* Just use leaf dimensions, if there are any.
		 */
		if( node->im ) {
			node->cumtrn.iarea.left = 0;
			node->cumtrn.iarea.top = 0;
			node->cumtrn.iarea.width = node->im->Xsize;
			node->cumtrn.iarea.height = node->im->Ysize;
			im__transform_set_area( &node->cumtrn );
		}
		break;

	default:
		error_exit( "internal error #98356" );
		/*NOTREACHED*/
	}
}

/* Propogate a transform down a tree. If dirty is set, we've been here before,
 * so there is a doubling up of this node. If this is a leaf, then we have the
 * same leaf twice (which, in fact, we can cope with); if this is a node, we 
 * have circularity.
 */
static int
propogate_transform( JoinNode *node, Transformation *trn )
{
	if( !node )
		return( 0 );

	if( node->dirty && node->arg1 && node->arg2 ) {
		im_error( "im_global_balance", 
			"%s", _( "circularity detected" ) );
		return( -1 );
	}
	node->dirty = 1;

	/* Transform our children.
	 */
	if( propogate_transform( node->arg1, trn ) ||
		propogate_transform( node->arg2, trn ) )
		return( -1 );

	/* Transform us, and recalculate our position and size.
	 */
	im__transform_add( &node->cumtrn, trn, &node->cumtrn );
	calc_geometry( node );

	return( 0 );
}

/* Ah ha! A leaf is actually made up of two smaller files with an lr or a tb
 * merge. Turn a leaf node into a join node. Propogate the transform down 
 * arg2's side of the tree.
 */
static int
make_join( SymbolTable *st, JoinType type, 
	JoinNode *arg1, JoinNode *arg2, JoinNode *out, 
	double a, double b, double dx, double dy, int mwidth )
{
	Transformation trn;

	/* Check output is ok.
	 */
	if( out->type != JOIN_LEAF ) {
		im_error( "im_global_balance", 
			_( "image \"%s\" used twice as output" ), out->name );
		return( -1 );
	}

	/* Fill fields.
	 */
	out->type = type;
	out->mwidth = mwidth;
	out->a = a;
	out->b = b;
	out->dx = dx;
	out->dy = dy;
	out->arg1 = arg1;
	out->arg2 = arg2;
	out->thistrn.a = a;
	out->thistrn.b = -b;
	out->thistrn.c = b;
	out->thistrn.d = a;
	out->thistrn.dx = dx;
	out->thistrn.dy = dy;

	/* Clean the table and propogate the transform down the RHS of the
	 * graph.
	 */
	clean_table( st );
	if( propogate_transform( arg2, &out->thistrn ) )
		return( -1 );

	/* Find the position and size of our output.
	 */
	calc_geometry( out );

	/* Now normalise the result, so that out is at (0,0) again.
	 */
	trn.a = 1.0;
	trn.b = 0.0;
	trn.c = 0.0;
	trn.d = 1.0;
	trn.dx = -out->cumtrn.oarea.left;
	trn.dy = -out->cumtrn.oarea.top;
	clean_table( st );
	if( propogate_transform( out, &trn ) )
		return( -1 );

	return( 0 );
}

/* Make a copy node.
 */
static int
make_copy( SymbolTable *st, JoinNode *before, JoinNode *after )
{
	/* Check output is ok.
	 */
	if( after->type != JOIN_LEAF ) {
		im_error( "im_global_balance", 
			_( "image \"%s\" used twice as output" ), after->name );
		return( -1 );
	}

	/* Fill fields.
	 */
	after->type = JOIN_CP;
	after->arg1 = before;
	after->arg2 = NULL;

	/* Copy over the position and size from the before to the after.
	 */
	calc_geometry( after ); 

	return( 0 );
}

/* Process a single .desc line.
 */
static int
process_line( SymbolTable *st, const char *text )
{
	char line[1024];

#ifdef DEBUG
	printf( "read: %s\n", text );
#endif /*DEBUG*/

	/* We destroy line during the parse.
	 */
	im_strncpy( line, text, 1024 );

	if( im_isprefix( "#LRJOIN ", line ) || 
		im_isprefix( "#TBJOIN ", line ) ) {
		/* Yes: magic join command. Break into tokens. Format is eg.

			#LRJOIN <left> <right> <out> <x> <y> [<mwidth>]

		 */
		char *item[MAX_ITEMS];
		int nitems;
		JoinType type;
		JoinNode *arg1, *arg2, *join;
		int dx, dy, mwidth;

		if( (nitems = break_items( line, item )) < 0 )
			return( -1 );
		if( nitems != 5 && nitems != 6 ) {
			im_error( "global_balance", 
				"%s", _( "bad number of args in join line" ) );
			return( -1 );
		}

		if( !(arg1 = add_node( st, item[0] )) ||
			!(arg2 = add_node( st, item[1] )) ||
			!(join = add_node( st, item[2] )) )
			return( -1 );
		dx = atoi( item[3] );
		dy = atoi( item[4] );
		if( nitems == 6 ) 
			mwidth = atoi( item[5] );
		else
			mwidth = -1;
		if( im_isprefix( "#LRJOIN ", line ) )
			type = JOIN_LR;
		else
			type = JOIN_TB;

		if( make_join( st, type, arg1, arg2, 
			join, 1.0, 0.0, dx, dy, mwidth ) )
			return( -1 );
	}
	else if( im_isprefix( "#LRROTSCALE ", line ) ||
		im_isprefix( "#TBROTSCALE ", line ) ) {
		/* Rot + scale. Format is eg.

			#LRROTSCALE <left> <right> <out> \
				<a> <b> <x> <y> [<mwidth>]

		 */
		char *item[MAX_ITEMS];
		int nitems;
		JoinType type;
		JoinNode *arg1, *arg2, *join;
		double a, b, dx, dy;
		int mwidth;

		if( (nitems = break_items( line, item )) < 0 )
			return( -1 );
		if( nitems != 7 && nitems != 8 ) {
			im_error( "global_balance", 
				"%s", _( "bad number of args in join1 line" ) );
			return( -1 );
		}

		if( !(arg1 = add_node( st, item[0] )) ||
			!(arg2 = add_node( st, item[1] )) ||
			!(join = add_node( st, item[2] )) )
			return( -1 );
		a = g_ascii_strtod( item[3], NULL );
		b = g_ascii_strtod( item[4], NULL );
		dx = g_ascii_strtod( item[5], NULL );
		dy = g_ascii_strtod( item[6], NULL );
		if( nitems == 8 )
			mwidth = atoi( item[7] );
		else
			mwidth = -1;
		if( im_isprefix( "#LRROTSCALE ", line ) )
			type = JOIN_LRROTSCALE;
		else
			type = JOIN_TBROTSCALE;

		if( make_join( st, type, arg1, arg2, 
			join, a, b, dx, dy, mwidth ) )
			return( -1 );
	}
	else if( im_isprefix( "copy ", line ) ) {
		/* im_copy() call ... make a JOIN_CP node.
		 */
		char *item[MAX_ITEMS];
		int nitems;
		JoinNode *before, *after;

		if( (nitems = break_items( line, item )) < 0 )
			return( -1 );
		if( nitems != 2 ) {
			im_error( "global_balance", 
				"%s", _( "bad number of args in copy line" ) );
			return( -1 );
		}

		if( !(before = add_node( st, item[0] )) ||
			!(after = add_node( st, item[1] )) ||
			make_copy( st, before, after ) )
			return( -1 );
	}

	return( 0 );
}

/* Set the dirty flag on any nodes we reference.
 */
static void *
set_referenced( JoinNode *node )
{
	if( node->arg1 )
		node->arg1->dirty = 1;
	if( node->arg2 )
		node->arg2->dirty = 1;
	
	return( NULL );
}

/* Is this a root node? Should be clean.
 */
static void *
is_root( JoinNode *node )
{
	if( !node->dirty )
		return( (void *) node );
	else
		return( NULL );
}

/* Scan the symbol table, looking for a node which no node references.
 */
static JoinNode *
find_root( SymbolTable *st )
{
	JoinNode *root;
	JoinNode *notroot;

	/* Clean the table, then scan it, setting all pointed-to nodes dirty.
	 */
	clean_table( st );
	im__map_table( st, set_referenced, NULL, NULL );

	/* Look for the first clean symbol.
	 */
	root = (JoinNode *) im__map_table( st, is_root, NULL, NULL );

	/* No root? Hot dang!
	 */
	if( !root ) {
		im_error( "im_global_balance", 
			"%s", _( "mosaic root not found in desc file\n"
			"is this really a mosaiced image?" ) );
		return( NULL );
	}

	/* Now dirty that - then if there are any more clean symbols, we have
	 * more than one root.
	 */
	root->dirty = 1;
	if( (notroot = im__map_table( st, is_root, NULL, NULL )) ) {
		im_error( "im_global_balance", 
			"%s", _( "more than one root" ) );
		return( NULL );
	}

	return( root );
}

/* Walk history_list and parse each line.
 */
int
im__parse_desc( SymbolTable *st, IMAGE *in )
{
	GSList *p;

	for( p = in->history_list; p; p = p->next ) {
		GValue *value = (GValue *) p->data;

		assert( G_VALUE_TYPE( value ) == IM_TYPE_REF_STRING );

		if( process_line( st, im_ref_string_get( value ) ) )
			return( -1 );
	}

	/* Find root.
	 */
	if( !(st->root = find_root( st )) )
		return( -1 );

	return( 0 );
}

/* Count and index all leaf images.
 */
static void *
count_leaves( JoinNode *node )
{
	if( node->type == JOIN_LEAF ) {
		node->index = node->st->nim;
		node->st->nim++;
	}

	return( NULL );
}

#ifdef DEBUG
/* Print a JoinNode.
 */
static void
print_node( JoinNode *node )
{
	printf( "%s, position %dx%d, size %dx%d, index %d\n",
		im_skip_dir( node->name ),
		node->cumtrn.oarea.left, node->cumtrn.oarea.top,
		node->cumtrn.oarea.width, node->cumtrn.oarea.height,
		node->index );
}
#endif /*DEBUG*/

#ifdef DEBUG
/* Print a leaf.
 */
static void *
print_leaf( JoinNode *node )
{
	if( node->type == JOIN_LEAF ) 
		print_node( node );

	return( NULL );
}
#endif /*DEBUG*/

/* Count all join nodes.
 */
static void *
count_joins( JoinNode *node )
{
	if( node->type == JOIN_TB ||
		node->type == JOIN_LR ||
		node->type == JOIN_LRROTSCALE ||
		node->type == JOIN_TBROTSCALE )
		node->st->njoin++;

	return( NULL );
}

#ifdef DEBUG
/* Print a few spaces.
 */
static void
spc( int n )
{
	int i;

	for( i = 0; i < n; i++ )
		printf( " " );
}
#endif /*DEBUG*/

#ifdef DEBUG
static char *
JoinType2char( JoinType type )
{
	switch( type ) {
	case JOIN_LR: 		return( "JOIN_LR" );
	case JOIN_TB: 		return( "JOIN_TB" );
	case JOIN_LRROTSCALE: 	return( "JOIN_LRROTSCALE" );
	case JOIN_TBROTSCALE: 	return( "JOIN_TBROTSCALE" );
	case JOIN_CP: 		return( "JOIN_CP" );
	case JOIN_LEAF: 	return( "JOIN_LEAF" );

	default:
		error_exit( "internal error #9275" );
		/*NOTEACHED*/

		return( NULL );
	}
}
#endif /*DEBUG*/

#ifdef DEBUG
/* Print a join node.
 */
static void *
print_joins( JoinNode *node, int indent )
{
	switch( node->type ) {
	case JOIN_TB:
	case JOIN_LR:
	case JOIN_TBROTSCALE:
	case JOIN_LRROTSCALE:
		spc( indent );
		printf( "%s to make %s, size %dx%d, pos. %dx%d, of:\n", 
			JoinType2char( node->type ), 
			im_skip_dir( node->name ),
			node->cumtrn.oarea.width, node->cumtrn.oarea.height,
			node->cumtrn.oarea.left, node->cumtrn.oarea.top );
		spc( indent );
		printf( "reference:\n" );
		print_joins( node->arg1, indent+2 );
		spc( indent );
		printf( "secondary:\n" );
		print_joins( node->arg2, indent+2 );
		break;

	case JOIN_CP:
		spc( indent );
		printf( "copy to make %s of:\n", im_skip_dir( node->name ) );
		print_joins( node->arg1, indent+2 );
		break;

	case JOIN_LEAF:
		spc( indent );
		printf( "input image %s\n", im_skip_dir( node->name ) );
		break;
	}

	return( NULL );
}
#endif /*DEBUG*/

#ifdef DEBUG
/* Print an overlap.
 */
static void *
print_overlap( OverlapInfo *lap )
{
	printf( "-> %s overlaps with %s; (this, other) = (%.4G, %.4G)\n",
		im_skip_dir( lap->node->name ),
		im_skip_dir( lap->other->name ),
		lap->nstats->coeff[4],
		lap->ostats->coeff[4] );

	return( NULL );
}
#endif /*DEBUG*/

#ifdef DEBUG
/* Print the overlaps on a leaf.
 */
static void *
print_overlaps( JoinNode *node )
{
	if( node->type == JOIN_LEAF && g_slist_length( node->overlaps ) > 0 ) {
		printf( "overlap of %s with:\n", im_skip_dir( node->name ) );
		im_slist_map2( node->overlaps, 
			(VSListMap2Fn) print_overlap, NULL, NULL );
	}

	return( NULL );
}
#endif /*DEBUG*/

#ifdef DEBUG
/* Print and accumulate the error on an overlap.
 */
static void *
print_overlap_error( OverlapInfo *lap, double *fac, double *total )
{
	double na = lap->nstats->coeff[4];
	double oa = lap->ostats->coeff[4];
	double err;

	if( fac ) {
		na *= fac[lap->node->index];
		oa *= fac[lap->other->index];
	}

	err = na - oa;

	printf( "-> file %s, error = %g\n",
		im_skip_dir( lap->other->name ), err );
	*total += err*err;

	return( NULL );
}
#endif /*DEBUG*/

#ifdef DEBUG
/* Print and accumulate the overlap errors on a leaf.
 */
static void *
print_overlap_errors( JoinNode *node, double *fac, double *total )
{
	if( node->type == JOIN_LEAF && g_slist_length( node->overlaps ) > 0 ) {
		printf( "overlap of %s (index %d) with:\n", 
			im_skip_dir( node->name ), node->index );
		im_slist_map2( node->overlaps, 
			(VSListMap2Fn) print_overlap_error, fac, total );
	}

	return( NULL );
}
#endif /*DEBUG*/

/* Extract a rect.
 */
static int
extract_rect( IMAGE *in, IMAGE *out, Rect *r )
{
	return( im_extract_area( in, out, 
		r->left, r->top, r->width, r->height ) );
}

/* Two images overlap in an area ... make a mask the size of the area, which
 * has 255 for every pixel where both images are non-zero.
 */
static int
make_overlap_mask( IMAGE *ref, IMAGE *sec, IMAGE *mask, 
	Rect *rarea, Rect *sarea )
{
	IMAGE *t[6];

	if( im_open_local_array( mask, t, 6, "mytemps", "p" ) ||
		extract_rect( ref, t[0], rarea ) ||
		extract_rect( sec, t[1], sarea ) ||
		im_extract_band( t[0], t[2], 0 ) ||
		im_extract_band( t[1], t[3], 0 ) ||
		im_notequalconst( t[2], t[4], 0.0 ) || 
		im_notequalconst( t[3], t[5], 0.0 ) || 
		im_andimage( t[4], t[5], mask ) ) 
		return( -1 );

	return( 0 );
}

/* Find the number of non-zero pixels in a mask image.
 */
static int
count_nonzero( IMAGE *in, gint64 *count )
{
	double avg;

	if( im_avg( in, &avg ) )
		return( -1 );
	*count = (avg * in->Xsize * in->Ysize ) / 255.0;
	
	return( 0 );
}

/* Find stats on an area of an IMAGE ... consider only pixels for which the
 * mask is true.
 */
static DOUBLEMASK *
find_image_stats( IMAGE *in, IMAGE *mask, Rect *area )
{
	DOUBLEMASK *stats;
	IMAGE *t[4];
	gint64 count;

	/* Extract area, build black image, mask out pixels we want.
	 */
	if( im_open_local_array( in, t, 4, "find_image_stats", "p" ) ||
		extract_rect( in, t[0], area ) ||
		im_black( t[1], t[0]->Xsize, t[0]->Ysize, t[0]->Bands ) ||
		im_clip2fmt( t[1], t[2], t[0]->BandFmt ) ||
		im_ifthenelse( mask, t[0], t[2], t[3] ) )
		return( NULL );

	/* Get stats from masked image.
	 */
	if( !(stats = im_local_dmask( in, im_stats( t[3] ) )) ) 
		return( NULL );

	/* Number of non-zero pixels in mask.
	 */
	if( count_nonzero( mask, &count ) )
		return( NULL );

	/* And scale masked average to match.
	 */
	stats->coeff[4] *= (double) count / 
		((double) mask->Xsize * mask->Ysize);

	/* Yuk! Zap the deviation column with the pixel count. Used later to
	 * determine if this is likely to be a significant overlap.
	 */
	stats->coeff[5] = count;

#ifdef DEBUG
	if( count == 0 )
		im_warn( "global_balance", "%s", _( "empty overlap!" ) );
#endif /*DEBUG*/

	return( stats );
}

/* Find the stats for an overlap struct.
 */
static int
find_overlap_stats( OverlapInfo *lap )
{
	IMAGE *t1 = im_open_local( lap->node->im, "find_overlap_stats:1", "p" );
	Rect rarea, sarea;

	/* Translate the overlap area into the coordinate scheme for the main
	 * node.
	 */
	rarea = lap->overlap;
	rarea.left -= lap->node->cumtrn.oarea.left;
	rarea.top -= lap->node->cumtrn.oarea.top;

	/* Translate the overlap area into the coordinate scheme for the other
	 * node.
	 */
	sarea = lap->overlap;
	sarea.left -= lap->other->cumtrn.oarea.left;
	sarea.top -= lap->other->cumtrn.oarea.top;

	/* Make a mask for the overlap.
	 */
	if( make_overlap_mask( lap->node->trnim, lap->other->trnim, t1,
		&rarea, &sarea ) )
		return( -1 );

	/* Find stats for that area.
	 */
	if( !(lap->nstats = find_image_stats( lap->node->trnim, t1, &rarea )) )
		return( -1 );
	if( !(lap->ostats = find_image_stats( lap->other->trnim, t1, &sarea )) )
		return( -1 );

	return( 0 );
}

/* Sub-fn. of below.
 */
static void *
overlap_eq( OverlapInfo *this, JoinNode *node )
{
	if( this->other == node )
		return( this );
	else
		return( NULL );
}

/* Is this an overlapping leaf? If yes, add to overlap list.
 */
static void *
test_overlap( JoinNode *other, JoinNode *node )
{
	Rect overlap;
	OverlapInfo *lap;

	/* Is other a suitable leaf to overlap with node?
	 */
	if( other->type != JOIN_LEAF || node == other ) 
		return( NULL );

	/* Is there an overlap?
	 */
	im_rect_intersectrect( &node->cumtrn.oarea, &other->cumtrn.oarea, 
		&overlap );
	if( im_rect_isempty( &overlap ) ) 
		return( NULL );

	/* Is this a trivial overlap? Ignore it if it is.
	 */
	if( overlap.width * overlap.height < TRIVIAL )
		/* Too few pixels.
		 */
		return( NULL );

	/* Have we already added this overlap the other way around? ie. is 
	 * node on other's overlap list?
	 */
	if( im_slist_map2( other->overlaps, 
		(VSListMap2Fn) overlap_eq, node, NULL ) )
		return( NULL );

	/* A new overlap - add to overlap list.
	 */
	if( !(lap = build_overlap( node, other, &overlap )) )
		return( node );

	/* Calculate overlap statistics.
	 */
	if( find_overlap_stats( lap ) )
		return( node );

	/* If the pixel count either masked overlap is trivial, ignore this
	 * overlap.
	 */
	if( lap->nstats->coeff[5] < TRIVIAL || 
		lap->ostats->coeff[5] < TRIVIAL ) {
#ifdef DEBUG
		printf( "trivial overlap ... junking\n" );
		printf( "nstats count = %g, ostats count = %g\n",
			lap->nstats->coeff[5], lap->ostats->coeff[5] );
		print_overlap( lap );
#endif /*DEBUG*/
		overlap_destroy( lap );
	}

	return( NULL );
}

/* If this is a leaf, look at all other joins for a leaf that overlaps. Aside:
 * If this is a leaf, there should be an IMAGE. Flag an error if there is
 * not.
 */
static void *
find_overlaps( JoinNode *node, SymbolTable *st )
{
	if( node->type == JOIN_LEAF ) {
		/* Check for image.
		 */
		if( !node->im ) {
			im_error( "im_global_balance", 
				_( "unable to open \"%s\"" ), node->name );
			return( node );
		}
		if( !node->trnim ) 
			error_exit( "global_balance: sanity failure #9834" );

		return( im__map_table( st, test_overlap, node, NULL ) );
	}
	
	return( NULL );
}

/* Bundle of variables for matrix creation.
 */
typedef struct {
	SymbolTable *st;		/* Main table */
	JoinNode *leaf;			/* Leaf to be 1.000 */
	DOUBLEMASK *K;			/* LHS */
	DOUBLEMASK *M;			/* RHS */
	int row;			/* Current row */
} MatrixBundle;

/* Add a new row for the nominated overlap to the matricies.
 */
static void *
add_nominated( OverlapInfo *ovl, MatrixBundle *bun, double *gamma )
{
	double *Kp = bun->K->coeff + bun->row;
	double *Mp = bun->M->coeff + bun->row*bun->M->xsize;
	double ns = pow( ovl->nstats->coeff[4], 1/(*gamma) );
	double os = pow( ovl->ostats->coeff[4], 1/(*gamma) );

	Kp[0] = ns;
	Mp[ovl->other->index - 1] = os;

	bun->row++;

	return( NULL );
}

/* Add a new row for an ordinary overlap to the matricies.
 */
static void *
add_other( OverlapInfo *ovl, MatrixBundle *bun, double *gamma )
{
	double *Mp = bun->M->coeff + bun->row*bun->M->xsize;
	double ns = -pow( ovl->nstats->coeff[4], 1/(*gamma) );
	double os = pow( ovl->ostats->coeff[4], 1/(*gamma) );

	Mp[ovl->node->index - 1] = ns;
	Mp[ovl->other->index - 1] = os;

	bun->row++;

	return( NULL );
}

/* Add stuff for node to matrix.
 */
static void *
add_row( JoinNode *node, MatrixBundle *bun, double *gamma )
{
	if( node == bun->leaf )
		im_slist_map2( node->overlaps, 
			(VSListMap2Fn) add_nominated, bun, gamma );
	else
		im_slist_map2( node->overlaps, 
			(VSListMap2Fn) add_other, bun, gamma );
	
	return( NULL );
}

/* Fill K and M. leaf is image selected to have factor of 1.000.
 */
static void
fill_matricies( SymbolTable *st, double gamma, DOUBLEMASK *K, DOUBLEMASK *M )
{
	MatrixBundle bun;

	bun.st = st;
	bun.leaf = st->leaf;
	bun.K = K;
	bun.M = M;
	bun.row = 0;

	/* Build matricies.
	 */
	im__map_table( st, add_row, &bun, &gamma );
}

/* Used to select the leaf whose coefficient we set to 1.
 */
static void *
choose_leaf( JoinNode *node )
{
	if( node->type == JOIN_LEAF )
		return( node );
	
	return( NULL );
}

/* Make an image from a node.
 */
static IMAGE *
make_mos_image( SymbolTable *st, JoinNode *node, transform_fn tfn, void *a )
{
	IMAGE *im1, *im2, *out;

	switch( node->type ) {
	case JOIN_LR:
	case JOIN_TB:
		if( !(im1 = make_mos_image( st, node->arg1, tfn, a )) ||
			!(im2 = make_mos_image( st, node->arg2, tfn, a )) ||
			!(out = im_open_local( st->im, node->name, "p" )) )
			return( NULL );

		if( node->type == JOIN_LR ) {
			if( im_lrmerge( im1, im2, out, 
				-node->dx, -node->dy, node->mwidth ) )
				return( NULL );
		}
		else {
			if( im_tbmerge( im1, im2, out, 
				-node->dx, -node->dy, node->mwidth ) )
				return( NULL );
		}

		break;

	case JOIN_LRROTSCALE:
	case JOIN_TBROTSCALE:
		if( !(im1 = make_mos_image( st, node->arg1, tfn, a )) ||
			!(im2 = make_mos_image( st, node->arg2, tfn, a )) ||
			!(out = im_open_local( st->im, node->name, "p" )) )
			return( NULL );

		if( node->type == JOIN_LRROTSCALE ) {
			if( im__lrmerge1( im1, im2, out, 
				node->a, node->b, node->dx, node->dy,
				node->mwidth ) )
				return( NULL );
		}
		else {
			if( im__tbmerge1( im1, im2, out, 
				node->a, node->b, node->dx, node->dy,
				node->mwidth ) )
				return( NULL );
		}

		break;

	case JOIN_LEAF:
		/* Trivial case!
		 */
		if( !(out = tfn( node, a )) )
			return( NULL );

		break;

	case JOIN_CP:
		/* Very trivial case.
		 */
		out = make_mos_image( st, node->arg1, tfn, a );

		break;

	default:
		error_exit( "internal error #982369824375987" );
		/*NOTEACHED*/
		return( NULL );
	}

	return( out );
}

/* Re-build mosaic. 
 */
int
im__build_mosaic( SymbolTable *st, IMAGE *out, transform_fn tfn, void *a )
{
	JoinNode *root = st->root;
	IMAGE *im1, *im2;

	switch( root->type ) {
	case JOIN_LR:
	case JOIN_TB:
		if( !(im1 = make_mos_image( st, root->arg1, tfn, a )) ||
			!(im2 = make_mos_image( st, root->arg2, tfn, a )) )
			return( -1 );

		if( root->type == JOIN_LR ) {
			if( im_lrmerge( im1, im2, out, 
				-root->dx, -root->dy, root->mwidth ) )
				return( -1 );
		}
		else {
			if( im_tbmerge( im1, im2, out, 
				-root->dx, -root->dy, root->mwidth ) )
				return( -1 );
		}

		break;

	case JOIN_LRROTSCALE:
	case JOIN_TBROTSCALE:
		if( !(im1 = make_mos_image( st, root->arg1, tfn, a )) ||
			!(im2 = make_mos_image( st, root->arg2, tfn, a )) )
			return( -1 );

		if( root->type == JOIN_LRROTSCALE ) {
			if( im__lrmerge1( im1, im2, out, 
				root->a, root->b, root->dx, root->dy,
				root->mwidth ) )
				return( -1 );
		}
		else {
			if( im__tbmerge1( im1, im2, out, 
				root->a, root->b, root->dx, root->dy,
				root->mwidth ) )
				return( -1 );
		}

		break;

	case JOIN_LEAF:
		/* Trivial case! Just one file in our mosaic.
		 */
		if( !(im1 = tfn( root, a )) || im_copy( im1, out ) )
			return( -1 );

		break;

	case JOIN_CP:
		/* Very trivial case.
		 */
		if( !(im1 = make_mos_image( st, root->arg1, tfn, a )) )
			return( -1 );
		if( im_copy( im1, out ) )
			return( -1 );

		break;

	default:
		error_exit( "internal error #982369824375987" );
		/*NOTEACHED*/
	}

	return( 0 );
}

/* Find correction factors.
 */
static int
find_factors( SymbolTable *st, double gamma )
{
	DOUBLEMASK *K;
	DOUBLEMASK *M;
	DOUBLEMASK *m1, *m2, *m3, *m4, *m5;
	double total;
	double avg;
	int i;

	/* Make output matricies.
	 */
	if( !(K = im_local_dmask( st->im, 
			im_create_dmask( "K", 1, st->novl ) )) ||
		!(M = im_local_dmask( st->im, 
			im_create_dmask( "M", st->nim-1, st->novl ) )) ) 
		return( -1 );
	fill_matricies( st, gamma, K, M );
#ifdef DEBUG
	im_write_dmask( K );
	im_write_dmask( M );
#endif /*DEBUG*/

	/* Calculate LMS.
	 */
	if( !(m1 = im_local_dmask( st->im, im_mattrn( M, "lms:1" ) )) )
		return( -1 );
	if( !(m2 = im_local_dmask( st->im, im_matmul( m1, M, "lms:2" ) )) )
		return( -1 );
	if( !(m3 = im_local_dmask( st->im, im_matinv( m2, "lms:3" ) )) )
		return( -1 );
	if( !(m4 = im_local_dmask( st->im, im_matmul( m3, m1, "lms:4" ) )) )
		return( -1 );
	if( !(m5 = im_local_dmask( st->im, im_matmul( m4, K, "lms:5" ) )) )
		return( -1 );

	/* Make array of correction factors.
	 */
	if( !(st->fac = IM_ARRAY( st->im, st->nim, double )) )
		return( -1 );
	for( i = 0; i < m5->ysize; i++ )
		st->fac[i + 1] = m5->coeff[i];
	st->fac[0] = 1.0;

	/* Find average balance factor, normalise to that average.
	 */
	total = 0.0;
	for( i = 0; i < st->nim; i++ )
		total += st->fac[i];
	avg = total / st->nim;
	for( i = 0; i < st->nim; i++ )
		st->fac[i] /= avg;

#ifdef DEBUG
	/* Diagnostics!
	 */
	printf( "debugging output for im_global_balance():\n" );
	for( i = 0; i < st->nim; i++ )
		printf( "balance factor %d = %g\n", i, st->fac[i] );
	total = 0.0;
	printf( "Overlap errors:\n" );
	im__map_table( st, print_overlap_errors, NULL, &total );
	printf( "RMS error = %g\n", sqrt( total / st->novl ) );

	total = 0.0;
	printf( "Overlap errors after adjustment:\n" );
	im__map_table( st, print_overlap_errors, st->fac, &total );
	printf( "RMS error = %g\n", sqrt( total / st->novl ) );
#endif /*DEBUG*/

	return( 0 );
}

/* Look for all leaves, make sure we have a transformed version of each.
 */
static void *
generate_trn_leaves( JoinNode *node, SymbolTable *st )
{
	if( node->type == JOIN_LEAF ) {
		/* Check for image.
		 */
		if( !node->im ) {
			im_error( "im_global_balance", 
				_( "unable to open \"%s\"" ), node->name );
			return( node );
		}
		if( node->trnim ) 
			error_exit( "global_balance: sanity failure #765" );
		
		/* Special case: if this is an untransformed leaf (there will
		 * always be at least one), then skip the affine.
		 */
		if( im__transform_isidentity( &node->cumtrn ) )
			node->trnim = node->im;
		else
			if( !(node->trnim = 
				im_open_local( node->im, "trnleaf:1", "p" )) ||
				im__affine( node->im, node->trnim, 
					&node->cumtrn ) ) 
				return( node );
	}

	return( NULL );
}

/* Analyse mosaic.
 */
static int
analyse_mosaic( SymbolTable *st, IMAGE *in )
{
	/* Parse Hist on in.
	 */
	if( im__parse_desc( st, in ) )
		return( -1 );

	/* Print parsed data.
	 */
#ifdef DEBUG
	printf( "Input files:\n" );
	im__map_table( st, print_leaf, NULL, NULL );
	printf( "\nOutput file:\n" );
	print_node( st->root );
	printf( "\nJoin commands:\n" );
	print_joins( st->root, 0 );
#endif /*DEBUG*/

	/* Generate transformed leaves.
	 */
	if( im__map_table( st, generate_trn_leaves, st, NULL ) )
		return( -1 );

	/* Find overlaps.
	 */
	if( im__map_table( st, find_overlaps, st, NULL ) )
		return( -1 );

	/* Scan table, counting and indexing input images and joins. 
	 */
	im__map_table( st, count_leaves, NULL, NULL );
	im__map_table( st, count_joins, NULL, NULL );

	/* Select leaf to be 1.000.
	 * This must be index == 0, unless you change stuff above!
	 */
	st->leaf = im__map_table( st, choose_leaf, NULL, NULL );

	/* And print overlaps.
	 */
#ifdef DEBUG
	printf( "\nLeaf to be 1.000:\n" );
	print_node( st->leaf );
	printf( "\nOverlaps:\n" );
	im__map_table( st, print_overlaps, NULL, NULL );
	printf( "\n%d input files, %d unique overlaps, %d joins\n", 
		st->nim, st->novl, st->njoin );
#endif /*DEBUG*/

	return( 0 );
}

/* Scale im by fac --- if it's uchar/ushort, use a lut. If we can use a lut,
 * transform in linear space. If we can't, don't bother for efficiency.
 */
static IMAGE *
transform( JoinNode *node, double *gamma )
{
	SymbolTable *st = node->st;
	IMAGE *in = node->im;
	double fac = st->fac[node->index];

	IMAGE *out = im_open_local( st->im, node->name, "p" );

	IMAGE *t1 = im_open_local( out, "transform:1", "p" );
	IMAGE *t2 = im_open_local( out, "transform:2", "p" );
	IMAGE *t3 = im_open_local( out, "transform:3", "p" );
	IMAGE *t4 = im_open_local( out, "transform:4", "p" );
	IMAGE *t5 = im_open_local( out, "transform:5", "p" );

	if( !out || !t1 || !t2 || !t3 || !t4 || !t5 )
		return( NULL );

	if( fac == 1.0 ) {
		/* Easy!
		 */
		out = in;
	}
	else if( in->BandFmt == IM_BANDFMT_UCHAR ) {
		if( im_identity( t1, 1 ) || 
			im_powtra( t1, t2, 1.0 / (*gamma) ) ||
			im_lintra( fac, t2, 0.0, t3 ) ||
			im_powtra( t3, t4, *gamma ) ||
			im_clip2fmt( t4, t5, IM_BANDFMT_UCHAR ) ||
			im_maplut( in, out, t5 ) )
			return( NULL );
	}
	else if( in->BandFmt == IM_BANDFMT_USHORT ) {
		if( im_identity_ushort( t1, 1, 65535 ) || 
			im_powtra( t1, t2, 1.0 / (*gamma) ) ||
			im_lintra( fac, t2, 0.0, t3 ) ||
			im_powtra( t3, t4, *gamma ) ||
			im_clip2fmt( t4, t5, IM_BANDFMT_USHORT ) ||
			im_maplut( in, out, t5 ) )
			return( NULL );
	}
	else {
		/* Just im_lintra it.
		 */
		if( im_lintra( fac, in, 0.0, t1 ) ||
			im_clip2fmt( t1, out, in->BandFmt ) )
			return( NULL );
	}

	return( out );
}

/* As above, but output as float, not matched to input.
 */
static IMAGE *
transformf( JoinNode *node, double *gamma )
{
	SymbolTable *st = node->st;
	IMAGE *in = node->im;
	double fac = node->st->fac[node->index];

	IMAGE *out = im_open_local( st->im, node->name, "p" );
	IMAGE *t1 = im_open_local( out, "transform:1", "p" );
	IMAGE *t2 = im_open_local( out, "transform:2", "p" );
	IMAGE *t3 = im_open_local( out, "transform:3", "p" );
	IMAGE *t4 = im_open_local( out, "transform:4", "p" );

	if( !out || !t1 || !t2 || !t3 || !t4 )
		return( NULL );

	if( fac == 1.0 ) {
		/* Easy!
		 */
		out = in;
	}
	else if( in->BandFmt == IM_BANDFMT_UCHAR ) {
		if( im_identity( t1, 1 ) || 
			im_powtra( t1, t2, 1/(*gamma) ) ||
			im_lintra( fac, t2, 0.0, t3 ) ||
			im_powtra( t3, t4, *gamma ) ||
			im_maplut( in, out, t4 ) )
			return( NULL );
	}
	else if( in->BandFmt == IM_BANDFMT_USHORT ) {
		if( im_identity_ushort( t1, 1, 65535 ) || 
			im_powtra( t1, t2, 1/(*gamma) ) ||
			im_lintra( fac, t2, 0.0, t3 ) ||
			im_powtra( t3, t4, *gamma ) ||
			im_maplut( in, out, t4 ) )
			return( NULL );
	}
	else {
		/* Just im_lintra it.
		 */
		if( im_lintra( fac, in, 0.0, out ) )
			return( NULL );
	}

	return( out );
}

/* Balance mosaic, outputting in the original format.
 */
int
im_global_balance( IMAGE *in, IMAGE *out, double gamma )
{
	SymbolTable *st;

	if( !(st = im__build_symtab( out, SYM_TAB_SIZE )) ||
		analyse_mosaic( st, in ) ||
		find_factors( st, gamma ) ||
		im__build_mosaic( st, out, (transform_fn) transform, &gamma ) )
		return( -1 );

	return( 0 );
}

/* Balance mosaic, outputting as float. This is useful if the automatic
 * selection of balance range fails - our caller can search the output for the
 * min and max, and rescale to prevent burn-out.
 */
int
im_global_balancef( IMAGE *in, IMAGE *out, double gamma )
{	
	SymbolTable *st;

	if( !(st = im__build_symtab( out, SYM_TAB_SIZE )) ||
		analyse_mosaic( st, in ) ||
		find_factors( st, gamma ) ||
		im__build_mosaic( st, out, (transform_fn) transformf, &gamma ) )
		return( -1 );

	return( 0 );
}
