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 {
Shinya Kitaoka 120a6e
  int xa, xb, region;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
typedef struct big { UINT lo, hi; } BIG;
Shinya Kitaoka 120a6e
#define ADD_BIG(B, X)                                                          \
Shinya Kitaoka 120a6e
  ((B).lo += (UINT)(X), (B).hi += (B).lo >> 30, (B).lo &= 0x3fffffff, (B))
Shinya Kitaoka 120a6e
#define ASS_BIG(B, X)                                                          \
Shinya Kitaoka 120a6e
  ((B).lo = (UINT)(X), (B).hi = (B).lo >> 30, (B).lo &= 0x3fffffff, (B))
Shinya Kitaoka 120a6e
#define ADD_BIG_BIG(B1, B2)                                                    \
Shinya Kitaoka 120a6e
  ((B1).lo += (B2).lo, (B1).hi += (B2).hi, (B1).hi += (B1).lo >> 30,           \
Shinya Kitaoka 120a6e
   (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 {
Shinya Kitaoka 120a6e
  int region_id;
Shinya Kitaoka 120a6e
  struct vicine *next;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct s_fabri_region {
Shinya Kitaoka 120a6e
  int active, nextfree, x, y, x1, y1, x2, y2, lx, ly, xm, ym, npix, lxa, lxb,
Shinya Kitaoka 120a6e
      tone, color_id, per, holes, match;
Shinya Kitaoka 120a6e
  BIG bx, by;
Shinya Kitaoka 120a6e
  BIG bx2, by2;
Shinya Kitaoka 120a6e
  struct vicine *vicini;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct s_fabri_region_list {
Shinya Kitaoka 120a6e
  struct s_fabri_region *array;
Shinya Kitaoka 120a6e
  int size, n, lx, ly;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static struct s_fabri_region_list F_reference = {0, 0, 0}, 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
Shinya Kitaoka 120a6e
static void scan_fabri_regions(TRasterCM32P ras,
Shinya Kitaoka 120a6e
                               struct s_fabri_region_list *rlst, int mode,
Shinya Kitaoka 120a6e
                               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
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
void rect_autofill_learn(const TToonzImageP &imgToLearn, int x1, int y1, int x2,
Shinya Kitaoka 120a6e
                         int y2)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  double pbx, pby;
Shinya Kitaoka 120a6e
  double abx, aby;
Shinya Kitaoka 120a6e
  int tot_pix = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if ((x2 - x1) * (y2 - y1) < MIN_SIZE) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pbx = pby = 0.0;
Shinya Kitaoka 120a6e
  abx = aby = 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P ras = imgToLearn->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (F_reference.array) {
Shinya Kitaoka 120a6e
    for (i = 0; i < F_reference.n; i++) free_list(&F_reference.array[i].vicini);
Shinya Kitaoka 120a6e
    free(F_reference.array);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  F_reference.array = 0;
Shinya Kitaoka 120a6e
  F_reference.size  = 0;
Shinya Kitaoka 120a6e
  F_reference.n     = 0;
Shinya Kitaoka 120a6e
  F_reference.lx    = 0;
Shinya Kitaoka 120a6e
  F_reference.ly    = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  scan_fabri_regions(ras, &F_reference, 1, x1, y1, x2, y2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n; i++) {
Shinya Kitaoka 120a6e
    F_reference.array[i].match = -1;
Shinya Kitaoka 120a6e
    F_reference.array[i].color_id =
Shinya Kitaoka 120a6e
        ras->pixels(F_reference.array[i].y)[F_reference.array[i].x].getPaint();
Shinya Kitaoka 120a6e
    pbx += BIG_TO_DOUBLE(F_reference.array[i].bx);
Shinya Kitaoka 120a6e
    pby += BIG_TO_DOUBLE(F_reference.array[i].by);
Shinya Kitaoka 120a6e
    abx = BIG_TO_DOUBLE(F_reference.array[i].bx);
Shinya Kitaoka 120a6e
    aby = BIG_TO_DOUBLE(F_reference.array[i].by);
Shinya Kitaoka 120a6e
    tot_pix += F_reference.array[i].npix;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (tot_pix) {
Shinya Kitaoka 120a6e
    F_ref_bx = pbx / tot_pix;
Shinya Kitaoka 120a6e
    F_ref_by = pby / tot_pix;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    F_ref_bx = 0;
Shinya Kitaoka 120a6e
    F_ref_by = 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*----------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
bool rect_autofill_apply(const TToonzImageP &imgToApply, int x1, int y1, int x2,
Shinya Kitaoka 120a6e
                         int y2, bool selective, TTileSetCM32 *tileSet)
Toshihiro Shimizu 890ddd
/*----------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  double pbx, pby;
Shinya Kitaoka 120a6e
  double abx, aby;
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int tot_pix = 0;
Shinya Kitaoka 120a6e
  int *prob_vector;
Shinya Kitaoka 120a6e
  int fro, to;
Shinya Kitaoka 120a6e
  int col;
Shinya Kitaoka 120a6e
  int valore;
Shinya Kitaoka 120a6e
  int padre;
Shinya Kitaoka 120a6e
  // int temp_prob, att_match;
Shinya Kitaoka 120a6e
  TRasterCM32P ras = imgToApply->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if ((x2 - x1) * (y2 - y1) < MIN_SIZE) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (F_reference.n <= 0 || F_reference.array == 0) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pbx = pby = 0.0;
Shinya Kitaoka 120a6e
  abx = aby = 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* Resetta gli eventuali accoppiamenti fatti precedentemente */
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n; i++) F_reference.array[i].match = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (F_work.array) {
Shinya Kitaoka 120a6e
    for (i = 0; i < F_work.n; i++) free_list(&F_work.array[i].vicini);
Shinya Kitaoka 120a6e
    free(F_work.array);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  F_work.array = 0;
Shinya Kitaoka 120a6e
  F_work.size  = 0;
Shinya Kitaoka 120a6e
  F_work.n     = 0;
Shinya Kitaoka 120a6e
  F_work.lx    = 0;
Shinya Kitaoka 120a6e
  F_work.ly    = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  scan_fabri_regions(ras, &F_work, 1, x1, y1, x2, y2);
Shinya Kitaoka 120a6e
  if (F_work.n <= 0 || F_work.array == 0) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (abs(F_work.lx * F_work.ly - F_reference.lx * F_reference.ly) >
Shinya Kitaoka 120a6e
      0.1 * (F_work.lx * F_work.ly + F_reference.lx * F_reference.ly))
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < F_work.n; i++) {
Shinya Kitaoka 120a6e
    F_work.array[i].match = -1;
Shinya Kitaoka 120a6e
    pbx += BIG_TO_DOUBLE(F_work.array[i].bx);
Shinya Kitaoka 120a6e
    pby += BIG_TO_DOUBLE(F_work.array[i].by);
Shinya Kitaoka 120a6e
    abx = BIG_TO_DOUBLE(F_work.array[i].bx);
Shinya Kitaoka 120a6e
    aby = BIG_TO_DOUBLE(F_work.array[i].by);
Shinya Kitaoka 120a6e
    tot_pix += F_work.array[i].npix;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  F_wor_bx = pbx / tot_pix;
Shinya Kitaoka 120a6e
  F_wor_by = pby / tot_pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  prob_vector = (int *)calloc(3 * F_work.n * F_reference.n, sizeof(int));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n; i++)
Shinya Kitaoka 120a6e
    for (j = 0; j < F_work.n; j++) assign_prob3(prob_vector, i, j);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Dx_f = Dx_f / F_reference.n;
Shinya Kitaoka 120a6e
  DP_f = DP_f / F_reference.n;
Shinya Kitaoka 120a6e
  Df_f = Df_f / F_reference.n;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Dx_t = Dx_t / F_work.n;
Shinya Kitaoka 120a6e
  DP_t = DP_t / F_work.n;
Shinya Kitaoka 120a6e
  Df_t = Df_t / F_work.n;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef SELECTIVE
Shinya Kitaoka 120a6e
  if (selective) {
Shinya Kitaoka 120a6e
    // Accoppia non trasparenti
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = 0; i < F_work.n; i++)
Shinya Kitaoka 120a6e
      if (F_work.array[i].color_id != 0) {
Shinya Kitaoka 120a6e
        temp_prob = 0;
Shinya Kitaoka 120a6e
        att_match = F_reference.n;
Shinya Kitaoka 120a6e
        /* Se non verra' aggiornato in seguito non verra' *
Shinya Kitaoka 120a6e
* comunque piu' cambiato di colore               */
Shinya Kitaoka 120a6e
        for (j = 0; j < F_reference.n; j++)
Shinya Kitaoka 120a6e
          if ((F_reference.array[i].match < 0) &&
Shinya Kitaoka 120a6e
              ((prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                   (prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                   (prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                i * F_reference.n + j] /
Shinya Kitaoka 120a6e
                    1500.0) >
Shinya Kitaoka 120a6e
               temp_prob)) {
Shinya Kitaoka 120a6e
            att_match = j;
Shinya Kitaoka 120a6e
            temp_prob = (prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                        (prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                        (prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                     i * F_reference.n + j] /
Shinya Kitaoka 120a6e
                         1500.0);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        F_work.array[i].match = att_match;
Shinya Kitaoka 120a6e
        if (att_match < F_reference.n) F_reference.array[att_match].match = i;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*--------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool recomputeBBox = false;
Shinya Kitaoka 120a6e
  FillParameters params;
Shinya Kitaoka 120a6e
  params.m_emptyOnly = selective;
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n && i < F_work.n; i++) {
Shinya Kitaoka 120a6e
    padre  = trova_migliore_padre(prob_vector, &fro);
Shinya Kitaoka 120a6e
    valore = match(prob_vector, padre, &fro, &to);
Shinya Kitaoka 120a6e
    if (valore > AMB_TRESH) {
Shinya Kitaoka 120a6e
      F_work.array[to].match       = fro;
Shinya Kitaoka 120a6e
      F_reference.array[fro].match = to;
Shinya Kitaoka 120a6e
      F_work.array[to].color_id    = F_reference.array[fro].color_id;
Shinya Kitaoka 120a6e
      if ((F_work.array[to].color_id != 0) && (valore != 0)) {
Shinya Kitaoka 120a6e
        params.m_p       = TPoint(F_work.array[to].x, F_work.array[to].y);
Shinya Kitaoka 120a6e
        params.m_styleId = F_work.array[to].color_id;
Shinya Kitaoka 120a6e
        TTileSaverCM32 tileSaver(ras, tileSet);
Shinya Kitaoka 120a6e
        recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*..........................................................................*/
Shinya Kitaoka 120a6e
  /* Matching basato sulla probabilita' di colore                             */
Shinya Kitaoka 120a6e
  /*..........................................................................*/
Shinya Kitaoka 120a6e
  if (FALSE) {
Shinya Kitaoka 120a6e
    bool recomputeBBox = false;
Shinya Kitaoka 120a6e
    for (i = 0; i < F_work.n; i++) {
Shinya Kitaoka 120a6e
      if (F_work.array[i].match < 0) {
Shinya Kitaoka 120a6e
        find_best(prob_vector, &col, i);
Shinya Kitaoka 120a6e
        F_work.array[i].match    = 1;
Shinya Kitaoka 120a6e
        F_work.array[i].color_id = col;
Shinya Kitaoka 120a6e
        if (F_work.array[i].color_id != 0) {
Shinya Kitaoka 120a6e
          params.m_p       = TPoint(F_work.array[i].x, F_work.array[i].y);
Shinya Kitaoka 120a6e
          params.m_styleId = F_work.array[i].color_id;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          TTileSaverCM32 tileSaver(ras, tileSet);
Shinya Kitaoka 120a6e
          recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  free(prob_vector);
Shinya Kitaoka 120a6e
  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
{
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  double pbx, pby;
Shinya Kitaoka 120a6e
  double abx, aby;
Shinya Kitaoka 120a6e
  int tot_pix = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pbx = pby = 0.0;
Shinya Kitaoka 120a6e
  abx = aby = 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P ras = imgToLearn->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (F_reference.array) {
Shinya Kitaoka 120a6e
    for (i = 0; i < F_reference.n; i++) free_list(&F_reference.array[i].vicini);
Shinya Kitaoka 120a6e
    free(F_reference.array);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  F_reference.array = 0;
Shinya Kitaoka 120a6e
  F_reference.size  = 0;
Shinya Kitaoka 120a6e
  F_reference.n     = 0;
Shinya Kitaoka 120a6e
  F_reference.lx    = 0;
Shinya Kitaoka 120a6e
  F_reference.ly    = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  scan_fabri_regions(ras, &F_reference, 0, 0, 0, 0, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n; i++) {
Shinya Kitaoka 120a6e
    F_reference.array[i].match = -1;
Shinya Kitaoka 120a6e
    F_reference.array[i].color_id =
Shinya Kitaoka 120a6e
        ras->pixels(F_reference.array[i].y)[F_reference.array[i].y].getPaint();
Shinya Kitaoka 120a6e
    pbx += BIG_TO_DOUBLE(F_reference.array[i].bx);
Shinya Kitaoka 120a6e
    pby += BIG_TO_DOUBLE(F_reference.array[i].by);
Shinya Kitaoka 120a6e
    abx = BIG_TO_DOUBLE(F_reference.array[i].bx);
Shinya Kitaoka 120a6e
    aby = BIG_TO_DOUBLE(F_reference.array[i].by);
Shinya Kitaoka 120a6e
    tot_pix += F_reference.array[i].npix;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  F_ref_bx = pbx / tot_pix;
Shinya Kitaoka 120a6e
  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
/*...........................................................................*/
Shinya Kitaoka 120a6e
bool autofill_apply(const TToonzImageP &imgToApply, bool selective,
Shinya Kitaoka 120a6e
                    TTileSetCM32 *tileSet)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  double pbx, pby;
Shinya Kitaoka 120a6e
  double abx, aby;
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int tot_pix = 0;
Shinya Kitaoka 120a6e
  int *prob_vector;
Shinya Kitaoka 120a6e
  int fro, to;
Shinya Kitaoka 120a6e
  int col;
Shinya Kitaoka 120a6e
  int valore;
Shinya Kitaoka 120a6e
  int padre;
Shinya Kitaoka 120a6e
  //  int  temp_prob, att_match;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (F_reference.n <= 0 || F_reference.array == 0) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pbx = pby = 0.0;
Shinya Kitaoka 120a6e
  abx = aby = 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P ras = imgToApply->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* Resetta gli eventuali accoppiamenti fatti precedentemente */
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n; i++) F_reference.array[i].match = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (F_work.array) {
Shinya Kitaoka 120a6e
    for (i = 0; i < F_work.n; i++) free_list(&F_work.array[i].vicini);
Shinya Kitaoka 120a6e
    free(F_work.array);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  F_work.array = 0;
Shinya Kitaoka 120a6e
  F_work.size  = 0;
Shinya Kitaoka 120a6e
  F_work.n     = 0;
Shinya Kitaoka 120a6e
  F_work.lx    = 0;
Shinya Kitaoka 120a6e
  F_work.ly    = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  scan_fabri_regions(ras, &F_work, 0, 0, 0, 0, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (abs(F_work.lx * F_work.ly - F_reference.lx * F_reference.ly) >
Shinya Kitaoka 120a6e
      0.1 * (F_work.lx * F_work.ly + F_reference.lx * F_reference.ly))
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < F_work.n; i++) {
Shinya Kitaoka 120a6e
    F_work.array[i].match = -1;
Shinya Kitaoka 120a6e
    pbx += BIG_TO_DOUBLE(F_work.array[i].bx);
Shinya Kitaoka 120a6e
    pby += BIG_TO_DOUBLE(F_work.array[i].by);
Shinya Kitaoka 120a6e
    abx = BIG_TO_DOUBLE(F_work.array[i].bx);
Shinya Kitaoka 120a6e
    aby = BIG_TO_DOUBLE(F_work.array[i].by);
Shinya Kitaoka 120a6e
    tot_pix += F_work.array[i].npix;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  F_wor_bx = pbx / tot_pix;
Shinya Kitaoka 120a6e
  F_wor_by = pby / tot_pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  prob_vector = (int *)calloc(3 * F_work.n * F_reference.n, sizeof(int));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n; i++)
Shinya Kitaoka 120a6e
    for (j = 0; j < F_work.n; j++) assign_prob3(prob_vector, i, j);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Dx_f = Dx_f / F_reference.n;
Shinya Kitaoka 120a6e
  DP_f = DP_f / F_reference.n;
Shinya Kitaoka 120a6e
  Df_f = Df_f / F_reference.n;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Dx_t = Dx_t / F_work.n;
Shinya Kitaoka 120a6e
  DP_t = DP_t / F_work.n;
Shinya Kitaoka 120a6e
  Df_t = Df_t / F_work.n;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef SELECTIVE
Shinya Kitaoka 120a6e
  if (selective) {
Shinya Kitaoka 120a6e
    // Accoppia non trasparenti
Shinya Kitaoka 120a6e
    for (i = 0; i < F_work.n; i++)
Shinya Kitaoka 120a6e
      if (F_work.array[i].color_id != 0) {
Shinya Kitaoka 120a6e
        temp_prob = 0;
Shinya Kitaoka 120a6e
        att_match = F_reference.n;
Shinya Kitaoka 120a6e
        /* Se non verra' aggiornato in seguito non verra' *
Shinya Kitaoka 120a6e
* comunque piu' cambiato di colore               */
Shinya Kitaoka 120a6e
        for (j = 0; j < F_reference.n; j++)
Shinya Kitaoka 120a6e
          if ((F_reference.array[i].match < 0) &&
Shinya Kitaoka 120a6e
              ((prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                   (prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                   (prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                i * F_reference.n + j] /
Shinya Kitaoka 120a6e
                    1500.0) >
Shinya Kitaoka 120a6e
               temp_prob)) {
Shinya Kitaoka 120a6e
            att_match = j;
Shinya Kitaoka 120a6e
            temp_prob = (prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                        (prob_vector[i * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
                        (prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                     i * F_reference.n + j] /
Shinya Kitaoka 120a6e
                         1500.0);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        F_work.array[i].match = att_match;
Shinya Kitaoka 120a6e
        if (att_match < F_reference.n) F_reference.array[att_match].match = i;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*--------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool recomputeBBox = false;
Shinya Kitaoka 120a6e
  FillParameters params;
Shinya Kitaoka 120a6e
  params.m_emptyOnly = selective;
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n && i < F_work.n; i++) {
Shinya Kitaoka 120a6e
    padre  = trova_migliore_padre(prob_vector, &fro);
Shinya Kitaoka 120a6e
    valore = match(prob_vector, padre, &fro, &to);
Shinya Kitaoka 120a6e
    if (valore > AMB_TRESH) {
Shinya Kitaoka 120a6e
      F_work.array[to].match       = fro;
Shinya Kitaoka 120a6e
      F_reference.array[fro].match = to;
Shinya Kitaoka 120a6e
      F_work.array[to].color_id    = F_reference.array[fro].color_id;
Shinya Kitaoka 120a6e
      if ((F_work.array[to].color_id != 0) && (valore != 0)) {
Shinya Kitaoka 120a6e
        params.m_p       = TPoint(F_work.array[to].x, F_work.array[to].y);
Shinya Kitaoka 120a6e
        params.m_styleId = F_work.array[to].color_id;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        TTileSaverCM32 tileSaver(ras, tileSet);
Shinya Kitaoka 120a6e
        recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*..........................................................................*/
Shinya Kitaoka 120a6e
    /* Matching basato sulla probabilita' di colore */
Shinya Kitaoka 120a6e
    /*..........................................................................*/
Shinya Kitaoka 120a6e
    if (FALSE) {
Shinya Kitaoka 120a6e
      bool recomputeBBox = false;
Shinya Kitaoka 120a6e
      for (i = 0; i < F_work.n; i++) {
Shinya Kitaoka 120a6e
        if (F_work.array[i].match < 0) {
Shinya Kitaoka 120a6e
          find_best(prob_vector, &col, i);
Shinya Kitaoka 120a6e
          F_work.array[i].match    = 1;
Shinya Kitaoka 120a6e
          F_work.array[i].color_id = col;
Shinya Kitaoka 120a6e
          if (F_work.array[i].color_id != 0) {
Shinya Kitaoka 120a6e
            params.m_p       = TPoint(F_work.array[i].x, F_work.array[i].y);
Shinya Kitaoka 120a6e
            params.m_styleId = F_work.array[i].color_id;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            TTileSaverCM32 tileSaver(ras, tileSet);
Shinya Kitaoka 120a6e
            recomputeBBox = fill(ras, params, &tileSaver) || recomputeBBox;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  free(prob_vector);
Shinya Kitaoka 120a6e
  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
/*...........................................................................*/
Shinya Kitaoka 120a6e
static void scan_fabri_regions(TRasterCM32P ras,
Shinya Kitaoka 120a6e
                               struct s_fabri_region_list *rlst, int mode,
Shinya Kitaoka 120a6e
                               int ex1, int ey1, int ex2, int ey2)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int firstfree;
Shinya Kitaoka 120a6e
  TPixelCM32 *pix;
Shinya Kitaoka 120a6e
  int xa, xb;
Shinya Kitaoka 120a6e
  int xp, x, y, x1, y1, x2, y2, tmp;
Shinya Kitaoka 120a6e
  int dx, dy, i, j, h, n, tone, maxtone;
Shinya Kitaoka 120a6e
  int rold, rcur, nold, ncur;
Shinya Kitaoka 120a6e
  int precedente;
Shinya Kitaoka 120a6e
  struct s_segm *row[2];
Shinya Kitaoka 120a6e
  int *ultima_zona;
Shinya Kitaoka 120a6e
  int region_id, region_old, keep, discard, vicina;
Shinya Kitaoka 120a6e
  bool border_tooX1, border_tooY1, border_tooX2, border_tooY2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x1           = ex1;
Shinya Kitaoka 120a6e
  x2           = ex2;
Shinya Kitaoka 120a6e
  y1           = ey1;
Shinya Kitaoka 120a6e
  y2           = ey2;
Shinya Kitaoka 120a6e
  TRect rect   = ras->getBounds();
Shinya Kitaoka 120a6e
  border_tooX1 = x1 == rect.x0;
Shinya Kitaoka 120a6e
  border_tooY1 = y1 == rect.y0;
Shinya Kitaoka 120a6e
  border_tooX2 = x2 == rect.x1;
Shinya Kitaoka 120a6e
  border_tooY2 = y2 == rect.y1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  dx = x2 - x1 + 1;
Shinya Kitaoka 120a6e
  dy = y2 - y1 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rlst->lx = dx;
Shinya Kitaoka 120a6e
  rlst->ly = dy;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  row[0]      = (struct s_segm *)calloc(dx, sizeof(struct s_segm));
Shinya Kitaoka 120a6e
  row[1]      = (struct s_segm *)calloc(dx, sizeof(struct s_segm));
Shinya Kitaoka 120a6e
  ultima_zona = (int *)calloc(dx, sizeof(int));
Shinya Kitaoka 120a6e
  rold        = 1;
Shinya Kitaoka 120a6e
  rcur        = 0;
Shinya Kitaoka 120a6e
  nold = ncur = 0;
Shinya Kitaoka 120a6e
  vicina      = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (tmp = 0; tmp < dx; tmp++) ultima_zona[tmp] = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*.. Inizializza la struttura
Shinya Kitaoka 120a6e
   * ...............................................*/
Shinya Kitaoka 120a6e
  rlst->size  = 100;
Shinya Kitaoka 120a6e
  rlst->array = (struct s_fabri_region *)calloc(rlst->size,
Shinya Kitaoka 120a6e
                                                sizeof(struct s_fabri_region));
Shinya Kitaoka 120a6e
  rlst->n   = 0;
Shinya Kitaoka 120a6e
  firstfree = -1;
Shinya Kitaoka 120a6e
  for (tmp = 0; tmp < rlst->size; tmp++) {
Shinya Kitaoka 120a6e
    rlst->array[tmp].vicini = NULL;
Shinya Kitaoka 120a6e
    rlst->array[tmp].holes  = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*...........................................................................*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = y1; y <= y2; y++) {
Shinya Kitaoka 120a6e
    vicina = -1;
Shinya Kitaoka 120a6e
    pix    = ras->pixels(y) + x1;
Shinya Kitaoka 120a6e
    x      = x1;
Shinya Kitaoka 120a6e
    PRINTF("Cerca Area \n");
Shinya Kitaoka 120a6e
    while (x <= x2) {
Shinya Kitaoka 120a6e
      while (x <= x2 && pix->getTone() < pix->getMaxTone()) {
Shinya Kitaoka 120a6e
        pix++;
Shinya Kitaoka 120a6e
        x++;
Shinya Kitaoka 120a6e
      }              /*cerca una area */
Shinya Kitaoka 120a6e
      if (x <= x2) { /* non ho raggiunto il bordo */
Shinya Kitaoka 120a6e
        PRINTF("Prima del Bordo \n");
Shinya Kitaoka 120a6e
        xa      = x;
Shinya Kitaoka 120a6e
        maxtone = pix->getTone();
Shinya Kitaoka 120a6e
        xp      = x;
Shinya Kitaoka 120a6e
        while (x <= x2 && pix->getTone() >= pix->getMaxTone()) {
Shinya Kitaoka 120a6e
          tone = pix->getTone();
Shinya Kitaoka 120a6e
          if (tone > maxtone) {
Shinya Kitaoka 120a6e
            maxtone = tone;
Shinya Kitaoka 120a6e
            xp      = x;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          pix++;
Shinya Kitaoka 120a6e
          x++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        xb = x - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        PRINTF("Trovata Area \n");
Shinya Kitaoka 120a6e
        region_id = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        for (j = 0; j < nold && row[rold][j].xa <= xb; j++) {
Shinya Kitaoka 120a6e
          if (row[rold][j].xb >= xa && row[rold][j].xa <= xb) {
Shinya Kitaoka 120a6e
            region_old = row[rold][j].region;
Shinya Kitaoka 120a6e
            if (region_id == region_old) rlst->array[region_id].holes++;
Shinya Kitaoka 120a6e
            if (region_id < 0) {
Shinya Kitaoka 120a6e
              region_id = region_old;
Shinya Kitaoka 120a6e
              rlst->array[region_id].per +=
Shinya Kitaoka 120a6e
                  2 * (xb - xa + 1) + 2 -
Shinya Kitaoka 120a6e
                  2 * (std::min(row[rold][j].xb, xb) -
Shinya Kitaoka 120a6e
                       std::max(row[rold][j].xa, xa) + 1);
Shinya Kitaoka 120a6e
            } else if (region_id != region_old) {
Shinya Kitaoka 120a6e
              /* CONTATTO FRA region_id E region_old */
Shinya Kitaoka 120a6e
              PRINTF("Contatto tra %d e %d \n", region_id, region_old);
Shinya Kitaoka 120a6e
              keep    = region_old;
Shinya Kitaoka 120a6e
              discard = region_id;
Shinya Kitaoka 120a6e
              if (keep > discard) {
Shinya Kitaoka 120a6e
                tmp     = keep;
Shinya Kitaoka 120a6e
                keep    = discard;
Shinya Kitaoka 120a6e
                discard = tmp;
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
              /*.. UNISCO LE DUE REGIONI..................... */
Shinya Kitaoka 120a6e
              if (rlst->array[discard].x1 < rlst->array[keep].x1)
Shinya Kitaoka 120a6e
                rlst->array[keep].x1 = rlst->array[discard].x1;
Shinya Kitaoka 120a6e
              if (rlst->array[discard].y1 < rlst->array[keep].y1)
Shinya Kitaoka 120a6e
                rlst->array[keep].y1 = rlst->array[discard].y1;
Shinya Kitaoka 120a6e
              if (rlst->array[discard].x2 > rlst->array[keep].x2)
Shinya Kitaoka 120a6e
                rlst->array[keep].x2 = rlst->array[discard].x2;
Shinya Kitaoka 120a6e
              if (rlst->array[discard].y2 > rlst->array[keep].y2)
Shinya Kitaoka 120a6e
                rlst->array[keep].y2 = rlst->array[discard].y2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              rlst->array[keep].holes += rlst->array[discard].holes;
Shinya Kitaoka 120a6e
              rlst->array[keep].npix += rlst->array[discard].npix;
Shinya Kitaoka 120a6e
              rlst->array[keep].per += rlst->array[discard].per -
Shinya Kitaoka 120a6e
                                       2 * (std::min(row[rold][j].xb, xb) -
Shinya Kitaoka 120a6e
                                            std::max(row[rold][j].xa, xa) + 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              fondi(rlst, keep, discard);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              ADD_BIG_BIG(rlst->array[keep].by, rlst->array[discard].by);
Shinya Kitaoka 120a6e
              ADD_BIG_BIG(rlst->array[keep].bx, rlst->array[discard].bx);
Shinya Kitaoka 120a6e
              ADD_BIG_BIG(rlst->array[keep].by2, rlst->array[discard].by2);
Shinya Kitaoka 120a6e
              ADD_BIG_BIG(rlst->array[keep].bx2, rlst->array[discard].bx2);
Shinya Kitaoka 120a6e
              if (rlst->array[keep].tone < rlst->array[discard].tone) {
Shinya Kitaoka 120a6e
                rlst->array[keep].x    = rlst->array[discard].x;
Shinya Kitaoka 120a6e
                rlst->array[keep].y    = rlst->array[discard].y;
Shinya Kitaoka 120a6e
                rlst->array[keep].tone = rlst->array[discard].tone;
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
              /* OGNI RIFERIMENTO A 'discard' DIVENTA UN RIF.  A 'keep' */
Shinya Kitaoka 120a6e
              for (h = 0; h < nold; h++)
Shinya Kitaoka 120a6e
                if (row[rold][h].region == discard) row[rold][h].region = keep;
Shinya Kitaoka 120a6e
              for (h = 0; h < ncur; h++)
Shinya Kitaoka 120a6e
                if (row[rcur][h].region == discard) row[rcur][h].region = keep;
Shinya Kitaoka 120a6e
              region_id                                                 = keep;
Shinya Kitaoka 120a6e
              rinomina(discard, keep, rlst->n, rlst);
Shinya Kitaoka 120a6e
              for (tmp = 0; tmp < dx; tmp++)
Shinya Kitaoka 120a6e
                if (ultima_zona[tmp] == discard) ultima_zona[tmp] = keep;
Shinya Kitaoka 120a6e
              /* AGGIUNGO discard AL POOL DEI LIBERI */
Shinya Kitaoka 120a6e
              rlst->array[discard].active   = 0;
Shinya Kitaoka 120a6e
              rlst->array[discard].nextfree = firstfree;
Shinya Kitaoka 120a6e
              free_list(&rlst->array[discard].vicini);
Shinya Kitaoka 120a6e
              rlst->array[discard].vicini = NULL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              firstfree = discard;
Shinya Kitaoka 120a6e
            } /* end elseif */
Shinya Kitaoka 120a6e
          }   /* end of if */
Shinya Kitaoka 120a6e
        }     /* end of for */
Shinya Kitaoka 120a6e
        PRINTF("Region ID %d %d %d %d \n", region_id, xa, xb, y);
Shinya Kitaoka 120a6e
        PRINTF("Memorizza Area \n");
Shinya Kitaoka 120a6e
        if (region_id >= 0) {
Shinya Kitaoka 120a6e
          rlst->array[region_id].lxb                                    = xb;
Shinya Kitaoka 120a6e
          rlst->array[region_id].lxa                                    = xa;
Shinya Kitaoka 120a6e
          if (xa < rlst->array[region_id].x1) rlst->array[region_id].x1 = xa;
Shinya Kitaoka 120a6e
          if (xb > rlst->array[region_id].x2) rlst->array[region_id].x2 = xb;
Shinya Kitaoka 120a6e
          if (y < rlst->array[region_id].y1) rlst->array[region_id].y1  = y;
Shinya Kitaoka 120a6e
          if (y > rlst->array[region_id].y2) rlst->array[region_id].y2  = y;
Shinya Kitaoka 120a6e
          rlst->array[region_id].npix += xb - xa + 1;
Shinya Kitaoka 120a6e
          ADD_BIG(rlst->array[region_id].by, (xb - xa + 1) * y);
Shinya Kitaoka 120a6e
          ADD_BIG(rlst->array[region_id].bx, (xb - xa + 1) * (xb + xa) / 2);
Shinya Kitaoka 120a6e
          ADD_BIG(rlst->array[region_id].by2, (xb - xa + 1) * y * y);
Shinya Kitaoka 120a6e
          ADD_BIG(rlst->array[region_id].bx2, somma_quadrati(xa, xb));
Shinya Kitaoka 120a6e
          if (rlst->array[region_id].tone < maxtone ||
Shinya Kitaoka 120a6e
              (rlst->array[region_id].x2 - rlst->array[region_id].x1) <
Shinya Kitaoka 120a6e
                  xb - xa) {
Shinya Kitaoka 120a6e
            rlst->array[region_id].x    = xp;
Shinya Kitaoka 120a6e
            rlst->array[region_id].y    = y;
Shinya Kitaoka 120a6e
            rlst->array[region_id].tone = maxtone;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          /* CREO UNA NUOVA REGIONE */
Shinya Kitaoka 120a6e
          if (firstfree < 0) {
Shinya Kitaoka 120a6e
            if (rlst->n >= rlst->size) {
Shinya Kitaoka 120a6e
              rlst->size += 50;
Shinya Kitaoka 120a6e
              rlst->array = (struct s_fabri_region *)realloc(
Shinya Kitaoka 120a6e
                  rlst->array, rlst->size * sizeof(struct s_fabri_region));
Shinya Kitaoka 120a6e
              for (tmp = rlst->size - 1; tmp >= rlst->size - 50; tmp--)
Shinya Kitaoka 120a6e
                rlst->array[tmp].vicini = NULL;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            region_id = rlst->n++;
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            region_id = firstfree;
Shinya Kitaoka 120a6e
            firstfree = rlst->array[region_id].nextfree;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          rlst->array[region_id].active   = 1;
Shinya Kitaoka 120a6e
          rlst->array[region_id].vicini   = NULL;
Shinya Kitaoka 120a6e
          rlst->array[region_id].nextfree = 0;
Shinya Kitaoka 120a6e
          rlst->array[region_id].x        = xp;
Shinya Kitaoka 120a6e
          rlst->array[region_id].y        = y;
Shinya Kitaoka 120a6e
          rlst->array[region_id].x1       = xa;
Shinya Kitaoka 120a6e
          rlst->array[region_id].y1       = y;
Shinya Kitaoka 120a6e
          rlst->array[region_id].x2       = xb;
Shinya Kitaoka 120a6e
          rlst->array[region_id].y2       = y;
Shinya Kitaoka 120a6e
          rlst->array[region_id].npix     = xb - xa + 1;
Shinya Kitaoka 120a6e
          rlst->array[region_id].holes    = 0;
Shinya Kitaoka 120a6e
          rlst->array[region_id].per      = 2 * (xb - xa + 1) + 2;
Shinya Kitaoka 120a6e
          rlst->array[region_id].lxb      = xb;
Shinya Kitaoka 120a6e
          rlst->array[region_id].lxa      = xa;
Shinya Kitaoka 120a6e
          ASS_BIG(rlst->array[region_id].by, (xb - xa + 1) * y);
Shinya Kitaoka 120a6e
          ASS_BIG(rlst->array[region_id].bx, (xb - xa + 1) * (xb + xa) / 2);
Shinya Kitaoka 120a6e
          ASS_BIG(rlst->array[region_id].by2, (xb - xa + 1) * y * y);
Shinya Kitaoka 120a6e
          ASS_BIG(rlst->array[region_id].bx2, somma_quadrati(xa, xb));
Shinya Kitaoka 120a6e
          rlst->array[region_id].tone     = maxtone;
Shinya Kitaoka 120a6e
          rlst->array[region_id].color_id = pix->getPaint();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /* MEMORIZZO LA REGIONE CORRENTE */
Shinya Kitaoka 120a6e
        precedente = -1;
Shinya Kitaoka 120a6e
        /*-----------------------------------------------------
Shinya Kitaoka 120a6e
.. Controlla se esiste vicinanza verticale ...........*/
Shinya Kitaoka 120a6e
        for (tmp = xa; tmp <= xb; tmp++) {
Shinya Kitaoka 120a6e
          if (ultima_zona[tmp - x1] != precedente) {
Shinya Kitaoka 120a6e
            aggiungi(ultima_zona[tmp - x1], region_id, rlst);
Shinya Kitaoka 120a6e
            precedente = ultima_zona[tmp - x1];
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          ultima_zona[tmp - x1] = region_id;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        /*-----------------------------------------------------*/
Shinya Kitaoka 120a6e
        aggiungi(vicina, region_id, rlst);
Shinya Kitaoka 120a6e
        vicina = region_id;
Shinya Kitaoka 120a6e
        if (ncur >= dx - 1) {
Shinya Kitaoka 120a6e
          printf("autofill: row overflow dx=%d\n", dx);
Shinya Kitaoka 120a6e
          exit(1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        row[rcur][ncur].xa     = xa;
Shinya Kitaoka 120a6e
        row[rcur][ncur].xb     = xb;
Shinya Kitaoka 120a6e
        row[rcur][ncur].region = region_id;
Shinya Kitaoka 120a6e
        ncur++;
Shinya Kitaoka 120a6e
      } /* end of if#1 */
Shinya Kitaoka 120a6e
    }   /* end of while#1 */
Shinya Kitaoka 120a6e
    rcur = 1 - rcur;
Shinya Kitaoka 120a6e
    rold = 1 - rold;
Shinya Kitaoka 120a6e
    nold = ncur;
Shinya Kitaoka 120a6e
    ncur = 0;
Shinya Kitaoka 120a6e
  } /* end of for#1 */
Shinya Kitaoka 120a6e
  n = 0;
Shinya Kitaoka 120a6e
  /* mostra_vicini(rlst); */
Shinya Kitaoka 120a6e
  for (i = 0; i < rlst->n; i++)
Shinya Kitaoka 120a6e
    if ((rlst->array[i].active) && ((rlst->array[i].x1 > x1 || border_tooX1) &&
Shinya Kitaoka 120a6e
                                    (rlst->array[i].x2 < x2 || border_tooX2) &&
Shinya Kitaoka 120a6e
                                    (rlst->array[i].y1 > y1 || border_tooY1) &&
Shinya Kitaoka 120a6e
                                    (rlst->array[i].y2 < y2 || border_tooY2))) {
Shinya Kitaoka 120a6e
      if (n < i) {
Shinya Kitaoka 120a6e
        rlst->array[n]        = rlst->array[i];
Shinya Kitaoka 120a6e
        rlst->array[n].vicini = rlst->array[i].vicini;
Shinya Kitaoka 120a6e
        rinomina(i, n, rlst->n, rlst);
Shinya Kitaoka 120a6e
        for (tmp                                      = 0; tmp < dx; tmp++)
Shinya Kitaoka 120a6e
          if (ultima_zona[tmp] == i) ultima_zona[tmp] = n;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      rlst->array[n].lx = rlst->array[n].x2 - rlst->array[n].x1 + 1;
Shinya Kitaoka 120a6e
      rlst->array[n].ly = rlst->array[n].y2 - rlst->array[n].y1 + 1;
Shinya Kitaoka 120a6e
      rlst->array[n].xm = (rlst->array[n].x2 + rlst->array[n].x1) / 2;
Shinya Kitaoka 120a6e
      rlst->array[n].ym = (rlst->array[n].y2 + rlst->array[n].y1) / 2;
Shinya Kitaoka 120a6e
      n++;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      rimuovi_tutti(i, rlst);
Shinya Kitaoka 120a6e
  /* mostra_vicini(rlst); */
Shinya Kitaoka 120a6e
  rlst->n = n;
Shinya Kitaoka 120a6e
  free(row[0]);
Shinya Kitaoka 120a6e
  free(row[1]);
Shinya Kitaoka 120a6e
  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,
Shinya Kitaoka 120a6e
                     struct s_fabri_region_list *rlst)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  struct vicine *appo, *old, appo1;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  int trovato = FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  PRINTF("Rinomino %d %d Regioni: %d \n", regione1, regione2, num_regioni);
Shinya Kitaoka 120a6e
  /* mostra_vicini(rlst);  */
Shinya Kitaoka 120a6e
  for (i = 0; i < num_regioni; i++)
Shinya Kitaoka 120a6e
    if (rlst->array[i].active) {
Shinya Kitaoka 120a6e
      trovato = ((i == regione2) || (i == regione1));
Shinya Kitaoka 120a6e
      PRINTF(">> %d \n", i);
Shinya Kitaoka 120a6e
      old  = NULL;
Shinya Kitaoka 120a6e
      appo = rlst->array[i].vicini;
Shinya Kitaoka 120a6e
      while (appo != NULL) {
Shinya Kitaoka 120a6e
        if ((appo->region_id == regione2) || (appo->region_id == regione1)) {
Shinya Kitaoka 120a6e
          if (trovato)
Shinya Kitaoka 120a6e
            if (old != NULL) {
Shinya Kitaoka 120a6e
              PRINTF("A%d %d \n", i, appo->region_id);
Shinya Kitaoka 120a6e
              old->next = appo->next;
Shinya Kitaoka 120a6e
              free(appo);
Shinya Kitaoka 120a6e
              appo = old->next;
Shinya Kitaoka 120a6e
              /* mostra_vicini(rlst); */
Shinya Kitaoka 120a6e
            } else {
Shinya Kitaoka 120a6e
              PRINTF("B%d %d \n", i, appo->region_id);
Shinya Kitaoka 120a6e
              rlst->array[i].vicini = appo->next;
Shinya Kitaoka 120a6e
              appo1                 = *appo;
Shinya Kitaoka 120a6e
              free(appo);
Shinya Kitaoka 120a6e
              appo = appo1.next;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          else /* non ho ancora trovato */
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
            PRINTF("S%d \n", appo->region_id);
Shinya Kitaoka 120a6e
            appo->region_id = regione2;
Shinya Kitaoka 120a6e
            old             = appo;
Shinya Kitaoka 120a6e
            appo            = appo->next;
Shinya Kitaoka 120a6e
            trovato         = TRUE;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        } else /* region_id non e' region2 o regione 1 */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          PRINTF("D%d \n", appo->region_id);
Shinya Kitaoka 120a6e
          old  = appo;
Shinya Kitaoka 120a6e
          appo = appo->next;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  PRINTF("Rinomino %d %d\n", regione1, regione2);
Shinya Kitaoka 120a6e
  /*   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,
Shinya Kitaoka 120a6e
                     struct s_fabri_region_list *rlst)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  struct vicine *appo1, *appo2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*  if((regione1==0)||(regione2==0)) */
Shinya Kitaoka 120a6e
  PRINTF("Aggiungo %d a %d\n", regione1, regione2);
Shinya Kitaoka 120a6e
  if ((regione1 != -1) && (regione2 != -1) && (regione2 != regione1)) {
Shinya Kitaoka 120a6e
    if (rlst->array[regione1].active) {
Shinya Kitaoka 120a6e
      appo1 = rlst->array[regione1].vicini;
Shinya Kitaoka 120a6e
      while ((appo1 != NULL) && (appo1->region_id != regione2))
Shinya Kitaoka 120a6e
        appo1 = appo1->next;
Shinya Kitaoka 120a6e
      if (appo1 == NULL) {
Shinya Kitaoka 120a6e
        appo1            = (struct vicine *)calloc(1, sizeof(struct vicine));
Shinya Kitaoka 120a6e
        appo1->next      = rlst->array[regione1].vicini;
Shinya Kitaoka 120a6e
        appo1->region_id = regione2;
Shinya Kitaoka 120a6e
        rlst->array[regione1].vicini = appo1;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (rlst->array[regione2].active) {
Shinya Kitaoka 120a6e
      appo2 = rlst->array[regione2].vicini;
Shinya Kitaoka 120a6e
      while ((appo2 != NULL) && (appo2->region_id != regione1))
Shinya Kitaoka 120a6e
        appo2 = appo2->next;
Shinya Kitaoka 120a6e
      if (appo2 == NULL) {
Shinya Kitaoka 120a6e
        appo2            = (struct vicine *)calloc(1, sizeof(struct vicine));
Shinya Kitaoka 120a6e
        appo2->next      = rlst->array[regione2].vicini;
Shinya Kitaoka 120a6e
        appo2->region_id = regione1;
Shinya Kitaoka 120a6e
        rlst->array[regione2].vicini = appo2;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  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
{
Shinya Kitaoka 120a6e
  struct vicine *appo1, *appo2, *appo3;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  PRINTF("Fondi %d %d \n", r1, r2);
Shinya Kitaoka 120a6e
  /* mostra_vicini(rlst); */
Shinya Kitaoka 120a6e
  appo2 = rlst->array[r2].vicini;
Shinya Kitaoka 120a6e
  while (appo2 != NULL) {
Shinya Kitaoka 120a6e
    appo1 = rlst->array[r1].vicini;
Shinya Kitaoka 120a6e
    while ((appo1 != NULL) && (appo1->region_id != appo2->region_id) &&
Shinya Kitaoka 120a6e
           (appo2->region_id != r1))
Shinya Kitaoka 120a6e
      appo1 = appo1->next;
Shinya Kitaoka 120a6e
    if (appo1 == NULL) {
Shinya Kitaoka 120a6e
      appo3            = (struct vicine *)calloc(1, sizeof(struct vicine));
Shinya Kitaoka 120a6e
      appo3->next      = rlst->array[r1].vicini;
Shinya Kitaoka 120a6e
      appo3->region_id = appo2->region_id;
Shinya Kitaoka 120a6e
      rlst->array[r1].vicini = appo3;
Shinya Kitaoka 120a6e
      appo2                  = appo2->next;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      appo2 = appo2->next;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  PRINTF("Fuso %d %d \n", r1, r2);
Shinya Kitaoka 120a6e
  /* 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
{
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  struct vicine *appo;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < rlst->n; i++)
Shinya Kitaoka 120a6e
    if (rlst->array[i].active) {
Shinya Kitaoka 120a6e
      PRINTF("Region: %d ::", i);
Shinya Kitaoka 120a6e
      appo = rlst->array[i].vicini;
Shinya Kitaoka 120a6e
      while (appo != NULL) {
Shinya Kitaoka 120a6e
        PRINTF("%d ", appo->region_id);
Shinya Kitaoka 120a6e
        appo = appo->next;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      PRINTF("\n");
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      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
{
Shinya Kitaoka 120a6e
  struct vicine *appo, *old;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  PRINTF("Elimino %d \n", r1);
Shinya Kitaoka 120a6e
  /* mostra_vicini(rlst);  */
Shinya Kitaoka 120a6e
  for (i = 0; i < rlst->n; i++)
Shinya Kitaoka 120a6e
    if (rlst->array[i].active) {
Shinya Kitaoka 120a6e
      PRINTF(">> %d \n", i);
Shinya Kitaoka 120a6e
      old  = NULL;
Shinya Kitaoka 120a6e
      appo = rlst->array[i].vicini;
Shinya Kitaoka 120a6e
      while (appo != NULL) {
Shinya Kitaoka 120a6e
        if (appo->region_id == r1) {
Shinya Kitaoka 120a6e
          PRINTF("A%d %d\n", appo->region_id, old->region_id);
Shinya Kitaoka 120a6e
          if (old != NULL) {
Shinya Kitaoka 120a6e
            old->next = appo->next;
Shinya Kitaoka 120a6e
            /* free(appo); */
Shinya Kitaoka 120a6e
            appo = old->next;
Shinya Kitaoka 120a6e
            /* mostra_vicini(rlst); */
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            rlst->array[i].vicini = appo->next;
Shinya Kitaoka 120a6e
            /* free(appo); */
Shinya Kitaoka 120a6e
            appo = rlst->array[i].vicini;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        } else /* region_id non e' region2 o regione 1 */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          PRINTF("D%d \n", appo->region_id);
Shinya Kitaoka 120a6e
          old  = appo;
Shinya Kitaoka 120a6e
          appo = appo->next;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  /*  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
{
Shinya Kitaoka 120a6e
  double delta_posx1, delta_posy1, delta_posx2, delta_posy2;
Shinya Kitaoka 120a6e
  double delta_momx1, delta_momy1, delta_momx2, delta_momy2;
Shinya Kitaoka 120a6e
  int delta_pix, delta_pix_max;
Shinya Kitaoka 120a6e
  double delta_pos, delta_pos_max, delta_forma_mom;
Shinya Kitaoka 120a6e
  int delta_forma1, delta_forma2, delta_forma;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_posx1 =
Shinya Kitaoka 120a6e
      BIG_TO_DOUBLE(F_reference.array[i].bx) / F_reference.array[i].npix -
Shinya Kitaoka 120a6e
      F_ref_bx;
Shinya Kitaoka 120a6e
  delta_posy1 =
Shinya Kitaoka 120a6e
      BIG_TO_DOUBLE(F_reference.array[i].by) / F_reference.array[i].npix -
Shinya Kitaoka 120a6e
      F_ref_by;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_posx2 =
Shinya Kitaoka 120a6e
      BIG_TO_DOUBLE(F_work.array[j].bx) / F_work.array[j].npix - F_wor_bx;
Shinya Kitaoka 120a6e
  delta_posy2 =
Shinya Kitaoka 120a6e
      BIG_TO_DOUBLE(F_work.array[j].by) / F_work.array[j].npix - F_wor_by;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* Cosi' calcolo il modulo della differenza */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_pos = sqrt((delta_posx2 - delta_posx1) * (delta_posx2 - delta_posx1) +
Shinya Kitaoka 120a6e
                   (delta_posy2 - delta_posy1) * (delta_posy2 - delta_posy1));
Shinya Kitaoka 120a6e
  delta_pos_max = sqrt((double)(F_work.lx * F_work.lx + F_work.ly * F_work.ly));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  prob[i + j * F_reference.n] =
Shinya Kitaoka 120a6e
      ROUNDP(1000 * (1 - (delta_pos / delta_pos_max)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_pix = abs(F_reference.array[i].npix - F_work.array[j].npix);
Shinya Kitaoka 120a6e
  delta_pix_max =
Shinya Kitaoka 120a6e
      std::max((F_work.lx * F_work.ly), (F_reference.lx * F_reference.ly));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  prob[(F_work.n * F_reference.n) + i + (j * F_reference.n)] =
Shinya Kitaoka 120a6e
      ROUNDP(1000 * (1 - ((double)delta_pix /
Shinya Kitaoka 120a6e
                          (F_reference.array[i].npix + F_work.array[j].npix))));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_momx1 =
Shinya Kitaoka 120a6e
      BIG_TO_DOUBLE(F_reference.array[i].bx2) / F_reference.array[i].npix -
Shinya Kitaoka 120a6e
      (BIG_TO_DOUBLE(F_reference.array[i].bx) / F_reference.array[i].npix *
Shinya Kitaoka 120a6e
       BIG_TO_DOUBLE(F_reference.array[i].bx) / F_reference.array[i].npix);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_momy1 =
Shinya Kitaoka 120a6e
      BIG_TO_DOUBLE(F_reference.array[i].by2) / F_reference.array[i].npix -
Shinya Kitaoka 120a6e
      (BIG_TO_DOUBLE(F_reference.array[i].by) / F_reference.array[i].npix *
Shinya Kitaoka 120a6e
       BIG_TO_DOUBLE(F_reference.array[i].by) / F_reference.array[i].npix);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_momx2 = BIG_TO_DOUBLE(F_work.array[j].bx2) / F_work.array[j].npix -
Shinya Kitaoka 120a6e
                (BIG_TO_DOUBLE(F_work.array[j].bx) / F_work.array[j].npix *
Shinya Kitaoka 120a6e
                 BIG_TO_DOUBLE(F_work.array[j].bx) / F_work.array[j].npix);
Shinya Kitaoka 120a6e
  delta_momy2 = BIG_TO_DOUBLE(F_work.array[j].by2) / F_work.array[j].npix -
Shinya Kitaoka 120a6e
                (BIG_TO_DOUBLE(F_work.array[j].by) / F_work.array[j].npix *
Shinya Kitaoka 120a6e
                 BIG_TO_DOUBLE(F_work.array[j].by) / F_work.array[j].npix);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_forma_mom =
Shinya Kitaoka 120a6e
      abs(sqrt(delta_momx1 + delta_momy1) - sqrt(delta_momx2 + delta_momy2));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_forma1 = ROUNDP(
Shinya Kitaoka 120a6e
      1000 * (((double)F_reference.array[i].per / F_reference.array[i].npix -
Shinya Kitaoka 120a6e
               2 / sqrt((double)F_reference.array[i].npix / 3.14)) /
Shinya Kitaoka 120a6e
              (2 - 2 / sqrt((double)F_reference.array[i].npix / 3.14))));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_forma2 =
Shinya Kitaoka 120a6e
      ROUNDP(1000 * (((double)F_work.array[j].per / F_work.array[j].npix -
Shinya Kitaoka 120a6e
                      2 / sqrt((double)F_work.array[j].npix / 3.14)) /
Shinya Kitaoka 120a6e
                     (2 - 2 / sqrt((double)F_work.array[j].npix / 3.14))));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delta_forma = ROUNDP(1000 * (1 - (delta_forma_mom / delta_pos_max)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  prob[(2 * F_work.n * F_reference.n) + i + (j * F_reference.n)] = delta_forma;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Dx_f += ROUNDP(sqrt(delta_posx1 * delta_posx1 + delta_posy1 * delta_posy1));
Shinya Kitaoka 120a6e
  DP_f += F_reference.array[i].npix;
Shinya Kitaoka 120a6e
  Df_f += ROUNDP(sqrt(delta_momx1 * delta_momx1 + delta_momy1 * delta_momy1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Dx_t += ROUNDP(sqrt(delta_posx2 * delta_posx2 + delta_posy2 * delta_posy2));
Shinya Kitaoka 120a6e
  DP_t += F_work.array[j].npix;
Shinya Kitaoka 120a6e
  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
{
Shinya Kitaoka 120a6e
  float att_max = 0.0;
Shinya Kitaoka 120a6e
  int i, j, numero;
Shinya Kitaoka 120a6e
  float color_value;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < F_reference.n; i++) {
Shinya Kitaoka 120a6e
    color_value = 0.0;
Shinya Kitaoka 120a6e
    numero      = 0;
Shinya Kitaoka 120a6e
    for (j = 0; j < F_reference.n; j++) {
Shinya Kitaoka 120a6e
      if (F_reference.array[i].color_id == F_reference.array[j].color_id) {
Shinya Kitaoka 120a6e
        color_value +=
Shinya Kitaoka 120a6e
            (prob[to * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
            (prob[to * F_reference.n + j] / 1000.0) *
Shinya Kitaoka 120a6e
            /*   (prob[(F_work.n*F_reference.n)+to*F_reference.n+j]/1500.0)*
Shinya Kitaoka 120a6e
             */ (prob[2 * (F_work.n * F_reference.n) + to * F_reference.n + j] /
Shinya Kitaoka 120a6e
                 1500.0);
Shinya Kitaoka 120a6e
        numero++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if ((color_value / numero) > att_max) {
Shinya Kitaoka 120a6e
      att_max = color_value / numero;
Shinya Kitaoka 120a6e
      PRINTF("Nuovo Massimo %f \n", att_max);
Shinya Kitaoka 120a6e
      *col = F_reference.array[i].color_id;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
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
{
Shinya Kitaoka 120a6e
  if (*vic != NULL) {
Shinya Kitaoka 120a6e
    free_list(&(*vic)->next);
Shinya Kitaoka 120a6e
    free(*vic);
Shinya Kitaoka 120a6e
    *vic = NULL;
Shinya Kitaoka 120a6e
  }
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
{
Shinya Kitaoka 120a6e
  int somma = 0;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = std::min(x, y); i <= std::max(x, y); i++) somma += i * i;
Shinya Kitaoka 120a6e
  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
{
Shinya Kitaoka 120a6e
  int att_best, att_second, att_max_diff = 0;
Shinya Kitaoka 120a6e
  int att_choice = -1, i, j, k;
Shinya Kitaoka 120a6e
  struct vicine *a1, *a2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  PRINTF("Inizio Ricerca del Padre \n");
Shinya Kitaoka 120a6e
  for (k = 0; k < F_reference.n; k++)
Shinya Kitaoka 120a6e
    if (F_reference.array[k].match >= 0) {
Shinya Kitaoka 120a6e
      PRINTF("%d Gia' Accoppiato\n", k);
Shinya Kitaoka 120a6e
      a1 = F_reference.array[k].vicini;
Shinya Kitaoka 120a6e
      while (a1 != NULL) {
Shinya Kitaoka 120a6e
        i = a1->region_id;
Shinya Kitaoka 120a6e
        if (F_reference.array[i].match < 0) {
Shinya Kitaoka 120a6e
          PRINTF("%d vicino di %d Non Accoppiato\n", i, k);
Shinya Kitaoka 120a6e
          a2         = F_work.array[F_reference.array[k].match].vicini;
Shinya Kitaoka 120a6e
          att_best   = 0;
Shinya Kitaoka 120a6e
          att_second = 0;
Shinya Kitaoka 120a6e
          while (a2 != NULL) {
Shinya Kitaoka 120a6e
            PRINTF("Coppia %d %d \n", i, j);
Shinya Kitaoka 120a6e
            j = a2->region_id;
Shinya Kitaoka 120a6e
            if (F_work.array[j].match < 0) {
Shinya Kitaoka 120a6e
              if (prob_vector[j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                      prob_vector[(F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                  j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                      prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                  j * F_reference.n + i] >
Shinya Kitaoka 120a6e
                  att_second)
Shinya Kitaoka 120a6e
                att_second = prob_vector[j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                             prob_vector[(F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                         j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                             prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                         j * F_reference.n + i];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              if (prob_vector[j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                      prob_vector[(F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                  j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                      prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                  j * F_reference.n + i] >
Shinya Kitaoka 120a6e
                  att_best) {
Shinya Kitaoka 120a6e
                att_second = att_best;
Shinya Kitaoka 120a6e
                att_best   = prob_vector[j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                           prob_vector[(F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                       j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                           prob_vector[2 * (F_work.n * F_reference.n) +
Shinya Kitaoka 120a6e
                                       j * F_reference.n + i];
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            a2 = a2->next;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          if ((att_best - att_second) > att_max_diff) {
Shinya Kitaoka 120a6e
            att_max_diff = att_best - att_second;
Shinya Kitaoka 120a6e
            att_choice   = F_reference.array[k].match;
Shinya Kitaoka 120a6e
            *att_my      = i;
Shinya Kitaoka 120a6e
            PRINTF("Nuovo Coeff.: %d \n", att_max_diff);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        a1 = a1->next;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  PRINTF("Finita Ricerca del Padre \n");
Shinya Kitaoka 120a6e
  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
{
Shinya Kitaoka 120a6e
  int att_max = 0, i, j;
Shinya Kitaoka 120a6e
  struct vicine *a2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (padre > -1) {
Shinya Kitaoka 120a6e
    a2 = F_work.array[padre].vicini;
Shinya Kitaoka 120a6e
    while (a2 != NULL) {
Shinya Kitaoka 120a6e
      j = a2->region_id;
Shinya Kitaoka 120a6e
      if ((F_work.array[j].match < 0) &&
Shinya Kitaoka 120a6e
          (prob[j * F_reference.n + (*fro)] *
Shinya Kitaoka 120a6e
               prob[(F_work.n * F_reference.n) + j * F_reference.n + (*fro)] *
Shinya Kitaoka 120a6e
               prob[2 * (F_work.n * F_reference.n) + j * F_reference.n +
Shinya Kitaoka 120a6e
                    (*fro)] >
Shinya Kitaoka 120a6e
           att_max)) {
Shinya Kitaoka 120a6e
        att_max =
Shinya Kitaoka 120a6e
            prob[j * F_reference.n + (*fro)] *
Shinya Kitaoka 120a6e
            prob[(F_work.n * F_reference.n) + j * F_reference.n + (*fro)] *
Shinya Kitaoka 120a6e
            prob[2 * (F_work.n * F_reference.n) + j * F_reference.n + (*fro)];
Shinya Kitaoka 120a6e
        *to = j;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      a2 = a2->next;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    for (i = 0; i < F_reference.n; i++)
Shinya Kitaoka 120a6e
      for (j = 0; j < F_work.n; j++)
Shinya Kitaoka 120a6e
        if ((F_work.array[j].match < 0) && (F_reference.array[i].match < 0) &&
Shinya Kitaoka 120a6e
            (F_work.array[j].npix > DIM_TRESH * F_work.lx * F_work.ly) &&
Shinya Kitaoka 120a6e
            (F_reference.array[i].npix >
Shinya Kitaoka 120a6e
             DIM_TRESH * F_reference.lx * F_reference.ly)) {
Shinya Kitaoka 120a6e
          if (prob[j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                  prob[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                  prob[2 * (F_work.n * F_reference.n) + j * F_reference.n + i] >
Shinya Kitaoka 120a6e
              att_max) {
Shinya Kitaoka 120a6e
            att_max =
Shinya Kitaoka 120a6e
                prob[j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                prob[(F_work.n * F_reference.n) + j * F_reference.n + i] *
Shinya Kitaoka 120a6e
                prob[2 * (F_work.n * F_reference.n) + j * F_reference.n + i];
Shinya Kitaoka 120a6e
            *fro = i;
Shinya Kitaoka 120a6e
            *to  = j;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return att_max;
Toshihiro Shimizu 890ddd
}