Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/* Vesione dell'Autofill aggiornata al 22.11.94 (Fabrizio Grisoli)           */
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/* aggiornata il 20.8.98 per CM24 (W.T.) */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "autofill.h"
Toshihiro Shimizu 890ddd
#include <stdio.h></stdio.h>
Toshihiro Shimizu 890ddd
#include <stdlib.h></stdlib.h>
Toshihiro Shimizu 890ddd
#include <math.h></math.h>
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Campbell Barton 40cabe
#include "tw/tw.h"
Toshihiro Shimizu 890ddd
#include "toonz/fill.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttilesaver.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/tmacro.h"
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define PRINTF
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct s_segm {
Toshihiro Shimizu 890ddd
	int xa, xb, region;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef struct big {
Toshihiro Shimizu 890ddd
	UINT lo, hi;
Toshihiro Shimizu 890ddd
} BIG;
Toshihiro Shimizu 890ddd
#define ADD_BIG(B, X) ((B).lo += (UINT)(X), \
Toshihiro Shimizu 890ddd
					   (B).hi += (B).lo >> 30, (B).lo &= 0x3fffffff, (B))
Toshihiro Shimizu 890ddd
#define ASS_BIG(B, X) ((B).lo = (UINT)(X), \
Toshihiro Shimizu 890ddd
					   (B).hi = (B).lo >> 30, (B).lo &= 0x3fffffff, (B))
Toshihiro Shimizu 890ddd
#define ADD_BIG_BIG(B1, B2) ((B1).lo += (B2).lo, (B1).hi += (B2).hi, \
Toshihiro Shimizu 890ddd
							 (B1).hi += (B1).lo >> 30, (B1).lo &= 0x3fffffff, (B1))
Toshihiro Shimizu 890ddd
#define BIG_TO_DOUBLE(B) ((double)(B).hi * (double)0x40000000 + (double)(B).lo)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BORDER_TOO 1
Toshihiro Shimizu 890ddd
#define NO_BORDER 0
Toshihiro Shimizu 890ddd
#define DIM_TRESH 0.00005
Toshihiro Shimizu 890ddd
#define AMB_TRESH 130000
Toshihiro Shimizu 890ddd
#define MIN_SIZE 20
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct vicine {
Toshihiro Shimizu 890ddd
	int region_id;
Toshihiro Shimizu 890ddd
	struct vicine *next;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct s_fabri_region {
Toshihiro Shimizu 890ddd
	int active,
Toshihiro Shimizu 890ddd
		nextfree,
Toshihiro Shimizu 890ddd
		x, y, x1, y1, x2, y2, lx, ly,
Toshihiro Shimizu 890ddd
		xm, ym, npix, lxa, lxb,
Toshihiro Shimizu 890ddd
		tone, color_id,
Toshihiro Shimizu 890ddd
		per, holes, match;
Toshihiro Shimizu 890ddd
	BIG bx, by;
Toshihiro Shimizu 890ddd
	BIG bx2, by2;
Toshihiro Shimizu 890ddd
	struct vicine *vicini;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct s_fabri_region_list {
Toshihiro Shimizu 890ddd
	struct s_fabri_region *array;
Toshihiro Shimizu 890ddd
	int size, n, lx, ly;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static struct s_fabri_region_list
Toshihiro Shimizu 890ddd
	F_reference = {0, 0, 0},
Toshihiro Shimizu 890ddd
	F_work = {0, 0, 0};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int F_ref_bx = 0;
Toshihiro Shimizu 890ddd
static int F_ref_by = 0;
Toshihiro Shimizu 890ddd
static int F_wor_bx = 0;
Toshihiro Shimizu 890ddd
static int F_wor_by = 0;
Toshihiro Shimizu 890ddd
static int Dx_f = 0, DP_f = 0, Df_f = 0;
Toshihiro Shimizu 890ddd
static int Dx_t = 0, DP_t = 0, Df_t = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*-- Local Prototipes -------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int trova_migliore_padre(int prob_vector[], int *att_best);
Toshihiro Shimizu 890ddd
static int match(int prob[], int padre, int *fro, int *to);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void scan_fabri_regions(TRasterCM32P ras, struct s_fabri_region_list *rlst, int mode,
Toshihiro Shimizu 890ddd
							   int x1, int y1, int x2, int y2);
Toshihiro Shimizu 890ddd
static void rinomina(int r1, int r2, int r_num, struct s_fabri_region_list *rl);
Toshihiro Shimizu 890ddd
static void aggiungi(int r1, int r2, struct s_fabri_region_list *rlst);
Toshihiro Shimizu 890ddd
static void rimuovi_tutti(int r1, struct s_fabri_region_list *rlst);
Toshihiro Shimizu 890ddd
static void fondi(struct s_fabri_region_list *rlst, int r1, int r2);
Toshihiro Shimizu 890ddd
static void assign_prob3(int prob[], int i, int j);
Toshihiro Shimizu 890ddd
static void find_best(int prob_vector[], int *col, int to);
Toshihiro Shimizu 890ddd
static void free_list(struct vicine **vic);
Toshihiro Shimizu 890ddd
static int somma_quadrati(int x, int y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
void rect_autofill_learn(const TToonzImageP &imgToLearn, int x1, int y1, int x2, int y2)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double abx, aby;
Toshihiro Shimizu 890ddd
	int tot_pix = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((x2 - x1) * (y2 - y1) < MIN_SIZE)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pbx = pby = 0.0;
Toshihiro Shimizu 890ddd
	abx = aby = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterCM32P ras = imgToLearn->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (F_reference.array) {
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_reference.n; i++)
Toshihiro Shimizu 890ddd
			free_list(&F_reference.array[i].vicini);
Toshihiro Shimizu 890ddd
		free(F_reference.array);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	F_reference.array = 0;
Toshihiro Shimizu 890ddd
	F_reference.size = 0;
Toshihiro Shimizu 890ddd
	F_reference.n = 0;
Toshihiro Shimizu 890ddd
	F_reference.lx = 0;
Toshihiro Shimizu 890ddd
	F_reference.ly = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	scan_fabri_regions(ras, &F_reference, 1, x1, y1, x2, y2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n; i++) {
Toshihiro Shimizu 890ddd
		F_reference.array[i].match = -1;
Toshihiro Shimizu 890ddd
		F_reference.array[i].color_id = ras->pixels(F_reference.array[i].y)[F_reference.array[i].x].getPaint();
Toshihiro Shimizu 890ddd
		pbx += BIG_TO_DOUBLE(F_reference.array[i].bx);
Toshihiro Shimizu 890ddd
		pby += BIG_TO_DOUBLE(F_reference.array[i].by);
Toshihiro Shimizu 890ddd
		abx = BIG_TO_DOUBLE(F_reference.array[i].bx);
Toshihiro Shimizu 890ddd
		aby = BIG_TO_DOUBLE(F_reference.array[i].by);
Toshihiro Shimizu 890ddd
		tot_pix += F_reference.array[i].npix;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (tot_pix) {
Toshihiro Shimizu 890ddd
		F_ref_bx = pbx / tot_pix;
Toshihiro Shimizu 890ddd
		F_ref_by = pby / tot_pix;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		F_ref_bx = 0;
Toshihiro Shimizu 890ddd
		F_ref_by = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*----------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
bool rect_autofill_apply(const TToonzImageP &imgToApply, int x1, int y1, int x2, int y2, bool selective, TTileSetCM32 *tileSet)
Toshihiro Shimizu 890ddd
/*----------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double abx, aby;
Toshihiro Shimizu 890ddd
	int i, j;
Toshihiro Shimizu 890ddd
	int tot_pix = 0;
Toshihiro Shimizu 890ddd
	int *prob_vector;
Toshihiro Shimizu 890ddd
	int fro, to;
Toshihiro Shimizu 890ddd
	int col;
Toshihiro Shimizu 890ddd
	int valore;
Toshihiro Shimizu 890ddd
	int padre;
Toshihiro Shimizu 890ddd
	//int temp_prob, att_match;
Toshihiro Shimizu 890ddd
	TRasterCM32P ras = imgToApply->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((x2 - x1) * (y2 - y1) < MIN_SIZE)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (F_reference.n <= 0 || F_reference.array == 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pbx = pby = 0.0;
Toshihiro Shimizu 890ddd
	abx = aby = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* Resetta gli eventuali accoppiamenti fatti precedentemente */
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n; i++)
Toshihiro Shimizu 890ddd
		F_reference.array[i].match = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (F_work.array) {
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_work.n; i++)
Toshihiro Shimizu 890ddd
			free_list(&F_work.array[i].vicini);
Toshihiro Shimizu 890ddd
		free(F_work.array);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	F_work.array = 0;
Toshihiro Shimizu 890ddd
	F_work.size = 0;
Toshihiro Shimizu 890ddd
	F_work.n = 0;
Toshihiro Shimizu 890ddd
	F_work.lx = 0;
Toshihiro Shimizu 890ddd
	F_work.ly = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	scan_fabri_regions(ras, &F_work, 1, x1, y1, x2, y2);
Toshihiro Shimizu 890ddd
	if (F_work.n <= 0 || F_work.array == 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (abs(F_work.lx * F_work.ly - F_reference.lx * F_reference.ly) > 0.1 *
Toshihiro Shimizu 890ddd
																		   (F_work.lx * F_work.ly + F_reference.lx * F_reference.ly))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_work.n; i++) {
Toshihiro Shimizu 890ddd
		F_work.array[i].match = -1;
Toshihiro Shimizu 890ddd
		pbx += BIG_TO_DOUBLE(F_work.array[i].bx);
Toshihiro Shimizu 890ddd
		pby += BIG_TO_DOUBLE(F_work.array[i].by);
Toshihiro Shimizu 890ddd
		abx = BIG_TO_DOUBLE(F_work.array[i].bx);
Toshihiro Shimizu 890ddd
		aby = BIG_TO_DOUBLE(F_work.array[i].by);
Toshihiro Shimizu 890ddd
		tot_pix += F_work.array[i].npix;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	F_wor_bx = pbx / tot_pix;
Toshihiro Shimizu 890ddd
	F_wor_by = pby / tot_pix;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	prob_vector = (int *)calloc(3 * F_work.n * F_reference.n, sizeof(int));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n; i++)
Toshihiro Shimizu 890ddd
		for (j = 0; j < F_work.n; j++)
Toshihiro Shimizu 890ddd
			assign_prob3(prob_vector, i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Dx_f = Dx_f / F_reference.n;
Toshihiro Shimizu 890ddd
	DP_f = DP_f / F_reference.n;
Toshihiro Shimizu 890ddd
	Df_f = Df_f / F_reference.n;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Dx_t = Dx_t / F_work.n;
Toshihiro Shimizu 890ddd
	DP_t = DP_t / F_work.n;
Toshihiro Shimizu 890ddd
	Df_t = Df_t / F_work.n;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef SELECTIVE
Toshihiro Shimizu 890ddd
	if (selective) {
Toshihiro Shimizu 890ddd
		//Accoppia non trasparenti
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_work.n; i++)
Toshihiro Shimizu 890ddd
			if (F_work.array[i].color_id != 0) {
Toshihiro Shimizu 890ddd
				temp_prob = 0;
Toshihiro Shimizu 890ddd
				att_match = F_reference.n;
Toshihiro Shimizu 890ddd
				/* Se non verra' aggiornato in seguito non verra' *
Toshihiro Shimizu 890ddd
        * comunque piu' cambiato di colore               */
Toshihiro Shimizu 890ddd
				for (j = 0; j < F_reference.n; j++)
Toshihiro Shimizu 890ddd
					if ((F_reference.array[i].match < 0) &&
Toshihiro Shimizu 890ddd
						((prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
							 (prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
							 (prob_vector[2 * (F_work.n * F_reference.n) + i * F_reference.n + j] / 1500.0) >
Toshihiro Shimizu 890ddd
						 temp_prob)) {
Toshihiro Shimizu 890ddd
						att_match = j;
Toshihiro Shimizu 890ddd
						temp_prob = (prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
									(prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
									(prob_vector[2 * (F_work.n * F_reference.n) + i * F_reference.n + j] / 1500.0);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				F_work.array[i].match = att_match;
Toshihiro Shimizu 890ddd
				if (att_match < F_reference.n)
Toshihiro Shimizu 890ddd
					F_reference.array[att_match].match = i;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*--------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool recomputeBBox = false;
Toshihiro Shimizu 890ddd
	FillParameters params;
Toshihiro Shimizu 890ddd
	params.m_emptyOnly = selective;
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n && i < F_work.n; i++) {
Toshihiro Shimizu 890ddd
		padre = trova_migliore_padre(prob_vector, &fro);
Toshihiro Shimizu 890ddd
		valore = match(prob_vector, padre, &fro, &to);
Toshihiro Shimizu 890ddd
		if (valore > AMB_TRESH) {
Toshihiro Shimizu 890ddd
			F_work.array[to].match = fro;
Toshihiro Shimizu 890ddd
			F_reference.array[fro].match = to;
Toshihiro Shimizu 890ddd
			F_work.array[to].color_id = F_reference.array[fro].color_id;
Toshihiro Shimizu 890ddd
			if ((F_work.array[to].color_id != 0) && (valore != 0)) {
Toshihiro Shimizu 890ddd
				params.m_p = TPoint(F_work.array[to].x, F_work.array[to].y);
Toshihiro Shimizu 890ddd
				params.m_styleId = F_work.array[to].color_id;
Toshihiro Shimizu 890ddd
				TTileSaverCM32 tileSaver(ras, tileSet);
Toshihiro Shimizu 890ddd
				recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/*..........................................................................*/
Toshihiro Shimizu 890ddd
	/* Matching basato sulla probabilita' di colore                             */
Toshihiro Shimizu 890ddd
	/*..........................................................................*/
Toshihiro Shimizu 890ddd
	if (FALSE) {
Toshihiro Shimizu 890ddd
		bool recomputeBBox = false;
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_work.n; i++) {
Toshihiro Shimizu 890ddd
			if (F_work.array[i].match < 0) {
Toshihiro Shimizu 890ddd
				find_best(prob_vector, &col, i);
Toshihiro Shimizu 890ddd
				F_work.array[i].match = 1;
Toshihiro Shimizu 890ddd
				F_work.array[i].color_id = col;
Toshihiro Shimizu 890ddd
				if (F_work.array[i].color_id != 0) {
Toshihiro Shimizu 890ddd
					params.m_p = TPoint(F_work.array[i].x, F_work.array[i].y);
Toshihiro Shimizu 890ddd
					params.m_styleId = F_work.array[i].color_id;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					TTileSaverCM32 tileSaver(ras, tileSet);
Toshihiro Shimizu 890ddd
					recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	free(prob_vector);
Toshihiro Shimizu 890ddd
	return recomputeBBox;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/* Versione del Learning delle aree di Fabrizio                              */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
void autofill_learn(const TToonzImageP &imgToLearn)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double abx, aby;
Toshihiro Shimizu 890ddd
	int tot_pix = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pbx = pby = 0.0;
Toshihiro Shimizu 890ddd
	abx = aby = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterCM32P ras = imgToLearn->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (F_reference.array) {
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_reference.n; i++)
Toshihiro Shimizu 890ddd
			free_list(&F_reference.array[i].vicini);
Toshihiro Shimizu 890ddd
		free(F_reference.array);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	F_reference.array = 0;
Toshihiro Shimizu 890ddd
	F_reference.size = 0;
Toshihiro Shimizu 890ddd
	F_reference.n = 0;
Toshihiro Shimizu 890ddd
	F_reference.lx = 0;
Toshihiro Shimizu 890ddd
	F_reference.ly = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	scan_fabri_regions(ras, &F_reference, 0, 0, 0, 0, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n; i++) {
Toshihiro Shimizu 890ddd
		F_reference.array[i].match = -1;
Toshihiro Shimizu 890ddd
		F_reference.array[i].color_id = ras->pixels(F_reference.array[i].y)[F_reference.array[i].y].getPaint();
Toshihiro Shimizu 890ddd
		pbx += BIG_TO_DOUBLE(F_reference.array[i].bx);
Toshihiro Shimizu 890ddd
		pby += BIG_TO_DOUBLE(F_reference.array[i].by);
Toshihiro Shimizu 890ddd
		abx = BIG_TO_DOUBLE(F_reference.array[i].bx);
Toshihiro Shimizu 890ddd
		aby = BIG_TO_DOUBLE(F_reference.array[i].by);
Toshihiro Shimizu 890ddd
		tot_pix += F_reference.array[i].npix;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	F_ref_bx = pbx / tot_pix;
Toshihiro Shimizu 890ddd
	F_ref_by = pby / tot_pix;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-- end of learn_fabrizio --------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/* Versione del matching delle aree di Fabrizio                              */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
bool autofill_apply(const TToonzImageP &imgToApply, bool selective, TTileSetCM32 *tileSet)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double abx, aby;
Toshihiro Shimizu 890ddd
	int i, j;
Toshihiro Shimizu 890ddd
	int tot_pix = 0;
Toshihiro Shimizu 890ddd
	int *prob_vector;
Toshihiro Shimizu 890ddd
	int fro, to;
Toshihiro Shimizu 890ddd
	int col;
Toshihiro Shimizu 890ddd
	int valore;
Toshihiro Shimizu 890ddd
	int padre;
Toshihiro Shimizu 890ddd
	//  int  temp_prob, att_match;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (F_reference.n <= 0 || F_reference.array == 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pbx = pby = 0.0;
Toshihiro Shimizu 890ddd
	abx = aby = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterCM32P ras = imgToApply->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* Resetta gli eventuali accoppiamenti fatti precedentemente */
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n; i++)
Toshihiro Shimizu 890ddd
		F_reference.array[i].match = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (F_work.array) {
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_work.n; i++)
Toshihiro Shimizu 890ddd
			free_list(&F_work.array[i].vicini);
Toshihiro Shimizu 890ddd
		free(F_work.array);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	F_work.array = 0;
Toshihiro Shimizu 890ddd
	F_work.size = 0;
Toshihiro Shimizu 890ddd
	F_work.n = 0;
Toshihiro Shimizu 890ddd
	F_work.lx = 0;
Toshihiro Shimizu 890ddd
	F_work.ly = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	scan_fabri_regions(ras, &F_work, 0, 0, 0, 0, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (abs(F_work.lx * F_work.ly - F_reference.lx * F_reference.ly) > 0.1 *
Toshihiro Shimizu 890ddd
																		   (F_work.lx * F_work.ly + F_reference.lx * F_reference.ly))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_work.n; i++) {
Toshihiro Shimizu 890ddd
		F_work.array[i].match = -1;
Toshihiro Shimizu 890ddd
		pbx += BIG_TO_DOUBLE(F_work.array[i].bx);
Toshihiro Shimizu 890ddd
		pby += BIG_TO_DOUBLE(F_work.array[i].by);
Toshihiro Shimizu 890ddd
		abx = BIG_TO_DOUBLE(F_work.array[i].bx);
Toshihiro Shimizu 890ddd
		aby = BIG_TO_DOUBLE(F_work.array[i].by);
Toshihiro Shimizu 890ddd
		tot_pix += F_work.array[i].npix;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	F_wor_bx = pbx / tot_pix;
Toshihiro Shimizu 890ddd
	F_wor_by = pby / tot_pix;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	prob_vector = (int *)calloc(3 * F_work.n * F_reference.n, sizeof(int));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n; i++)
Toshihiro Shimizu 890ddd
		for (j = 0; j < F_work.n; j++)
Toshihiro Shimizu 890ddd
			assign_prob3(prob_vector, i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Dx_f = Dx_f / F_reference.n;
Toshihiro Shimizu 890ddd
	DP_f = DP_f / F_reference.n;
Toshihiro Shimizu 890ddd
	Df_f = Df_f / F_reference.n;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Dx_t = Dx_t / F_work.n;
Toshihiro Shimizu 890ddd
	DP_t = DP_t / F_work.n;
Toshihiro Shimizu 890ddd
	Df_t = Df_t / F_work.n;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef SELECTIVE
Toshihiro Shimizu 890ddd
	if (selective) {
Toshihiro Shimizu 890ddd
		// Accoppia non trasparenti
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_work.n; i++)
Toshihiro Shimizu 890ddd
			if (F_work.array[i].color_id != 0) {
Toshihiro Shimizu 890ddd
				temp_prob = 0;
Toshihiro Shimizu 890ddd
				att_match = F_reference.n;
Toshihiro Shimizu 890ddd
				/* Se non verra' aggiornato in seguito non verra' *
Toshihiro Shimizu 890ddd
      * comunque piu' cambiato di colore               */
Toshihiro Shimizu 890ddd
				for (j = 0; j < F_reference.n; j++)
Toshihiro Shimizu 890ddd
					if ((F_reference.array[i].match < 0) &&
Toshihiro Shimizu 890ddd
						((prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
							 (prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
							 (prob_vector[2 * (F_work.n * F_reference.n) + i * F_reference.n + j] / 1500.0) >
Toshihiro Shimizu 890ddd
						 temp_prob)) {
Toshihiro Shimizu 890ddd
						att_match = j;
Toshihiro Shimizu 890ddd
						temp_prob = (prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
									(prob_vector[i * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
									(prob_vector[2 * (F_work.n * F_reference.n) + i * F_reference.n + j] / 1500.0);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				F_work.array[i].match = att_match;
Toshihiro Shimizu 890ddd
				if (att_match < F_reference.n)
Toshihiro Shimizu 890ddd
					F_reference.array[att_match].match = i;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*--------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool recomputeBBox = false;
Toshihiro Shimizu 890ddd
	FillParameters params;
Toshihiro Shimizu 890ddd
	params.m_emptyOnly = selective;
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n && i < F_work.n; i++) {
Toshihiro Shimizu 890ddd
		padre = trova_migliore_padre(prob_vector, &fro);
Toshihiro Shimizu 890ddd
		valore = match(prob_vector, padre, &fro, &to);
Toshihiro Shimizu 890ddd
		if (valore > AMB_TRESH) {
Toshihiro Shimizu 890ddd
			F_work.array[to].match = fro;
Toshihiro Shimizu 890ddd
			F_reference.array[fro].match = to;
Toshihiro Shimizu 890ddd
			F_work.array[to].color_id = F_reference.array[fro].color_id;
Toshihiro Shimizu 890ddd
			if ((F_work.array[to].color_id != 0) && (valore != 0)) {
Toshihiro Shimizu 890ddd
				params.m_p = TPoint(F_work.array[to].x, F_work.array[to].y);
Toshihiro Shimizu 890ddd
				params.m_styleId = F_work.array[to].color_id;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TTileSaverCM32 tileSaver(ras, tileSet);
Toshihiro Shimizu 890ddd
				recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*..........................................................................*/
Toshihiro Shimizu 890ddd
		/* Matching basato sulla probabilita' di colore                             */
Toshihiro Shimizu 890ddd
		/*..........................................................................*/
Toshihiro Shimizu 890ddd
		if (FALSE) {
Toshihiro Shimizu 890ddd
			bool recomputeBBox = false;
Toshihiro Shimizu 890ddd
			for (i = 0; i < F_work.n; i++) {
Toshihiro Shimizu 890ddd
				if (F_work.array[i].match < 0) {
Toshihiro Shimizu 890ddd
					find_best(prob_vector, &col, i);
Toshihiro Shimizu 890ddd
					F_work.array[i].match = 1;
Toshihiro Shimizu 890ddd
					F_work.array[i].color_id = col;
Toshihiro Shimizu 890ddd
					if (F_work.array[i].color_id != 0) {
Toshihiro Shimizu 890ddd
						params.m_p = TPoint(F_work.array[i].x, F_work.array[i].y);
Toshihiro Shimizu 890ddd
						params.m_styleId = F_work.array[i].color_id;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						TTileSaverCM32 tileSaver(ras, tileSet);
Toshihiro Shimizu 890ddd
						recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	free(prob_vector);
Toshihiro Shimizu 890ddd
	return recomputeBBox;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-- end of apply_fabrizio --------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/* Scansione delle aree di Fabrizio                                          */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void scan_fabri_regions(TRasterCM32P ras, struct s_fabri_region_list *rlst,
Toshihiro Shimizu 890ddd
							   int mode, int ex1, int ey1, int ex2, int ey2)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int firstfree;
Toshihiro Shimizu 890ddd
	TPixelCM32 *pix;
Toshihiro Shimizu 890ddd
	int xa, xb;
Toshihiro Shimizu 890ddd
	int xp, x, y, x1, y1, x2, y2, tmp;
Toshihiro Shimizu 890ddd
	int dx, dy, i, j, h, n, tone, maxtone;
Toshihiro Shimizu 890ddd
	int rold, rcur, nold, ncur;
Toshihiro Shimizu 890ddd
	int precedente;
Toshihiro Shimizu 890ddd
	struct s_segm *row[2];
Toshihiro Shimizu 890ddd
	int *ultima_zona;
Toshihiro Shimizu 890ddd
	int region_id, region_old, keep, discard, vicina;
Toshihiro Shimizu 890ddd
	bool border_tooX1, border_tooY1, border_tooX2, border_tooY2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	x1 = ex1;
Toshihiro Shimizu 890ddd
	x2 = ex2;
Toshihiro Shimizu 890ddd
	y1 = ey1;
Toshihiro Shimizu 890ddd
	y2 = ey2;
Toshihiro Shimizu 890ddd
	TRect rect = ras->getBounds();
Toshihiro Shimizu 890ddd
	border_tooX1 = x1 == rect.x0;
Toshihiro Shimizu 890ddd
	border_tooY1 = y1 == rect.y0;
Toshihiro Shimizu 890ddd
	border_tooX2 = x2 == rect.x1;
Toshihiro Shimizu 890ddd
	border_tooY2 = y2 == rect.y1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	dx = x2 - x1 + 1;
Toshihiro Shimizu 890ddd
	dy = y2 - y1 + 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rlst->lx = dx;
Toshihiro Shimizu 890ddd
	rlst->ly = dy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	row[0] = (struct s_segm *)calloc(dx, sizeof(struct s_segm));
Toshihiro Shimizu 890ddd
	row[1] = (struct s_segm *)calloc(dx, sizeof(struct s_segm));
Toshihiro Shimizu 890ddd
	ultima_zona = (int *)calloc(dx, sizeof(int));
Toshihiro Shimizu 890ddd
	rold = 1;
Toshihiro Shimizu 890ddd
	rcur = 0;
Toshihiro Shimizu 890ddd
	nold = ncur = 0;
Toshihiro Shimizu 890ddd
	vicina = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (tmp = 0; tmp < dx; tmp++)
Toshihiro Shimizu 890ddd
		ultima_zona[tmp] = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*.. Inizializza la struttura ...............................................*/
Toshihiro Shimizu 890ddd
	rlst->size = 100;
Toshihiro Shimizu 890ddd
	rlst->array = (struct s_fabri_region *)
Toshihiro Shimizu 890ddd
		calloc(rlst->size, sizeof(struct s_fabri_region));
Toshihiro Shimizu 890ddd
	rlst->n = 0;
Toshihiro Shimizu 890ddd
	firstfree = -1;
Toshihiro Shimizu 890ddd
	for (tmp = 0; tmp < rlst->size; tmp++) {
Toshihiro Shimizu 890ddd
		rlst->array[tmp].vicini = NULL;
Toshihiro Shimizu 890ddd
		rlst->array[tmp].holes = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/*...........................................................................*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (y = y1; y <= y2; y++) {
Toshihiro Shimizu 890ddd
		vicina = -1;
Toshihiro Shimizu 890ddd
		pix = ras->pixels(y) + x1;
Toshihiro Shimizu 890ddd
		x = x1;
Toshihiro Shimizu 890ddd
		PRINTF("Cerca Area \n");
Toshihiro Shimizu 890ddd
		while (x <= x2) {
Toshihiro Shimizu 890ddd
			while (x <= x2 && pix->getTone() < pix->getMaxTone()) {
Toshihiro Shimizu 890ddd
				pix++;
Toshihiro Shimizu 890ddd
				x++;
Toshihiro Shimizu 890ddd
			}			   /*cerca una area */
Toshihiro Shimizu 890ddd
			if (x <= x2) { /* non ho raggiunto il bordo */
Toshihiro Shimizu 890ddd
				PRINTF("Prima del Bordo \n");
Toshihiro Shimizu 890ddd
				xa = x;
Toshihiro Shimizu 890ddd
				maxtone = pix->getTone();
Toshihiro Shimizu 890ddd
				xp = x;
Toshihiro Shimizu 890ddd
				while (x <= x2 && pix->getTone() >= pix->getMaxTone()) {
Toshihiro Shimizu 890ddd
					tone = pix->getTone();
Toshihiro Shimizu 890ddd
					if (tone > maxtone) {
Toshihiro Shimizu 890ddd
						maxtone = tone;
Toshihiro Shimizu 890ddd
						xp = x;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					pix++;
Toshihiro Shimizu 890ddd
					x++;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				xb = x - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				PRINTF("Trovata Area \n");
Toshihiro Shimizu 890ddd
				region_id = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				for (j = 0; j < nold && row[rold][j].xa <= xb; j++) {
Toshihiro Shimizu 890ddd
					if (row[rold][j].xb >= xa && row[rold][j].xa <= xb) {
Toshihiro Shimizu 890ddd
						region_old = row[rold][j].region;
Toshihiro Shimizu 890ddd
						if (region_id == region_old)
Toshihiro Shimizu 890ddd
							rlst->array[region_id].holes++;
Toshihiro Shimizu 890ddd
						if (region_id < 0) {
Toshihiro Shimizu 890ddd
							region_id = region_old;
Toshihiro Shimizu 890ddd
							rlst->array[region_id].per += 2 * (xb - xa + 1) + 2 -
Toshihiro Shimizu 890ddd
														  2 * (MIN(row[rold][j].xb, xb) - MAX(row[rold][j].xa, xa) + 1);
Toshihiro Shimizu 890ddd
						} else if (region_id != region_old) {
Toshihiro Shimizu 890ddd
							/* CONTATTO FRA region_id E region_old */
Toshihiro Shimizu 890ddd
							PRINTF("Contatto tra %d e %d \n", region_id, region_old);
Toshihiro Shimizu 890ddd
							keep = region_old;
Toshihiro Shimizu 890ddd
							discard = region_id;
Toshihiro Shimizu 890ddd
							if (keep > discard) {
Toshihiro Shimizu 890ddd
								tmp = keep;
Toshihiro Shimizu 890ddd
								keep = discard;
Toshihiro Shimizu 890ddd
								discard = tmp;
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
							/*.. UNISCO LE DUE REGIONI..................... */
Toshihiro Shimizu 890ddd
							if (rlst->array[discard].x1 < rlst->array[keep].x1)
Toshihiro Shimizu 890ddd
								rlst->array[keep].x1 = rlst->array[discard].x1;
Toshihiro Shimizu 890ddd
							if (rlst->array[discard].y1 < rlst->array[keep].y1)
Toshihiro Shimizu 890ddd
								rlst->array[keep].y1 = rlst->array[discard].y1;
Toshihiro Shimizu 890ddd
							if (rlst->array[discard].x2 > rlst->array[keep].x2)
Toshihiro Shimizu 890ddd
								rlst->array[keep].x2 = rlst->array[discard].x2;
Toshihiro Shimizu 890ddd
							if (rlst->array[discard].y2 > rlst->array[keep].y2)
Toshihiro Shimizu 890ddd
								rlst->array[keep].y2 = rlst->array[discard].y2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
							rlst->array[keep].holes += rlst->array[discard].holes;
Toshihiro Shimizu 890ddd
							rlst->array[keep].npix += rlst->array[discard].npix;
Toshihiro Shimizu 890ddd
							rlst->array[keep].per += rlst->array[discard].per -
Toshihiro Shimizu 890ddd
													 2 * (MIN(row[rold][j].xb, xb) - MAX(row[rold][j].xa, xa) + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
							fondi(rlst, keep, discard);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
							ADD_BIG_BIG(rlst->array[keep].by, rlst->array[discard].by);
Toshihiro Shimizu 890ddd
							ADD_BIG_BIG(rlst->array[keep].bx, rlst->array[discard].bx);
Toshihiro Shimizu 890ddd
							ADD_BIG_BIG(rlst->array[keep].by2, rlst->array[discard].by2);
Toshihiro Shimizu 890ddd
							ADD_BIG_BIG(rlst->array[keep].bx2, rlst->array[discard].bx2);
Toshihiro Shimizu 890ddd
							if (rlst->array[keep].tone < rlst->array[discard].tone) {
Toshihiro Shimizu 890ddd
								rlst->array[keep].x = rlst->array[discard].x;
Toshihiro Shimizu 890ddd
								rlst->array[keep].y = rlst->array[discard].y;
Toshihiro Shimizu 890ddd
								rlst->array[keep].tone = rlst->array[discard].tone;
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
							/* OGNI RIFERIMENTO A 'discard' DIVENTA UN RIF.  A 'keep' */
Toshihiro Shimizu 890ddd
							for (h = 0; h < nold; h++)
Toshihiro Shimizu 890ddd
								if (row[rold][h].region == discard)
Toshihiro Shimizu 890ddd
									row[rold][h].region = keep;
Toshihiro Shimizu 890ddd
							for (h = 0; h < ncur; h++)
Toshihiro Shimizu 890ddd
								if (row[rcur][h].region == discard)
Toshihiro Shimizu 890ddd
									row[rcur][h].region = keep;
Toshihiro Shimizu 890ddd
							region_id = keep;
Toshihiro Shimizu 890ddd
							rinomina(discard, keep, rlst->n, rlst);
Toshihiro Shimizu 890ddd
							for (tmp = 0; tmp < dx; tmp++)
Toshihiro Shimizu 890ddd
								if (ultima_zona[tmp] == discard)
Toshihiro Shimizu 890ddd
									ultima_zona[tmp] = keep;
Toshihiro Shimizu 890ddd
							/* AGGIUNGO discard AL POOL DEI LIBERI */
Toshihiro Shimizu 890ddd
							rlst->array[discard].active = 0;
Toshihiro Shimizu 890ddd
							rlst->array[discard].nextfree = firstfree;
Toshihiro Shimizu 890ddd
							free_list(&rlst->array[discard].vicini);
Toshihiro Shimizu 890ddd
							rlst->array[discard].vicini = NULL;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
							firstfree = discard;
Toshihiro Shimizu 890ddd
						} /* end elseif */
Toshihiro Shimizu 890ddd
					}	 /* end of if */
Toshihiro Shimizu 890ddd
				}		  /* end of for */
Toshihiro Shimizu 890ddd
				PRINTF("Region ID %d %d %d %d \n", region_id, xa, xb, y);
Toshihiro Shimizu 890ddd
				PRINTF("Memorizza Area \n");
Toshihiro Shimizu 890ddd
				if (region_id >= 0) {
Toshihiro Shimizu 890ddd
					rlst->array[region_id].lxb = xb;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].lxa = xa;
Toshihiro Shimizu 890ddd
					if (xa < rlst->array[region_id].x1)
Toshihiro Shimizu 890ddd
						rlst->array[region_id].x1 = xa;
Toshihiro Shimizu 890ddd
					if (xb > rlst->array[region_id].x2)
Toshihiro Shimizu 890ddd
						rlst->array[region_id].x2 = xb;
Toshihiro Shimizu 890ddd
					if (y < rlst->array[region_id].y1)
Toshihiro Shimizu 890ddd
						rlst->array[region_id].y1 = y;
Toshihiro Shimizu 890ddd
					if (y > rlst->array[region_id].y2)
Toshihiro Shimizu 890ddd
						rlst->array[region_id].y2 = y;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].npix += xb - xa + 1;
Toshihiro Shimizu 890ddd
					ADD_BIG(rlst->array[region_id].by, (xb - xa + 1) * y);
Toshihiro Shimizu 890ddd
					ADD_BIG(rlst->array[region_id].bx, (xb - xa + 1) * (xb + xa) / 2);
Toshihiro Shimizu 890ddd
					ADD_BIG(rlst->array[region_id].by2, (xb - xa + 1) * y * y);
Toshihiro Shimizu 890ddd
					ADD_BIG(rlst->array[region_id].bx2, somma_quadrati(xa, xb));
Toshihiro Shimizu 890ddd
					if (rlst->array[region_id].tone < maxtone ||
Toshihiro Shimizu 890ddd
						(rlst->array[region_id].x2 - rlst->array[region_id].x1) < xb - xa) {
Toshihiro Shimizu 890ddd
						rlst->array[region_id].x = xp;
Toshihiro Shimizu 890ddd
						rlst->array[region_id].y = y;
Toshihiro Shimizu 890ddd
						rlst->array[region_id].tone = maxtone;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					/* CREO UNA NUOVA REGIONE */
Toshihiro Shimizu 890ddd
					if (firstfree < 0) {
Toshihiro Shimizu 890ddd
						if (rlst->n >= rlst->size) {
Toshihiro Shimizu 890ddd
							rlst->size += 50;
Toshihiro Shimizu 890ddd
							rlst->array = (struct s_fabri_region *)
Toshihiro Shimizu 890ddd
								realloc(rlst->array, rlst->size * sizeof(struct s_fabri_region));
Toshihiro Shimizu 890ddd
							for (tmp = rlst->size - 1; tmp >= rlst->size - 50; tmp--)
Toshihiro Shimizu 890ddd
								rlst->array[tmp].vicini = NULL;
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
						region_id = rlst->n++;
Toshihiro Shimizu 890ddd
					} else {
Toshihiro Shimizu 890ddd
						region_id = firstfree;
Toshihiro Shimizu 890ddd
						firstfree = rlst->array[region_id].nextfree;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					rlst->array[region_id].active = 1;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].vicini = NULL;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].nextfree = 0;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].x = xp;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].y = y;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].x1 = xa;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].y1 = y;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].x2 = xb;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].y2 = y;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].npix = xb - xa + 1;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].holes = 0;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].per = 2 * (xb - xa + 1) + 2;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].lxb = xb;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].lxa = xa;
Toshihiro Shimizu 890ddd
					ASS_BIG(rlst->array[region_id].by, (xb - xa + 1) * y);
Toshihiro Shimizu 890ddd
					ASS_BIG(rlst->array[region_id].bx, (xb - xa + 1) * (xb + xa) / 2);
Toshihiro Shimizu 890ddd
					ASS_BIG(rlst->array[region_id].by2, (xb - xa + 1) * y * y);
Toshihiro Shimizu 890ddd
					ASS_BIG(rlst->array[region_id].bx2, somma_quadrati(xa, xb));
Toshihiro Shimizu 890ddd
					rlst->array[region_id].tone = maxtone;
Toshihiro Shimizu 890ddd
					rlst->array[region_id].color_id = pix->getPaint();
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				/* MEMORIZZO LA REGIONE CORRENTE */
Toshihiro Shimizu 890ddd
				precedente = -1;
Toshihiro Shimizu 890ddd
				/*-----------------------------------------------------
Toshihiro Shimizu 890ddd
        .. Controlla se esiste vicinanza verticale ...........*/
Toshihiro Shimizu 890ddd
				for (tmp = xa; tmp <= xb; tmp++) {
Toshihiro Shimizu 890ddd
					if (ultima_zona[tmp - x1] != precedente) {
Toshihiro Shimizu 890ddd
						aggiungi(ultima_zona[tmp - x1], region_id, rlst);
Toshihiro Shimizu 890ddd
						precedente = ultima_zona[tmp - x1];
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					ultima_zona[tmp - x1] = region_id;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				/*-----------------------------------------------------*/
Toshihiro Shimizu 890ddd
				aggiungi(vicina, region_id, rlst);
Toshihiro Shimizu 890ddd
				vicina = region_id;
Toshihiro Shimizu 890ddd
				if (ncur >= dx - 1) {
Toshihiro Shimizu 890ddd
					printf("autofill: row overflow dx=%d\n", dx);
Toshihiro Shimizu 890ddd
					exit(1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				row[rcur][ncur].xa = xa;
Toshihiro Shimizu 890ddd
				row[rcur][ncur].xb = xb;
Toshihiro Shimizu 890ddd
				row[rcur][ncur].region = region_id;
Toshihiro Shimizu 890ddd
				ncur++;
Toshihiro Shimizu 890ddd
			} /* end of if#1 */
Toshihiro Shimizu 890ddd
		}	 /* end of while#1 */
Toshihiro Shimizu 890ddd
		rcur = 1 - rcur;
Toshihiro Shimizu 890ddd
		rold = 1 - rold;
Toshihiro Shimizu 890ddd
		nold = ncur;
Toshihiro Shimizu 890ddd
		ncur = 0;
Toshihiro Shimizu 890ddd
	} /* end of for#1 */
Toshihiro Shimizu 890ddd
	n = 0;
Toshihiro Shimizu 890ddd
	/* mostra_vicini(rlst); */
Toshihiro Shimizu 890ddd
	for (i = 0; i < rlst->n; i++)
Toshihiro Shimizu 890ddd
		if ((rlst->array[i].active) &&
Toshihiro Shimizu 890ddd
			((rlst->array[i].x1 > x1 || border_tooX1) &&
Toshihiro Shimizu 890ddd
			 (rlst->array[i].x2 < x2 || border_tooX2) &&
Toshihiro Shimizu 890ddd
			 (rlst->array[i].y1 > y1 || border_tooY1) &&
Toshihiro Shimizu 890ddd
			 (rlst->array[i].y2 < y2 || border_tooY2))) {
Toshihiro Shimizu 890ddd
			if (n < i) {
Toshihiro Shimizu 890ddd
				rlst->array[n] = rlst->array[i];
Toshihiro Shimizu 890ddd
				rlst->array[n].vicini = rlst->array[i].vicini;
Toshihiro Shimizu 890ddd
				rinomina(i, n, rlst->n, rlst);
Toshihiro Shimizu 890ddd
				for (tmp = 0; tmp < dx; tmp++)
Toshihiro Shimizu 890ddd
					if (ultima_zona[tmp] == i)
Toshihiro Shimizu 890ddd
						ultima_zona[tmp] = n;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			rlst->array[n].lx = rlst->array[n].x2 - rlst->array[n].x1 + 1;
Toshihiro Shimizu 890ddd
			rlst->array[n].ly = rlst->array[n].y2 - rlst->array[n].y1 + 1;
Toshihiro Shimizu 890ddd
			rlst->array[n].xm = (rlst->array[n].x2 + rlst->array[n].x1) / 2;
Toshihiro Shimizu 890ddd
			rlst->array[n].ym = (rlst->array[n].y2 + rlst->array[n].y1) / 2;
Toshihiro Shimizu 890ddd
			n++;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			rimuovi_tutti(i, rlst);
Toshihiro Shimizu 890ddd
	/* mostra_vicini(rlst); */
Toshihiro Shimizu 890ddd
	rlst->n = n;
Toshihiro Shimizu 890ddd
	free(row[0]);
Toshihiro Shimizu 890ddd
	free(row[1]);
Toshihiro Shimizu 890ddd
	free(ultima_zona);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*- end of scan_fabri_regions --------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Rinomina tutti i vicini regione1 in regione2                             */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void rinomina(int regione1, int regione2, int num_regioni,
Toshihiro Shimizu 890ddd
					 struct s_fabri_region_list *rlst)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct vicine *appo, *old, appo1;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	int trovato = FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PRINTF("Rinomino %d %d Regioni: %d \n", regione1, regione2, num_regioni);
Toshihiro Shimizu 890ddd
	/* mostra_vicini(rlst);  */
Toshihiro Shimizu 890ddd
	for (i = 0; i < num_regioni; i++)
Toshihiro Shimizu 890ddd
		if (rlst->array[i].active) {
Toshihiro Shimizu 890ddd
			trovato = ((i == regione2) || (i == regione1));
Toshihiro Shimizu 890ddd
			PRINTF(">> %d \n", i);
Toshihiro Shimizu 890ddd
			old = NULL;
Toshihiro Shimizu 890ddd
			appo = rlst->array[i].vicini;
Toshihiro Shimizu 890ddd
			while (appo != NULL) {
Toshihiro Shimizu 890ddd
				if ((appo->region_id == regione2) || (appo->region_id == regione1)) {
Toshihiro Shimizu 890ddd
					if (trovato)
Toshihiro Shimizu 890ddd
						if (old != NULL) {
Toshihiro Shimizu 890ddd
							PRINTF("A%d %d \n", i, appo->region_id);
Toshihiro Shimizu 890ddd
							old->next = appo->next;
Toshihiro Shimizu 890ddd
							free(appo);
Toshihiro Shimizu 890ddd
							appo = old->next;
Toshihiro Shimizu 890ddd
							/* mostra_vicini(rlst); */
Toshihiro Shimizu 890ddd
						} else {
Toshihiro Shimizu 890ddd
							PRINTF("B%d %d \n", i, appo->region_id);
Toshihiro Shimizu 890ddd
							rlst->array[i].vicini = appo->next;
Toshihiro Shimizu 890ddd
							appo1 = *appo;
Toshihiro Shimizu 890ddd
							free(appo);
Toshihiro Shimizu 890ddd
							appo = appo1.next;
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
					else /* non ho ancora trovato */
Toshihiro Shimizu 890ddd
					{
Toshihiro Shimizu 890ddd
						PRINTF("S%d \n", appo->region_id);
Toshihiro Shimizu 890ddd
						appo->region_id = regione2;
Toshihiro Shimizu 890ddd
						old = appo;
Toshihiro Shimizu 890ddd
						appo = appo->next;
Toshihiro Shimizu 890ddd
						trovato = TRUE;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				} else /* region_id non e' region2 o regione 1 */
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					PRINTF("D%d \n", appo->region_id);
Toshihiro Shimizu 890ddd
					old = appo;
Toshihiro Shimizu 890ddd
					appo = appo->next;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	PRINTF("Rinomino %d %d\n", regione1, regione2);
Toshihiro Shimizu 890ddd
	/*   mostra_vicini(rlst);  */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- end of rinomina ---------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/* Aggiunge a regione2 il vicino regione1 e viceversa                        */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void aggiungi(int regione1, int regione2,
Toshihiro Shimizu 890ddd
					 struct s_fabri_region_list *rlst)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct vicine *appo1, *appo2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*  if((regione1==0)||(regione2==0)) */
Toshihiro Shimizu 890ddd
	PRINTF("Aggiungo %d a %d\n", regione1, regione2);
Toshihiro Shimizu 890ddd
	if ((regione1 != -1) && (regione2 != -1) && (regione2 != regione1)) {
Toshihiro Shimizu 890ddd
		if (rlst->array[regione1].active) {
Toshihiro Shimizu 890ddd
			appo1 = rlst->array[regione1].vicini;
Toshihiro Shimizu 890ddd
			while ((appo1 != NULL) && (appo1->region_id != regione2))
Toshihiro Shimizu 890ddd
				appo1 = appo1->next;
Toshihiro Shimizu 890ddd
			if (appo1 == NULL) {
Toshihiro Shimizu 890ddd
				appo1 = (struct vicine *)calloc(1, sizeof(struct vicine));
Toshihiro Shimizu 890ddd
				appo1->next = rlst->array[regione1].vicini;
Toshihiro Shimizu 890ddd
				appo1->region_id = regione2;
Toshihiro Shimizu 890ddd
				rlst->array[regione1].vicini = appo1;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (rlst->array[regione2].active) {
Toshihiro Shimizu 890ddd
			appo2 = rlst->array[regione2].vicini;
Toshihiro Shimizu 890ddd
			while ((appo2 != NULL) && (appo2->region_id != regione1))
Toshihiro Shimizu 890ddd
				appo2 = appo2->next;
Toshihiro Shimizu 890ddd
			if (appo2 == NULL) {
Toshihiro Shimizu 890ddd
				appo2 = (struct vicine *)calloc(1, sizeof(struct vicine));
Toshihiro Shimizu 890ddd
				appo2->next = rlst->array[regione2].vicini;
Toshihiro Shimizu 890ddd
				appo2->region_id = regione1;
Toshihiro Shimizu 890ddd
				rlst->array[regione2].vicini = appo2;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	PRINTF("Aggiunto %d a %d\n", regione1, regione2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- end of aggiungi ---------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Aggiunge i vicini di r2 a quelli di r1                                   */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void fondi(struct s_fabri_region_list *rlst, int r1, int r2)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct vicine *appo1, *appo2, *appo3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PRINTF("Fondi %d %d \n", r1, r2);
Toshihiro Shimizu 890ddd
	/* mostra_vicini(rlst); */
Toshihiro Shimizu 890ddd
	appo2 = rlst->array[r2].vicini;
Toshihiro Shimizu 890ddd
	while (appo2 != NULL) {
Toshihiro Shimizu 890ddd
		appo1 = rlst->array[r1].vicini;
Toshihiro Shimizu 890ddd
		while ((appo1 != NULL) && (appo1->region_id != appo2->region_id) &&
Toshihiro Shimizu 890ddd
			   (appo2->region_id != r1))
Toshihiro Shimizu 890ddd
			appo1 = appo1->next;
Toshihiro Shimizu 890ddd
		if (appo1 == NULL) {
Toshihiro Shimizu 890ddd
			appo3 = (struct vicine *)calloc(1, sizeof(struct vicine));
Toshihiro Shimizu 890ddd
			appo3->next = rlst->array[r1].vicini;
Toshihiro Shimizu 890ddd
			appo3->region_id = appo2->region_id;
Toshihiro Shimizu 890ddd
			rlst->array[r1].vicini = appo3;
Toshihiro Shimizu 890ddd
			appo2 = appo2->next;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			appo2 = appo2->next;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	PRINTF("Fuso %d %d \n", r1, r2);
Toshihiro Shimizu 890ddd
	/* mostra_vicini(rlst); */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- end of fondi ------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Mostra i vicini di ogni regione                                          */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void mostra_vicini(struct s_fabri_region_list *rlst)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	struct vicine *appo;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < rlst->n; i++)
Toshihiro Shimizu 890ddd
		if (rlst->array[i].active) {
Toshihiro Shimizu 890ddd
			PRINTF("Region: %d ::", i);
Toshihiro Shimizu 890ddd
			appo = rlst->array[i].vicini;
Toshihiro Shimizu 890ddd
			while (appo != NULL) {
Toshihiro Shimizu 890ddd
				PRINTF("%d ", appo->region_id);
Toshihiro Shimizu 890ddd
				appo = appo->next;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			PRINTF("\n");
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			PRINTF("Region: %d inactive \n", i);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- end of mostra_vicini ----------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Rimuove r1 come vicino in ogni regione                                   */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void rimuovi_tutti(int r1, struct s_fabri_region_list *rlst)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct vicine *appo, *old;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PRINTF("Elimino %d \n", r1);
Toshihiro Shimizu 890ddd
	/* mostra_vicini(rlst);  */
Toshihiro Shimizu 890ddd
	for (i = 0; i < rlst->n; i++)
Toshihiro Shimizu 890ddd
		if (rlst->array[i].active) {
Toshihiro Shimizu 890ddd
			PRINTF(">> %d \n", i);
Toshihiro Shimizu 890ddd
			old = NULL;
Toshihiro Shimizu 890ddd
			appo = rlst->array[i].vicini;
Toshihiro Shimizu 890ddd
			while (appo != NULL) {
Toshihiro Shimizu 890ddd
				if (appo->region_id == r1) {
Toshihiro Shimizu 890ddd
					PRINTF("A%d %d\n", appo->region_id, old->region_id);
Toshihiro Shimizu 890ddd
					if (old != NULL) {
Toshihiro Shimizu 890ddd
						old->next = appo->next;
Toshihiro Shimizu 890ddd
						/* free(appo); */
Toshihiro Shimizu 890ddd
						appo = old->next;
Toshihiro Shimizu 890ddd
						/* mostra_vicini(rlst); */
Toshihiro Shimizu 890ddd
					} else {
Toshihiro Shimizu 890ddd
						rlst->array[i].vicini = appo->next;
Toshihiro Shimizu 890ddd
						/* free(appo); */
Toshihiro Shimizu 890ddd
						appo = rlst->array[i].vicini;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				} else /* region_id non e' region2 o regione 1 */
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					PRINTF("D%d \n", appo->region_id);
Toshihiro Shimizu 890ddd
					old = appo;
Toshihiro Shimizu 890ddd
					appo = appo->next;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	/*  mostra_vicini(rlst); */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- end of rimuovi_tutti ----------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Assegna la probabilita' di transizione i->j    (3)                       */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void assign_prob3(int prob[], int i, int j)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double delta_posx1, delta_posy1, delta_posx2, delta_posy2;
Toshihiro Shimizu 890ddd
	double delta_momx1, delta_momy1, delta_momx2, delta_momy2;
Toshihiro Shimizu 890ddd
	int delta_pix, delta_pix_max;
Toshihiro Shimizu 890ddd
	double delta_pos, delta_pos_max, delta_forma_mom;
Toshihiro Shimizu 890ddd
	int delta_forma1, delta_forma2, delta_forma;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_posx1 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_reference.array[i].bx) / F_reference.array[i].npix -
Toshihiro Shimizu 890ddd
		F_ref_bx;
Toshihiro Shimizu 890ddd
	delta_posy1 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_reference.array[i].by) / F_reference.array[i].npix -
Toshihiro Shimizu 890ddd
		F_ref_by;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_posx2 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_work.array[j].bx) / F_work.array[j].npix -
Toshihiro Shimizu 890ddd
		F_wor_bx;
Toshihiro Shimizu 890ddd
	delta_posy2 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_work.array[j].by) / F_work.array[j].npix -
Toshihiro Shimizu 890ddd
		F_wor_by;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* Cosi' calcolo il modulo della differenza */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_pos =
Toshihiro Shimizu 890ddd
		sqrt((delta_posx2 - delta_posx1) * (delta_posx2 - delta_posx1) +
Toshihiro Shimizu 890ddd
			 (delta_posy2 - delta_posy1) * (delta_posy2 - delta_posy1));
Toshihiro Shimizu 890ddd
	delta_pos_max =
Toshihiro Shimizu 890ddd
		sqrt((double)(F_work.lx * F_work.lx + F_work.ly * F_work.ly));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	prob[i + j * F_reference.n] =
Toshihiro Shimizu 890ddd
		ROUNDP(1000 * (1 -
Toshihiro Shimizu 890ddd
					   (delta_pos / delta_pos_max)));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_pix = abs(F_reference.array[i].npix - F_work.array[j].npix);
Toshihiro Shimizu 890ddd
	delta_pix_max = MAX((F_work.lx * F_work.ly), (F_reference.lx * F_reference.ly));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	prob[(F_work.n * F_reference.n) + i + (j * F_reference.n)] =
Toshihiro Shimizu 890ddd
		ROUNDP(1000 * (1 - ((double)delta_pix /
Toshihiro Shimizu 890ddd
							(F_reference.array[i].npix + F_work.array[j].npix))));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_momx1 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_reference.array[i].bx2) / F_reference.array[i].npix -
Toshihiro Shimizu 890ddd
		(BIG_TO_DOUBLE(F_reference.array[i].bx) / F_reference.array[i].npix *
Toshihiro Shimizu 890ddd
		 BIG_TO_DOUBLE(F_reference.array[i].bx) / F_reference.array[i].npix);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_momy1 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_reference.array[i].by2) / F_reference.array[i].npix -
Toshihiro Shimizu 890ddd
		(BIG_TO_DOUBLE(F_reference.array[i].by) / F_reference.array[i].npix *
Toshihiro Shimizu 890ddd
		 BIG_TO_DOUBLE(F_reference.array[i].by) / F_reference.array[i].npix);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_momx2 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_work.array[j].bx2) / F_work.array[j].npix -
Toshihiro Shimizu 890ddd
		(BIG_TO_DOUBLE(F_work.array[j].bx) / F_work.array[j].npix *
Toshihiro Shimizu 890ddd
		 BIG_TO_DOUBLE(F_work.array[j].bx) / F_work.array[j].npix);
Toshihiro Shimizu 890ddd
	delta_momy2 =
Toshihiro Shimizu 890ddd
		BIG_TO_DOUBLE(F_work.array[j].by2) / F_work.array[j].npix -
Toshihiro Shimizu 890ddd
		(BIG_TO_DOUBLE(F_work.array[j].by) / F_work.array[j].npix *
Toshihiro Shimizu 890ddd
		 BIG_TO_DOUBLE(F_work.array[j].by) / F_work.array[j].npix);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_forma_mom =
Toshihiro Shimizu 890ddd
		abs(sqrt(delta_momx1 + delta_momy1) -
Toshihiro Shimizu 890ddd
			sqrt(delta_momx2 + delta_momy2));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_forma1 = ROUNDP(1000 * (((double)F_reference.array[i].per / F_reference.array[i].npix -
Toshihiro Shimizu 890ddd
								   2 / sqrt((double)F_reference.array[i].npix / 3.14)) /
Toshihiro Shimizu 890ddd
								  (2 - 2 / sqrt((double)F_reference.array[i].npix / 3.14))));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_forma2 = ROUNDP(1000 * (((double)F_work.array[j].per / F_work.array[j].npix -
Toshihiro Shimizu 890ddd
								   2 / sqrt((double)F_work.array[j].npix / 3.14)) /
Toshihiro Shimizu 890ddd
								  (2 - 2 / sqrt((double)F_work.array[j].npix / 3.14))));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_forma =
Toshihiro Shimizu 890ddd
		ROUNDP(1000 * (1 -
Toshihiro Shimizu 890ddd
					   (delta_forma_mom / delta_pos_max)));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	prob[(2 * F_work.n * F_reference.n) + i + (j * F_reference.n)] = delta_forma;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Dx_f += ROUNDP(sqrt(delta_posx1 * delta_posx1 + delta_posy1 * delta_posy1));
Toshihiro Shimizu 890ddd
	DP_f += F_reference.array[i].npix;
Toshihiro Shimizu 890ddd
	Df_f += ROUNDP(sqrt(delta_momx1 * delta_momx1 + delta_momy1 * delta_momy1));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Dx_t += ROUNDP(sqrt(delta_posx2 * delta_posx2 + delta_posy2 * delta_posy2));
Toshihiro Shimizu 890ddd
	DP_t += F_work.array[j].npix;
Toshihiro Shimizu 890ddd
	Df_t += ROUNDP(sqrt(delta_momx2 * delta_momx2 + delta_momy2 * delta_momy2));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*- end of assign_prob ------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Trova il colore migliore per una regione                                 */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void find_best(int prob[], int *col, int to)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float att_max = 0.0;
Toshihiro Shimizu 890ddd
	int i, j, numero;
Toshihiro Shimizu 890ddd
	float color_value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < F_reference.n; i++) {
Toshihiro Shimizu 890ddd
		color_value = 0.0;
Toshihiro Shimizu 890ddd
		numero = 0;
Toshihiro Shimizu 890ddd
		for (j = 0; j < F_reference.n; j++) {
Toshihiro Shimizu 890ddd
			if (F_reference.array[i].color_id == F_reference.array[j].color_id) {
Toshihiro Shimizu 890ddd
				color_value += (prob[to * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
							   (prob[to * F_reference.n + j] / 1000.0) *
Toshihiro Shimizu 890ddd
							   /*   (prob[(F_work.n*F_reference.n)+to*F_reference.n+j]/1500.0)*
Toshihiro Shimizu 890ddd
             */ (prob[2 * (F_work.n * F_reference.n) + to * F_reference.n + j] / 1500.0);
Toshihiro Shimizu 890ddd
				numero++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if ((color_value / numero) > att_max) {
Toshihiro Shimizu 890ddd
			att_max = color_value / numero;
Toshihiro Shimizu 890ddd
			PRINTF("Nuovo Massimo %f \n", att_max);
Toshihiro Shimizu 890ddd
			*col = F_reference.array[i].color_id;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*- end of find_best --------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  libera la memoria occupata da una lista                                  */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static void free_list(struct vicine **vic)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (*vic != NULL) {
Toshihiro Shimizu 890ddd
		free_list(&(*vic)->next);
Toshihiro Shimizu 890ddd
		free(*vic);
Toshihiro Shimizu 890ddd
		*vic = NULL;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*- end of free_list --------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Somma il quadrato dei numeri da x a y o viceversa                        */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static int somma_quadrati(int x, int y)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int somma = 0;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = MIN(x, y); i <= MAX(x, y); i++)
Toshihiro Shimizu 890ddd
		somma += i * i;
Toshihiro Shimizu 890ddd
	return somma;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*- end of somma_quadrati ---------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*  Scegli il punto da cui proseguire l'accoppiamento                        */
Toshihiro Shimizu 890ddd
/*...........................................................................*/
Toshihiro Shimizu 890ddd
static int trova_migliore_padre(int prob_vector[], int *att_my)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int att_best, att_second, att_max_diff = 0;
Toshihiro Shimizu 890ddd
	int att_choice = -1, i, j, k;
Toshihiro Shimizu 890ddd
	struct vicine *a1, *a2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PRINTF("Inizio Ricerca del Padre \n");
Toshihiro Shimizu 890ddd
	for (k = 0; k < F_reference.n; k++)
Toshihiro Shimizu 890ddd
		if (F_reference.array[k].match >= 0) {
Toshihiro Shimizu 890ddd
			PRINTF("%d Gia' Accoppiato\n", k);
Toshihiro Shimizu 890ddd
			a1 = F_reference.array[k].vicini;
Toshihiro Shimizu 890ddd
			while (a1 != NULL) {
Toshihiro Shimizu 890ddd
				i = a1->region_id;
Toshihiro Shimizu 890ddd
				if (F_reference.array[i].match < 0) {
Toshihiro Shimizu 890ddd
					PRINTF("%d vicino di %d Non Accoppiato\n", i, k);
Toshihiro Shimizu 890ddd
					a2 = F_work.array[F_reference.array[k].match].vicini;
Toshihiro Shimizu 890ddd
					att_best = 0;
Toshihiro Shimizu 890ddd
					att_second = 0;
Toshihiro Shimizu 890ddd
					while (a2 != NULL) {
Toshihiro Shimizu 890ddd
						PRINTF("Coppia %d %d \n", i, j);
Toshihiro Shimizu 890ddd
						j = a2->region_id;
Toshihiro Shimizu 890ddd
						if (F_work.array[j].match < 0) {
Toshihiro Shimizu 890ddd
							if (prob_vector[j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
									prob_vector[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
									prob_vector[2 * (F_work.n * F_reference.n) + j * F_reference.n + i] >
Toshihiro Shimizu 890ddd
								att_second)
Toshihiro Shimizu 890ddd
								att_second = prob_vector[j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
											 prob_vector[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
											 prob_vector[2 * (F_work.n * F_reference.n) + j * F_reference.n + i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
							if (prob_vector[j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
									prob_vector[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
									prob_vector[2 * (F_work.n * F_reference.n) + j * F_reference.n + i] >
Toshihiro Shimizu 890ddd
								att_best) {
Toshihiro Shimizu 890ddd
								att_second = att_best;
Toshihiro Shimizu 890ddd
								att_best = prob_vector[j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
										   prob_vector[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
										   prob_vector[2 * (F_work.n * F_reference.n) + j * F_reference.n + i];
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
						a2 = a2->next;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					if ((att_best - att_second) > att_max_diff) {
Toshihiro Shimizu 890ddd
						att_max_diff = att_best - att_second;
Toshihiro Shimizu 890ddd
						att_choice = F_reference.array[k].match;
Toshihiro Shimizu 890ddd
						*att_my = i;
Toshihiro Shimizu 890ddd
						PRINTF("Nuovo Coeff.: %d \n", att_max_diff);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				a1 = a1->next;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	PRINTF("Finita Ricerca del Padre \n");
Toshihiro Shimizu 890ddd
	return att_choice;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int match(int prob[], int padre, int *fro, int *to)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int att_max = 0, i, j;
Toshihiro Shimizu 890ddd
	struct vicine *a2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (padre > -1) {
Toshihiro Shimizu 890ddd
		a2 = F_work.array[padre].vicini;
Toshihiro Shimizu 890ddd
		while (a2 != NULL) {
Toshihiro Shimizu 890ddd
			j = a2->region_id;
Toshihiro Shimizu 890ddd
			if ((F_work.array[j].match < 0) &&
Toshihiro Shimizu 890ddd
				(prob[j * F_reference.n + (*fro)] *
Toshihiro Shimizu 890ddd
					 prob[(F_work.n * F_reference.n) + j * F_reference.n + (*fro)] *
Toshihiro Shimizu 890ddd
					 prob[2 * (F_work.n * F_reference.n) + j * F_reference.n + (*fro)] >
Toshihiro Shimizu 890ddd
				 att_max)) {
Toshihiro Shimizu 890ddd
				att_max = prob[j * F_reference.n + (*fro)] *
Toshihiro Shimizu 890ddd
						  prob[(F_work.n * F_reference.n) + j * F_reference.n + (*fro)] *
Toshihiro Shimizu 890ddd
						  prob[2 * (F_work.n * F_reference.n) + j * F_reference.n + (*fro)];
Toshihiro Shimizu 890ddd
				*to = j;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			a2 = a2->next;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		for (i = 0; i < F_reference.n; i++)
Toshihiro Shimizu 890ddd
			for (j = 0; j < F_work.n; j++)
Toshihiro Shimizu 890ddd
				if (
Toshihiro Shimizu 890ddd
					(F_work.array[j].match < 0) &&
Toshihiro Shimizu 890ddd
					(F_reference.array[i].match < 0) &&
Toshihiro Shimizu 890ddd
					(F_work.array[j].npix > DIM_TRESH * F_work.lx * F_work.ly) &&
Toshihiro Shimizu 890ddd
					(F_reference.array[i].npix > DIM_TRESH * F_reference.lx * F_reference.ly)) {
Toshihiro Shimizu 890ddd
					if (
Toshihiro Shimizu 890ddd
						prob[j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
							prob[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
							prob[2 * (F_work.n * F_reference.n) + j * F_reference.n + i] >
Toshihiro Shimizu 890ddd
						att_max) {
Toshihiro Shimizu 890ddd
						att_max = prob[j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
								  prob[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Toshihiro Shimizu 890ddd
								  prob[2 * (F_work.n * F_reference.n) + j * F_reference.n + i];
Toshihiro Shimizu 890ddd
						*fro = i;
Toshihiro Shimizu 890ddd
						*to = j;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return att_max;
Toshihiro Shimizu 890ddd
}