Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "autopos.h"
Toshihiro Shimizu 890ddd
#include "cleanupcommon.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace CleanupTypes;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
guardare DAFARE
Toshihiro Shimizu 890ddd
guardare assumo
Toshihiro Shimizu 890ddd
autoalign rgb ->ora viene chiamata con un buffer rgbm ! modificare opportunamente
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
fare resize e realloc size dello stack a 65000 unita' 
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
#define TRUE 1
Toshihiro Shimizu 890ddd
#define FALSE 0
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define SECURITY_MARGIN_MM 4.0
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int Debug_flag = FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*===========================================================================*/
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
     AUTOALIGNMENT 
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define AUTOAL_BLACK_COLS 2
Toshihiro Shimizu 890ddd
#define AUTOAL_WHITE_COLS 2
Toshihiro Shimizu 890ddd
#define AUTOAL_THRESHOLD 160
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int autoalign_gr8(UCHAR *buffer_gr8,
Toshihiro Shimizu 890ddd
						 int wrap, int lx, int ly, int pix_origin,
Toshihiro Shimizu 890ddd
						 int dpix_dx, int dpix_dy, int strip_width)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int first_x[2], dx_dcol[2], target[2];
Toshihiro Shimizu 890ddd
	int i, x, y, cols;
Toshihiro Shimizu 890ddd
	int col_value, threshold;
Toshihiro Shimizu 890ddd
	int consec_black_cols, consec_white_cols, black_strip_edge;
Toshihiro Shimizu 890ddd
	UCHAR *pix, *origin;
Toshihiro Shimizu 890ddd
	int delta_x, delta_pix;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	origin = buffer_gr8 + pix_origin;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	first_x[0] = 0;
Toshihiro Shimizu 890ddd
	dx_dcol[0] = 1;
Toshihiro Shimizu 890ddd
	target[0] = strip_width / 2;
Toshihiro Shimizu 890ddd
	first_x[1] = lx - 1;
Toshihiro Shimizu 890ddd
	dx_dcol[1] = -1;
Toshihiro Shimizu 890ddd
	target[1] = lx - 1 - strip_width / 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	threshold = AUTOAL_THRESHOLD * ly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < 2; i++) {
Toshihiro Shimizu 890ddd
		consec_black_cols = 0;
Toshihiro Shimizu 890ddd
		consec_white_cols = 0;
Toshihiro Shimizu 890ddd
		black_strip_edge = 0;
Toshihiro Shimizu 890ddd
		for (x = first_x[i], cols = 0; cols < strip_width; x += dx_dcol[i], cols++) {
Toshihiro Shimizu 890ddd
			col_value = 0;
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				col_value += *pix;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (col_value < threshold) {
Toshihiro Shimizu 890ddd
				consec_white_cols = 0;
Toshihiro Shimizu 890ddd
				consec_black_cols++;
Toshihiro Shimizu 890ddd
				if (consec_black_cols >= AUTOAL_BLACK_COLS)
Toshihiro Shimizu 890ddd
					black_strip_edge = x;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				consec_black_cols = 0;
Toshihiro Shimizu 890ddd
				consec_white_cols++;
Toshihiro Shimizu 890ddd
				if (consec_white_cols >= AUTOAL_WHITE_COLS && black_strip_edge)
Toshihiro Shimizu 890ddd
					goto found;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
found:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (x = first_x[i], cols = 0; cols < strip_width; x += dx_dcol[i], cols++) {
Toshihiro Shimizu 890ddd
		pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
		for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
			*pix = 255;
Toshihiro Shimizu 890ddd
			pix += dpix_dy;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	delta_x = target[i] - black_strip_edge;
Toshihiro Shimizu 890ddd
	delta_pix = delta_x * dpix_dx;
Toshihiro Shimizu 890ddd
	if (delta_x > 0) {
Toshihiro Shimizu 890ddd
		for (x = lx - 1 - delta_x; x >= 0; x--) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				*(pix + delta_pix) = *pix;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (x = lx - delta_x; x < lx; x++) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				*pix = 255;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else if (delta_x < 0) {
Toshihiro Shimizu 890ddd
		for (x = -delta_x; x < lx; x++) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				*(pix + delta_pix) = *pix;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (x = 0; x < -delta_x; x++) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				*pix = 255;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int autoalign_rgb(TPixel32 *buffer_rgb,
Toshihiro Shimizu 890ddd
						 int wrap, int lx, int ly, int pix_origin,
Toshihiro Shimizu 890ddd
						 int dpix_dx, int dpix_dy, int strip_width)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int first_x[2], dx_dcol[2], target[2];
Toshihiro Shimizu 890ddd
	int i, x, y, cols;
Toshihiro Shimizu 890ddd
	int col_value, threshold;
Toshihiro Shimizu 890ddd
	int consec_black_cols, consec_white_cols, black_strip_edge;
Toshihiro Shimizu 890ddd
	TPixel32 *pix, *origin;
Toshihiro Shimizu 890ddd
	int delta_x, delta_pix;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	origin = buffer_rgb + pix_origin;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	first_x[0] = 0;
Toshihiro Shimizu 890ddd
	dx_dcol[0] = 1;
Toshihiro Shimizu 890ddd
	target[0] = strip_width / 2;
Toshihiro Shimizu 890ddd
	first_x[1] = lx - 1;
Toshihiro Shimizu 890ddd
	dx_dcol[1] = -1;
Toshihiro Shimizu 890ddd
	target[1] = lx - 1 - strip_width / 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	threshold = AUTOAL_THRESHOLD * ly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < 2; i++) {
Toshihiro Shimizu 890ddd
		consec_black_cols = 0;
Toshihiro Shimizu 890ddd
		consec_white_cols = 0;
Toshihiro Shimizu 890ddd
		black_strip_edge = 0;
Toshihiro Shimizu 890ddd
		for (x = first_x[i], cols = 0; cols < strip_width; x += dx_dcol[i], cols++) {
Toshihiro Shimizu 890ddd
			col_value = 0;
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				col_value += (pix->r * 2 + pix->g * 5 + pix->b) >> 3;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (col_value < threshold) {
Toshihiro Shimizu 890ddd
				consec_white_cols = 0;
Toshihiro Shimizu 890ddd
				consec_black_cols++;
Toshihiro Shimizu 890ddd
				if (consec_black_cols >= AUTOAL_BLACK_COLS)
Toshihiro Shimizu 890ddd
					black_strip_edge = x;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				consec_black_cols = 0;
Toshihiro Shimizu 890ddd
				consec_white_cols++;
Toshihiro Shimizu 890ddd
				if (consec_white_cols >= AUTOAL_WHITE_COLS && black_strip_edge)
Toshihiro Shimizu 890ddd
					goto found;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
found:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (x = first_x[i], cols = 0; cols < strip_width; x += dx_dcol[i], cols++) {
Toshihiro Shimizu 890ddd
		pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
		for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
			pix->r = pix->g = pix->b = 255;
Toshihiro Shimizu 890ddd
			pix += dpix_dy;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	delta_x = target[i] - black_strip_edge;
Toshihiro Shimizu 890ddd
	delta_pix = delta_x * dpix_dx;
Toshihiro Shimizu 890ddd
	if (delta_x > 0) {
Toshihiro Shimizu 890ddd
		for (x = lx - 1 - delta_x; x >= 0; x--) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				(pix + delta_pix)->r = pix->r;
Toshihiro Shimizu 890ddd
				(pix + delta_pix)->g = pix->g;
Toshihiro Shimizu 890ddd
				(pix + delta_pix)->b = pix->b;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (x = lx - delta_x; x < lx; x++) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				pix->r = pix->g = pix->b = 255;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else if (delta_x < 0) {
Toshihiro Shimizu 890ddd
		for (x = -delta_x; x < lx; x++) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				(pix + delta_pix)->r = pix->r;
Toshihiro Shimizu 890ddd
				(pix + delta_pix)->g = pix->g;
Toshihiro Shimizu 890ddd
				(pix + delta_pix)->b = pix->b;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (x = 0; x < -delta_x; x++) {
Toshihiro Shimizu 890ddd
			pix = origin + x * dpix_dx;
Toshihiro Shimizu 890ddd
			for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
				pix->r = pix->g = pix->b = 255;
Toshihiro Shimizu 890ddd
				pix += dpix_dy;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//static void make_bitcount (int b[256], int count_zeros)
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
//int i, j, xorValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//xorValue = count_zeros ? 0xff : 0;
Toshihiro Shimizu 890ddd
//for (i = 0; i < 256; i++)
Toshihiro Shimizu 890ddd
//  {
Toshihiro Shimizu 890ddd
//  b[i] = 0;
Toshihiro Shimizu 890ddd
//  for (j = i ^ xorValue; j; j &= j - 1)
Toshihiro Shimizu 890ddd
//    b[i]++;
Toshihiro Shimizu 890ddd
//  }
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//static int autoalign_bw (UCHAR *buffer_bw, bool isWB /*true se WB, false se BW*/,
Toshihiro Shimizu 890ddd
//                         int wrap, int lx, int ly, int pix_origin,
Toshihiro Shimizu 890ddd
//			 int dpix_dx, int dpix_dy, int strip_width)
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
/* SOLTANTO PER MAIN SCAN VERTICALE */
Toshihiro Shimizu 890ddd
/* LA PARTE DOPO found FUNZIONA SOLO PER ly MULTIPLO DI 8 */
Toshihiro Shimizu 890ddd
/* LA PARTE PRIMA BUTTA VIA I BYTE FRAZIONARI */
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
int first_x[2], dx_dcol[2], target[2];
Toshihiro Shimizu 890ddd
int i, x, y, cols;
Toshihiro Shimizu 890ddd
int col_value, threshold;
Toshihiro Shimizu 890ddd
int consec_black_cols, consec_white_cols, black_strip_edge;
Toshihiro Shimizu 890ddd
UCHAR *byte, *origin, white;
Toshihiro Shimizu 890ddd
int delta_x, delta_bytes;
Toshihiro Shimizu 890ddd
int ly_bytes, dbytes_dx, dbytes_dybytes;
Toshihiro Shimizu 890ddd
int bitcount[256];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
make_bitcount (bitcount, isWB);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ly_bytes = ly / 8;
Toshihiro Shimizu 890ddd
dbytes_dx = dpix_dx / 8;
Toshihiro Shimizu 890ddd
dbytes_dybytes = dpix_dy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (dpix_dy > 0 && (pix_origin & 7) != 0)
Toshihiro Shimizu 890ddd
  pix_origin = (pix_origin | 7) + 1;
Toshihiro Shimizu 890ddd
if (dpix_dy < 0 && (pix_origin & 7) != 7)
Toshihiro Shimizu 890ddd
  pix_origin = (pix_origin & ~7) - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
origin = buffer_bw + (pix_origin + 7) / 8;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
first_x[0] =      0; dx_dcol[0] =  1; target[0] =          strip_width / 2;
Toshihiro Shimizu 890ddd
first_x[1] = lx - 1; dx_dcol[1] = -1; target[1] = lx - 1 - strip_width / 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
threshold = ly / 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (i = 0; i < 2; i++)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  consec_black_cols = 0;
Toshihiro Shimizu 890ddd
  consec_white_cols = 0;
Toshihiro Shimizu 890ddd
  black_strip_edge  = 0;
Toshihiro Shimizu 890ddd
  for (x = first_x[i], cols = 0; cols < strip_width; x += dx_dcol[i], cols++)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    col_value = 0;
Toshihiro Shimizu 890ddd
    byte = origin + x * dbytes_dx;
Toshihiro Shimizu 890ddd
    for (y = 0; y < ly_bytes; y++)
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      col_value += bitcount[*byte];
Toshihiro Shimizu 890ddd
      byte += dbytes_dybytes;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    if (col_value < threshold)
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      consec_white_cols = 0;
Toshihiro Shimizu 890ddd
      consec_black_cols++;
Toshihiro Shimizu 890ddd
      if (consec_black_cols >= AUTOAL_BLACK_COLS)
Toshihiro Shimizu 890ddd
	black_strip_edge = x;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    else
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      consec_black_cols = 0;
Toshihiro Shimizu 890ddd
      consec_white_cols++;
Toshihiro Shimizu 890ddd
      if (consec_white_cols >= AUTOAL_WHITE_COLS && black_strip_edge)
Toshihiro Shimizu 890ddd
	goto found;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
return FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
found:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
white = isWB ? 0 : 255;
Toshihiro Shimizu 890ddd
for (x = first_x[i], cols = 0; cols < strip_width; x += dx_dcol[i], cols++)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  byte = origin + x * dbytes_dx;
Toshihiro Shimizu 890ddd
  for (y = 0; y < ly_bytes; y++)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    *byte = white;
Toshihiro Shimizu 890ddd
    byte += dbytes_dybytes;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
delta_x = target[i] - black_strip_edge;
Toshihiro Shimizu 890ddd
delta_bytes = delta_x * dbytes_dx;
Toshihiro Shimizu 890ddd
if (delta_x > 0)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  for (x = lx - 1 - delta_x; x >= 0; x--)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    byte = origin + x * dbytes_dx;
Toshihiro Shimizu 890ddd
    for (y = 0; y < ly_bytes; y++)
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      *(byte + delta_bytes) = *byte;
Toshihiro Shimizu 890ddd
      byte += dbytes_dybytes;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  for (x = lx - delta_x; x < lx; x++)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    byte = origin + x * dbytes_dx;
Toshihiro Shimizu 890ddd
    for (y = 0; y < ly_bytes; y++)
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      *byte = white;
Toshihiro Shimizu 890ddd
      byte += dbytes_dybytes;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
else if (delta_x < 0)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  for (x = -delta_x; x < lx; x++)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    byte = origin + x * dbytes_dx;
Toshihiro Shimizu 890ddd
    for (y = 0; y < ly_bytes; y++)
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      *(byte + delta_bytes) = *byte;
Toshihiro Shimizu 890ddd
      byte += dbytes_dybytes;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  for (x = 0; x < -delta_x; x++)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    byte = origin + x * dbytes_dx;
Toshihiro Shimizu 890ddd
    for (y = 0; y < ly_bytes; y++)
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      *byte = white;
Toshihiro Shimizu 890ddd
      byte += dbytes_dybytes;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int do_autoalign(const TRasterImageP &image)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int wrap, lx, ly, mx, my;
Toshihiro Shimizu 890ddd
	int pix_origin, dpix_dx, dpix_dy;
Toshihiro Shimizu 890ddd
	int strip_width;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
Non viene presa in considerazione una eventuale savebox
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
Per adesso non scrivo l'algo per wb con primary scan orizzontale, quindi:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
assert (image->orientation == TOR_LEFTBOT  ||
Toshihiro Shimizu 890ddd
        image->orientation == TOR_RIGHTBOT ||
Toshihiro Shimizu 890ddd
        image->orientation == TOR_LEFTTOP  ||
Toshihiro Shimizu 890ddd
        image->orientation == TOR_RIGHTTOP    );
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	/* DAFARE
Toshihiro Shimizu 890ddd
if (    image->orientation != TOR_LEFTBOT  &&
Toshihiro Shimizu 890ddd
        image->orientation != TOR_RIGHTBOT &&
Toshihiro Shimizu 890ddd
        image->orientation != TOR_LEFTTOP  &&
Toshihiro Shimizu 890ddd
        image->orientation != TOR_RIGHTTOP    )
Toshihiro Shimizu 890ddd
 {
Toshihiro Shimizu 890ddd
  tmsg_error(" autoalign error: bad image orientation");
Toshihiro Shimizu 890ddd
  return FALSE;
Toshihiro Shimizu 890ddd
 }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	// assumo che sia sempre orientata nel modo corretto
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterP ras = image->getRaster();
Toshihiro Shimizu 890ddd
	wrap = ras->getWrap();
Toshihiro Shimizu 890ddd
	assert(TRaster32P(ras) || TRasterGR8P(ras)); //per ricordare di gestire le img bw!
Toshihiro Shimizu 890ddd
	/* DAFARE
Toshihiro Shimizu 890ddd
if (rop_pixbits (image->ras.type) < 8 && rop_fillerbits (image->ras.type))
Toshihiro Shimizu 890ddd
  wrap = (wrap + 7) / 8 * 8;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* DAFARE
Toshihiro Shimizu 890ddd
switch (image->orientation)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  CASE TOR_BOTLEFT:__OR TOR_BOTRIGHT:__OR TOR_TOPLEFT:__OR TOR_TOPRIGHT:
Toshihiro Shimizu 890ddd
    strip_width = mmToPixel (5.0, image->x_dpi);
Toshihiro Shimizu 890ddd
    lx = image->ras.lx;
Toshihiro Shimizu 890ddd
    ly = image->ras.ly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  CASE TOR_LEFTBOT:__OR TOR_RIGHTBOT:__OR TOR_LEFTTOP:__OR TOR_RIGHTTOP:
Toshihiro Shimizu 890ddd
    strip_width = mmToPixel (5.0, image->y_dpi);
Toshihiro Shimizu 890ddd
    lx = image->ras.ly;
Toshihiro Shimizu 890ddd
    ly = image->ras.lx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  DEFAULT: assert (FALSE);lx=ly=strip_width=0;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	//assumo TOR_BOTLEFT:__OR TOR_BOTRIGHT:__OR TOR_TOPLEFT:__OR TOR_TOPRIGHT:
Toshihiro Shimizu 890ddd
	double dpix, dpiy;
Toshihiro Shimizu 890ddd
	image->getDpi(dpix, dpiy);
Toshihiro Shimizu 890ddd
	strip_width = (int)mmToPixel(5.0, dpix);
Toshihiro Shimizu 890ddd
	lx = ras->getLx();
Toshihiro Shimizu 890ddd
	ly = ras->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	mx = lx - 1;
Toshihiro Shimizu 890ddd
	my = ly - 1;
Toshihiro Shimizu 890ddd
	/* DAFARE
Toshihiro Shimizu 890ddd
switch (image->orientation)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  CASE TOR_BOTLEFT:
Toshihiro Shimizu 890ddd
    pix_origin = 0;
Toshihiro Shimizu 890ddd
    dpix_dx =  1;
Toshihiro Shimizu 890ddd
    dpix_dy =  wrap;
Toshihiro Shimizu 890ddd
  CASE TOR_BOTRIGHT:
Toshihiro Shimizu 890ddd
    pix_origin = mx;
Toshihiro Shimizu 890ddd
    dpix_dx = -1;
Toshihiro Shimizu 890ddd
    dpix_dy =  wrap;
Toshihiro Shimizu 890ddd
  CASE TOR_TOPLEFT:
Toshihiro Shimizu 890ddd
    pix_origin = my * wrap;
Toshihiro Shimizu 890ddd
    dpix_dx =  1;
Toshihiro Shimizu 890ddd
    dpix_dy = -wrap;
Toshihiro Shimizu 890ddd
  CASE TOR_TOPRIGHT:
Toshihiro Shimizu 890ddd
    pix_origin = mx + my * wrap;
Toshihiro Shimizu 890ddd
    dpix_dx = -1;
Toshihiro Shimizu 890ddd
    dpix_dy = -wrap;
Toshihiro Shimizu 890ddd
  CASE TOR_LEFTBOT:
Toshihiro Shimizu 890ddd
    pix_origin = 0;
Toshihiro Shimizu 890ddd
    dpix_dx =  wrap;
Toshihiro Shimizu 890ddd
    dpix_dy =  1;
Toshihiro Shimizu 890ddd
  CASE TOR_RIGHTBOT:
Toshihiro Shimizu 890ddd
    pix_origin = mx * wrap;
Toshihiro Shimizu 890ddd
    dpix_dx = -wrap;
Toshihiro Shimizu 890ddd
    dpix_dy =  1;
Toshihiro Shimizu 890ddd
  CASE TOR_LEFTTOP:
Toshihiro Shimizu 890ddd
    pix_origin = my;
Toshihiro Shimizu 890ddd
    dpix_dx =  wrap;
Toshihiro Shimizu 890ddd
    dpix_dy = -1;
Toshihiro Shimizu 890ddd
  CASE TOR_RIGHTTOP:
Toshihiro Shimizu 890ddd
    pix_origin = my + mx * wrap;
Toshihiro Shimizu 890ddd
    dpix_dx = -wrap;
Toshihiro Shimizu 890ddd
    dpix_dy = -1;
Toshihiro Shimizu 890ddd
  DEFAULT: assert(FALSE); pix_origin=dpix_dx=dpix_dy=0;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	//assumo  CASE TOR_BOTLEFT:
Toshihiro Shimizu 890ddd
	pix_origin = 0;
Toshihiro Shimizu 890ddd
	dpix_dx = 1;
Toshihiro Shimizu 890ddd
	dpix_dy = wrap;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterGR8P ras8(ras);
Toshihiro Shimizu 890ddd
	TRaster32P ras32(ras);
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
	int ret = FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (ras8)
Toshihiro Shimizu 890ddd
		ret = autoalign_gr8(ras8->getRawData(), wrap, lx, ly, pix_origin,
Toshihiro Shimizu 890ddd
							dpix_dx, dpix_dy, strip_width);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	else if (ras32)
Toshihiro Shimizu 890ddd
		ret = autoalign_rgb(ras32->pixels(), wrap, lx, ly, pix_origin,
Toshihiro Shimizu 890ddd
							dpix_dx, dpix_dy, strip_width);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		assert(!"Unsupported pixel type");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ras->unlock();
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
  CASE RAS_WB:
Toshihiro Shimizu 890ddd
  __OR RAS_BW:
Toshihiro Shimizu 890ddd
    assert ( !image->ras.bit_offs);
Toshihiro Shimizu 890ddd
    return autoalign_bw (image->ras.buffer, image->ras.type,
Toshihiro Shimizu 890ddd
                         wrap, lx, ly, pix_origin,
Toshihiro Shimizu 890ddd
		         dpix_dx, dpix_dy, strip_width);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  DEFAULT: assert (!"Unsupported alignment\n");
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	return FALSE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*===========================================================================*/
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
     AUTOCENTERING
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
 * Calcoli in millimetri per questa funzione che alla fine restituisce un 
Toshihiro Shimizu 890ddd
 * valore per la striscia di ricerca direttamente in pixel
Toshihiro Shimizu 890ddd
 */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int compute_strip_pixel(FDG_INFO *fdg, double dpi)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i, strip_size_pix;
Toshihiro Shimizu 890ddd
	double half_size, max_half_size, strip_size_mm;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	max_half_size = -1.0;
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)fdg->dots.size(); i++) {
Toshihiro Shimizu 890ddd
		half_size = (double)fdg->dots[i].lx * 0.5;
Toshihiro Shimizu 890ddd
		if (max_half_size < half_size)
Toshihiro Shimizu 890ddd
			max_half_size = half_size;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	strip_size_mm = fdg->dist_ctr_hole_to_edge +
Toshihiro Shimizu 890ddd
					max_half_size +
Toshihiro Shimizu 890ddd
					SECURITY_MARGIN_MM;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	strip_size_pix = (int)mmToPixel(strip_size_mm, dpi);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Debug_flag)
Toshihiro Shimizu 890ddd
		printf("Controllo una striscia larga %g mm e %d pixels\n",
Toshihiro Shimizu 890ddd
			   strip_size_mm, strip_size_pix);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return strip_size_pix;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define SQMM_TO_SQPIXEL(area, x_res, y_res) \
Toshihiro Shimizu 890ddd
	((double)((x_res) * (y_res)) * (double)(area) * ((1.0 / 25.4) * (1.0 / 25.4)))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
void convert_dots_mm_to_pixel(DOT *dots, int nd, double x_res, double y_res)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < nd; i++) {
Toshihiro Shimizu 890ddd
		dots[i].x1 = troundp(mmToPixel(dots[i].x1, x_res));
Toshihiro Shimizu 890ddd
		dots[i].y1 = troundp(mmToPixel(dots[i].y1, y_res));
Toshihiro Shimizu 890ddd
		dots[i].x2 = troundp(mmToPixel(dots[i].x2, x_res));
Toshihiro Shimizu 890ddd
		dots[i].y2 = troundp(mmToPixel(dots[i].y2, y_res));
Toshihiro Shimizu 890ddd
		dots[i].x = (float)mmToPixel(dots[i].x, x_res);
Toshihiro Shimizu 890ddd
		dots[i].y = (float)mmToPixel(dots[i].y, y_res);
Toshihiro Shimizu 890ddd
		dots[i].lx = troundp(mmToPixel(dots[i].lx, x_res));
Toshihiro Shimizu 890ddd
		dots[i].ly = troundp(mmToPixel(dots[i].ly, y_res));
Toshihiro Shimizu 890ddd
		dots[i].area = troundp(SQMM_TO_SQPIXEL(dots[i].area, x_res, y_res));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static char *Done = 0;
Toshihiro Shimizu 890ddd
static int Done_rowsize = 0;
Toshihiro Shimizu 890ddd
static int Done_colsize = 0;
Toshihiro Shimizu 890ddd
#define DONE_MASK(I, J) (1 << (((I) + (J)*Done_rowsize) & 7))
Toshihiro Shimizu 890ddd
#define DONE_BYTE(I, J) (((I) + (J)*Done_rowsize) >> 3)
Toshihiro Shimizu 890ddd
#define SET_DONE(I, J) (Done[DONE_BYTE(I, J)] |= DONE_MASK(I, J))
Toshihiro Shimizu 890ddd
#define NOT_DONE(I, J) (!(Done[DONE_BYTE(I, J)] & DONE_MASK(I, J)))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int Pix_ystep = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef struct big {
Toshihiro Shimizu 890ddd
	unsigned lo, hi;
Toshihiro Shimizu 890ddd
} BIG;
Toshihiro Shimizu 890ddd
#define CLEARBIG(B) ((B).lo = 0, (B).hi = 0, (B))
Toshihiro Shimizu 890ddd
#define ADDBIG(B, X) ((B).lo += (unsigned)(X), \
Toshihiro Shimizu 890ddd
					  (B).hi += (B).lo >> 30, (B).lo &= 0x3fffffff, (B))
Toshihiro Shimizu 890ddd
#define BIG_TO_DOUBLE(B) ((double)(B).hi * (double)0x40000000 + (double)(B).lo)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define IS_BLACK_GR8(PIX) (*(PIX) < 110)
Toshihiro Shimizu 890ddd
#define IS_VERY_BLACK_GR8(PIX) (*(PIX) < 30)
Toshihiro Shimizu 890ddd
#define BLACK_WEIGHT_GR8(PIX) (256 - *(PIX))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define RGBR(PIX) ((PIX)->r << 1)
Toshihiro Shimizu 890ddd
#define RGBG(PIX) ((PIX)->g << 2)
Toshihiro Shimizu 890ddd
#define RGBB(PIX) ((PIX)->b)
Toshihiro Shimizu 890ddd
#define RGBVAL(PIX) (RGBR(PIX) + RGBG(PIX) + RGBB(PIX))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define IS_BLACK_RGB(PIX) (RGBVAL(PIX) < 110 * 7)
Toshihiro Shimizu 890ddd
#define IS_VERY_BLACK_RGB(PIX) (RGBVAL(PIX) < 30 * 7)
Toshihiro Shimizu 890ddd
#define BLACK_WEIGHT_RGB(PIX) ((256 * 7 - RGBVAL(PIX)) >> 3)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static BIG Xsum, Ysum, Weightsum;
Toshihiro Shimizu 890ddd
static int Xmin, Xmax, Ymin, Ymax, Npix;
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
static int Level, Max_level;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
static int Very_black_found;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DAFARE
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
static int Black_pixel = 0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DAFARE
Toshihiro Shimizu 890ddd
static int find_dots_bw(const TRasterP &img, int strip_width, PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
						DOT dotarray[], int dotarray_size, int max_area);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
static int find_dots_gr8(const TRasterGR8P &img, int strip_width, PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
						 DOT dotarray[], int dotarray_size, int max_area);
Toshihiro Shimizu 890ddd
static int find_dots_rgb(const TRaster32P &img, int strip_width, PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
						 DOT dotarray[], int dotarray_size, int max_area);
Toshihiro Shimizu 890ddd
static void
Toshihiro Shimizu 890ddd
#ifdef DAFARE
Toshihiro Shimizu 890ddd
visit_bw(int i, int j, int x, int y, int bit, UCHAR *byte),
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	visit_gr8(int i, int j, int x, int y, UCHAR *pix),
Toshihiro Shimizu 890ddd
	visit_rgb(int i, int j, int x, int y, TPixel32 *pix),
Toshihiro Shimizu 890ddd
	stampa_dot(DOT *dot);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int
Toshihiro Shimizu 890ddd
compare_dots(DOT dots[], int *ndots, DOT reference[], int ref_dot);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define REVERSE(byte, bit)  \
Toshihiro Shimizu 890ddd
	{                       \
Toshihiro Shimizu 890ddd
		unsigned char mask; \
Toshihiro Shimizu 890ddd
		mask = 1 << (bit);  \
Toshihiro Shimizu 890ddd
		*(byte) ^= mask;    \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef struct
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	short ret, bit;
Toshihiro Shimizu 890ddd
	int x, y, i, j;
Toshihiro Shimizu 890ddd
	void *ptr;
Toshihiro Shimizu 890ddd
} STACK_INFO;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static STACK_INFO *Stack = 0;
Toshihiro Shimizu 890ddd
static int Stack_alloc_size = 0;
Toshihiro Shimizu 890ddd
static int Stack_size = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define CREATE_STACK                                                         \
Toshihiro Shimizu 890ddd
	{                                                                        \
Toshihiro Shimizu 890ddd
		assert(!Stack);                                                      \
Toshihiro Shimizu 890ddd
		Stack_alloc_size = 65500;                                            \
Toshihiro Shimizu 890ddd
		Stack_size = 0;                                                      \
Toshihiro Shimizu 890ddd
		Stack = (STACK_INFO *)malloc(Stack_alloc_size * sizeof(STACK_INFO)); \
Toshihiro Shimizu 890ddd
		if (!Stack)                                                          \
Toshihiro Shimizu 890ddd
			return FALSE;                                                    \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define DESTROY_STACK         \
Toshihiro Shimizu 890ddd
	{                         \
Toshihiro Shimizu 890ddd
		Stack_alloc_size = 0; \
Toshihiro Shimizu 890ddd
		Stack_size = 0;       \
Toshihiro Shimizu 890ddd
		free(Stack);          \
Toshihiro Shimizu 890ddd
		Stack = 0;            \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define STACK_IS_EMPTY (!Stack_size)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define PUSH_ONTO_STACK(RET, X, Y, I, J, BIT, PTR)                                       \
Toshihiro Shimizu 890ddd
	{                                                                                    \
Toshihiro Shimizu 890ddd
		if (Stack_size >= Stack_alloc_size) {                                            \
Toshihiro Shimizu 890ddd
			Stack_alloc_size += 65500;                                                   \
Toshihiro Shimizu 890ddd
			Stack = (STACK_INFO *)realloc(Stack, Stack_alloc_size * sizeof(STACK_INFO)); \
Toshihiro Shimizu 890ddd
			if (!Stack)                                                                  \
Toshihiro Shimizu 890ddd
				return;                                                                  \
Toshihiro Shimizu 890ddd
		}                                                                                \
Toshihiro Shimizu 890ddd
		Stack[Stack_size].ret = (RET);                                                   \
Toshihiro Shimizu 890ddd
		Stack[Stack_size].x = (X);                                                       \
Toshihiro Shimizu 890ddd
		Stack[Stack_size].y = (Y);                                                       \
Toshihiro Shimizu 890ddd
		Stack[Stack_size].i = (I);                                                       \
Toshihiro Shimizu 890ddd
		Stack[Stack_size].j = (J);                                                       \
Toshihiro Shimizu 890ddd
		Stack[Stack_size].bit = (BIT);                                                   \
Toshihiro Shimizu 890ddd
		Stack[Stack_size].ptr = (PTR);                                                   \
Toshihiro Shimizu 890ddd
		Stack_size++;                                                                    \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define POP_FROM_STACK_U(RET, X, Y, I, J, BIT, PTR) \
Toshihiro Shimizu 890ddd
	{                                               \
Toshihiro Shimizu 890ddd
		Stack_size--;                               \
Toshihiro Shimizu 890ddd
		(RET) = Stack[Stack_size].ret;              \
Toshihiro Shimizu 890ddd
		(X) = Stack[Stack_size].x;                  \
Toshihiro Shimizu 890ddd
		(Y) = Stack[Stack_size].y;                  \
Toshihiro Shimizu 890ddd
		(I) = Stack[Stack_size].i;                  \
Toshihiro Shimizu 890ddd
		(J) = Stack[Stack_size].j;                  \
Toshihiro Shimizu 890ddd
		(BIT) = Stack[Stack_size].bit;              \
Toshihiro Shimizu 890ddd
		(PTR) = (UCHAR *)Stack[Stack_size].ptr;     \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define POP_FROM_STACK_TPIXEL32(RET, X, Y, I, J, BIT, PTR) \
Toshihiro Shimizu 890ddd
	{                                                      \
Toshihiro Shimizu 890ddd
		Stack_size--;                                      \
Toshihiro Shimizu 890ddd
		(RET) = Stack[Stack_size].ret;                     \
Toshihiro Shimizu 890ddd
		(X) = Stack[Stack_size].x;                         \
Toshihiro Shimizu 890ddd
		(Y) = Stack[Stack_size].y;                         \
Toshihiro Shimizu 890ddd
		(I) = Stack[Stack_size].i;                         \
Toshihiro Shimizu 890ddd
		(J) = Stack[Stack_size].j;                         \
Toshihiro Shimizu 890ddd
		(BIT) = Stack[Stack_size].bit;                     \
Toshihiro Shimizu 890ddd
		(PTR) = (TPixel32 *)Stack[Stack_size].ptr;         \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int find_dots(const TRasterP &img, int strip_width, PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
					 DOT dotarray[], int dotarray_size, int max_area)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P ras32(img);
Toshihiro Shimizu 890ddd
	if (ras32)
Toshihiro Shimizu 890ddd
		return find_dots_rgb(ras32, strip_width, pegs_side, dotarray, dotarray_size,
Toshihiro Shimizu 890ddd
							 max_area);
Toshihiro Shimizu 890ddd
	TRasterGR8P ras8(img);
Toshihiro Shimizu 890ddd
	if (ras8)
Toshihiro Shimizu 890ddd
		return find_dots_gr8(ras8, strip_width, pegs_side, dotarray, dotarray_size,
Toshihiro Shimizu 890ddd
							 max_area);
Toshihiro Shimizu 890ddd
	assert(!"Unsupported pixel type");
Toshihiro Shimizu 890ddd
	/* DAFARE
Toshihiro Shimizu 890ddd
  CASE RAS_BW:
Toshihiro Shimizu 890ddd
  __OR RAS_WB:
Toshihiro Shimizu 890ddd
    return find_dots_bw (img, strip_width, pegs_side, dotarray, dotarray_size,
Toshihiro Shimizu 890ddd
                              max_area);
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
#ifdef DAFARE
Toshihiro Shimizu 890ddd
static int find_dots_bw(const TRasterP &img, int strip_width, PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
						DOT dotarray[], int dotarray_size, int max_area)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int n_dots, ins, shift;
Toshihiro Shimizu 890ddd
	int x, y; // coords in img coord system
Toshihiro Shimizu 890ddd
	int i, j; // coords in done coord system
Toshihiro Shimizu 890ddd
	int x0, y0, xsize, ysize, xlast, ylast, bit;
Toshihiro Shimizu 890ddd
	UCHAR *byte, *buffer;
Toshihiro Shimizu 890ddd
	int dot_lx, dot_ly;
Toshihiro Shimizu 890ddd
	float dot_x, dot_y;
Toshihiro Shimizu 890ddd
	int vertical;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (img->type == RAS_WB)
Toshihiro Shimizu 890ddd
		Black_pixel = 1;
Toshihiro Shimizu 890ddd
	else if (img->type == RAS_BW)
Toshihiro Shimizu 890ddd
		Black_pixel = 0;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		TERROR("find dots error: bad image type");
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (pegs_side) {
Toshihiro Shimizu 890ddd
		CASE PEGS_BOTTOM : __OR PEGS_TOP : x0 = 0;
Toshihiro Shimizu 890ddd
		y0 = pegs_side == PEGS_BOTTOM ? 0 : img->ly - strip_width;
Toshihiro Shimizu 890ddd
		xsize = img->lx;
Toshihiro Shimizu 890ddd
		ysize = strip_width;
Toshihiro Shimizu 890ddd
		vertical = FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		CASE PEGS_LEFT : __OR PEGS_RIGHT : x0 = pegs_side == PEGS_LEFT ? 0 : img->lx - strip_width;
Toshihiro Shimizu 890ddd
		y0 = 0;
Toshihiro Shimizu 890ddd
		xsize = strip_width;
Toshihiro Shimizu 890ddd
		ysize = img->ly;
Toshihiro Shimizu 890ddd
		vertical = TRUE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DEFAULT : {
Toshihiro Shimizu 890ddd
		ostrstream os;
Toshihiro Shimizu 890ddd
		os << "find dots internal error: pegs_side = " << std::hex << pegs_side << '\0';
Toshihiro Shimizu 890ddd
		os.freeze(false);
Toshihiro Shimizu 890ddd
		throw TCleanupException(os.str());
Toshihiro Shimizu 890ddd
		x0 = y0 = xsize = ysize = vertical = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	xlast = x0 + xsize - 1;
Toshihiro Shimizu 890ddd
	ylast = y0 + ysize - 1;
Toshihiro Shimizu 890ddd
	n_dots = 0;
Toshihiro Shimizu 890ddd
	Done_rowsize = xsize + 2;
Toshihiro Shimizu 890ddd
	Done_colsize = ysize + 2;
Toshihiro Shimizu 890ddd
	Done = (char *)calloc((size_t)((Done_rowsize * Done_colsize + 7) >> 3), sizeof(char));
Toshihiro Shimizu 890ddd
	if (!Done) {
Toshihiro Shimizu 890ddd
		throw TCleanupException("find_dots: out of memory");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (i = 0; i < Done_rowsize; i++) {
Toshihiro Shimizu 890ddd
		SET_DONE(i, 0);
Toshihiro Shimizu 890ddd
		SET_DONE(i, Done_colsize - 1);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (j = 0; j < Done_colsize; j++) {
Toshihiro Shimizu 890ddd
		SET_DONE(0, j);
Toshihiro Shimizu 890ddd
		SET_DONE(Done_rowsize - 1, j);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	buffer = (UCHAR *)img->buffer;
Toshihiro Shimizu 890ddd
	Pix_ystep = (img->wrap + 7) >> 3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Debug_flag) {
Toshihiro Shimizu 890ddd
		printf("Zona di scansione: (%d,%d) -- (%d,%d)\n",
Toshihiro Shimizu 890ddd
			   x0, y0, xlast, ylast);
Toshihiro Shimizu 890ddd
		printf("wrap: %d\n", img->wrap);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
	Max_level = max_area * 6 / 5;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CREATE_STACK
Toshihiro Shimizu 890ddd
	for (j = 1, y = y0; y <= ylast; j++, y++) {
Toshihiro Shimizu 890ddd
		bit = 7 - (x0 & 7);
Toshihiro Shimizu 890ddd
		byte = buffer + (x0 >> 3) + y * Pix_ystep;
Toshihiro Shimizu 890ddd
		for (i = 1, x = x0; x <= xlast; i++, x++) {
Toshihiro Shimizu 890ddd
			if (NOT_DONE(i, j) && ((*byte >> bit) & 1) == Black_pixel) {
Toshihiro Shimizu 890ddd
				CLEARBIG(Xsum);
Toshihiro Shimizu 890ddd
				CLEARBIG(Ysum);
Toshihiro Shimizu 890ddd
				CLEARBIG(Weightsum);
Toshihiro Shimizu 890ddd
				Xmin = Xmax = x;
Toshihiro Shimizu 890ddd
				Ymin = Ymax = y;
Toshihiro Shimizu 890ddd
				Npix = 0;
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
				Level = 0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
				visit_bw(i, j, x, y, bit, byte);
Toshihiro Shimizu 890ddd
				dot_lx = Xmax - Xmin + 1;
Toshihiro Shimizu 890ddd
				dot_ly = Ymax - Ymin + 1;
Toshihiro Shimizu 890ddd
				if (Npix < max_area * 3 / 2 &&
Toshihiro Shimizu 890ddd
					dot_lx > 3 && dot_lx < (xsize >> 1) &&
Toshihiro Shimizu 890ddd
					dot_ly > 3 && dot_ly < (ysize >> 1) &&
Toshihiro Shimizu 890ddd
					Xmin > x0 && Xmax < xlast &&
Toshihiro Shimizu 890ddd
					Ymin > y0 && Ymax < ylast) {
Toshihiro Shimizu 890ddd
					dot_x = BIG_TO_DOUBLE(Xsum) / BIG_TO_DOUBLE(Weightsum);
Toshihiro Shimizu 890ddd
					dot_y = BIG_TO_DOUBLE(Ysum) / BIG_TO_DOUBLE(Weightsum);
Toshihiro Shimizu 890ddd
					if (vertical) {
Toshihiro Shimizu 890ddd
						for (ins = 0; ins < n_dots; ins++)
Toshihiro Shimizu 890ddd
							if (dotarray[ins].y > dot_y)
Toshihiro Shimizu 890ddd
								break;
Toshihiro Shimizu 890ddd
					} else {
Toshihiro Shimizu 890ddd
						for (ins = 0; ins < n_dots; ins++)
Toshihiro Shimizu 890ddd
							if (dotarray[ins].x > dot_x)
Toshihiro Shimizu 890ddd
								break;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					for (shift = n_dots - 1; shift >= ins; shift--)
Toshihiro Shimizu 890ddd
						dotarray[shift + 1] = dotarray[shift];
Toshihiro Shimizu 890ddd
					n_dots++;
Toshihiro Shimizu 890ddd
					dotarray[ins].x1 = Xmin;
Toshihiro Shimizu 890ddd
					dotarray[ins].x2 = Xmax;
Toshihiro Shimizu 890ddd
					dotarray[ins].y1 = Ymin;
Toshihiro Shimizu 890ddd
					dotarray[ins].y2 = Ymax;
Toshihiro Shimizu 890ddd
					dotarray[ins].lx = dot_lx;
Toshihiro Shimizu 890ddd
					dotarray[ins].ly = dot_ly;
Toshihiro Shimizu 890ddd
					dotarray[ins].area = Npix;
Toshihiro Shimizu 890ddd
					dotarray[ins].x = dot_x;
Toshihiro Shimizu 890ddd
					dotarray[ins].y = dot_y;
Toshihiro Shimizu 890ddd
					if (n_dots >= dotarray_size)
Toshihiro Shimizu 890ddd
						goto end_loop;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (bit == 0) {
Toshihiro Shimizu 890ddd
				bit = 7;
Toshihiro Shimizu 890ddd
				byte++;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				bit--;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
end_loop:
Toshihiro Shimizu 890ddd
	DESTROY_STACK
Toshihiro Shimizu 890ddd
	free(Done);
Toshihiro Shimizu 890ddd
	Done = NIL;
Toshihiro Shimizu 890ddd
	return n_dots;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int find_dots_gr8(const TRasterGR8P &img, int strip_width, PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
						 DOT dotarray[], int dotarray_size, int max_area)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int n_dots, ins, shift;
Toshihiro Shimizu 890ddd
	int x, y; /* coords in img coord system */
Toshihiro Shimizu 890ddd
	int i, j; /* coords in done coord system */
Toshihiro Shimizu 890ddd
	int x0, y0, xsize, ysize, xlast, ylast;
Toshihiro Shimizu 890ddd
	UCHAR *pix, *buffer;
Toshihiro Shimizu 890ddd
	int dot_lx, dot_ly;
Toshihiro Shimizu 890ddd
	float dot_x, dot_y;
Toshihiro Shimizu 890ddd
	int vertical;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (pegs_side) {
Toshihiro Shimizu 890ddd
		CASE PEGS_BOTTOM : __OR PEGS_TOP : x0 = 0;
Toshihiro Shimizu 890ddd
		y0 = pegs_side == PEGS_BOTTOM ? 0 : img->getLy() - strip_width;
Toshihiro Shimizu 890ddd
		xsize = img->getLx();
Toshihiro Shimizu 890ddd
		ysize = strip_width;
Toshihiro Shimizu 890ddd
		vertical = FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		CASE PEGS_LEFT : __OR PEGS_RIGHT : x0 = pegs_side == PEGS_LEFT ? 0 : img->getLx() - strip_width;
Toshihiro Shimizu 890ddd
		y0 = 0;
Toshihiro Shimizu 890ddd
		xsize = strip_width;
Toshihiro Shimizu 890ddd
		ysize = img->getLy();
Toshihiro Shimizu 890ddd
		vertical = TRUE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DEFAULT : {
Toshihiro Shimizu 890ddd
		ostrstream os;
Toshihiro Shimizu 890ddd
		os << "find dots internal error: pegs_side = " << std::hex << pegs_side << '\0';
Toshihiro Shimizu 890ddd
		os.freeze(false);
Toshihiro Shimizu 890ddd
		throw TCleanupException(os.str());
Toshihiro Shimizu 890ddd
		x0 = y0 = xsize = ysize = vertical = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	xlast = x0 + xsize - 1;
Toshihiro Shimizu 890ddd
	ylast = y0 + ysize - 1;
Toshihiro Shimizu 890ddd
	n_dots = 0;
Toshihiro Shimizu 890ddd
	Done_rowsize = xsize + 2;
Toshihiro Shimizu 890ddd
	Done_colsize = ysize + 2;
Toshihiro Shimizu 890ddd
	Done = (char *)calloc((size_t)((Done_rowsize * Done_colsize + 7) >> 3), sizeof(char));
Toshihiro Shimizu 890ddd
	if (!Done) {
Toshihiro Shimizu 890ddd
		throw TCleanupException("find_dots: out of memory");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (i = 0; i < Done_rowsize; i++) {
Toshihiro Shimizu 890ddd
		SET_DONE(i, 0);
Toshihiro Shimizu 890ddd
		SET_DONE(i, Done_colsize - 1);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (j = 0; j < Done_colsize; j++) {
Toshihiro Shimizu 890ddd
		SET_DONE(0, j);
Toshihiro Shimizu 890ddd
		SET_DONE(Done_rowsize - 1, j);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Pix_ystep = img->getWrap();
Toshihiro Shimizu 890ddd
	if (Debug_flag) {
Toshihiro Shimizu 890ddd
		printf("Zona di scansione: (%d,%d) -- (%d,%d)\n",
Toshihiro Shimizu 890ddd
			   x0, y0, xlast, ylast);
Toshihiro Shimizu 890ddd
		printf("wrap: %d\n", img->getWrap());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
	Max_level = max_area * 6 / 5;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	img->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer = (UCHAR *)img->getRawData();
Toshihiro Shimizu 890ddd
	CREATE_STACK
Toshihiro Shimizu 890ddd
	for (j = 1, y = y0; y <= ylast; j++, y++)
Toshihiro Shimizu 890ddd
		for (i = 1, x = x0, pix = buffer + x0 + y * Pix_ystep; x <= xlast; i++, x++, pix++)
Toshihiro Shimizu 890ddd
			if (NOT_DONE(i, j) && IS_BLACK_GR8(pix)) {
Toshihiro Shimizu 890ddd
				CLEARBIG(Xsum);
Toshihiro Shimizu 890ddd
				CLEARBIG(Ysum);
Toshihiro Shimizu 890ddd
				CLEARBIG(Weightsum);
Toshihiro Shimizu 890ddd
				Xmin = Xmax = x;
Toshihiro Shimizu 890ddd
				Ymin = Ymax = y;
Toshihiro Shimizu 890ddd
				Npix = 0;
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
				Level = 0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
				visit_gr8(i, j, x, y, pix);
Toshihiro Shimizu 890ddd
				dot_lx = Xmax - Xmin + 1;
Toshihiro Shimizu 890ddd
				dot_ly = Ymax - Ymin + 1;
Toshihiro Shimizu 890ddd
				if (Npix < max_area * 3 / 2 &&
Toshihiro Shimizu 890ddd
					dot_lx > 3 && dot_lx < (xsize >> 1) &&
Toshihiro Shimizu 890ddd
					dot_ly > 3 && dot_ly < (ysize >> 1) &&
Toshihiro Shimizu 890ddd
					Xmin > x0 && Xmax < xlast &&
Toshihiro Shimizu 890ddd
					Ymin > y0 && Ymax < ylast) {
Toshihiro Shimizu 890ddd
					dot_x = (float)(BIG_TO_DOUBLE(Xsum) / BIG_TO_DOUBLE(Weightsum));
Toshihiro Shimizu 890ddd
					dot_y = (float)(BIG_TO_DOUBLE(Ysum) / BIG_TO_DOUBLE(Weightsum));
Toshihiro Shimizu 890ddd
					if (vertical) {
Toshihiro Shimizu 890ddd
						for (ins = 0; ins < n_dots; ins++)
Toshihiro Shimizu 890ddd
							if (dotarray[ins].y > dot_y)
Toshihiro Shimizu 890ddd
								break;
Toshihiro Shimizu 890ddd
					} else {
Toshihiro Shimizu 890ddd
						for (ins = 0; ins < n_dots; ins++)
Toshihiro Shimizu 890ddd
							if (dotarray[ins].x > dot_x)
Toshihiro Shimizu 890ddd
								break;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					for (shift = n_dots - 1; shift >= ins; shift--)
Toshihiro Shimizu 890ddd
						dotarray[shift + 1] = dotarray[shift];
Toshihiro Shimizu 890ddd
					n_dots++;
Toshihiro Shimizu 890ddd
					dotarray[ins].x1 = Xmin;
Toshihiro Shimizu 890ddd
					dotarray[ins].x2 = Xmax;
Toshihiro Shimizu 890ddd
					dotarray[ins].y1 = Ymin;
Toshihiro Shimizu 890ddd
					dotarray[ins].y2 = Ymax;
Toshihiro Shimizu 890ddd
					dotarray[ins].lx = dot_lx;
Toshihiro Shimizu 890ddd
					dotarray[ins].ly = dot_ly;
Toshihiro Shimizu 890ddd
					dotarray[ins].area = Npix;
Toshihiro Shimizu 890ddd
					dotarray[ins].x = dot_x;
Toshihiro Shimizu 890ddd
					dotarray[ins].y = dot_y;
Toshihiro Shimizu 890ddd
					if (n_dots >= dotarray_size)
Toshihiro Shimizu 890ddd
						goto end_loop;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
end_loop:
Toshihiro Shimizu 890ddd
	DESTROY_STACK
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	free(Done);
Toshihiro Shimizu 890ddd
	Done = 0;
Toshihiro Shimizu 890ddd
	img->unlock();
Toshihiro Shimizu 890ddd
	return n_dots;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int find_dots_rgb(const TRaster32P &img, int strip_width, PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
						 DOT dotarray[], int dotarray_size, int max_area)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int n_dots, ins, shift;
Toshihiro Shimizu 890ddd
	int x, y; /* coords in img coord system */
Toshihiro Shimizu 890ddd
	int i, j; /* coords in done coord system */
Toshihiro Shimizu 890ddd
	int x0, y0, xsize, ysize, xlast, ylast;
Toshihiro Shimizu 890ddd
	TPixel32 *pix, *buffer;
Toshihiro Shimizu 890ddd
	int dot_lx, dot_ly;
Toshihiro Shimizu 890ddd
	float dot_x, dot_y;
Toshihiro Shimizu 890ddd
	int vertical;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(img->getPixelSize() == 4); /*questo e' per ricordare che l'algo e' per RGB*/
Toshihiro Shimizu 890ddd
	switch (pegs_side) {
Toshihiro Shimizu 890ddd
		CASE PEGS_BOTTOM : __OR PEGS_TOP : x0 = 0;
Toshihiro Shimizu 890ddd
		y0 = pegs_side == PEGS_BOTTOM ? 0 : img->getLy() - strip_width;
Toshihiro Shimizu 890ddd
		xsize = img->getLx();
Toshihiro Shimizu 890ddd
		ysize = strip_width;
Toshihiro Shimizu 890ddd
		vertical = FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		CASE PEGS_LEFT : __OR PEGS_RIGHT : x0 = pegs_side == PEGS_LEFT ? 0 : img->getLx() - strip_width;
Toshihiro Shimizu 890ddd
		y0 = 0;
Toshihiro Shimizu 890ddd
		xsize = strip_width;
Toshihiro Shimizu 890ddd
		ysize = img->getLy();
Toshihiro Shimizu 890ddd
		vertical = TRUE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DEFAULT : {
Toshihiro Shimizu 890ddd
		ostrstream os;
Toshihiro Shimizu 890ddd
		os << "find dots internal error: pegs_side = " << std::hex << pegs_side << '\0';
Toshihiro Shimizu 890ddd
		os.freeze(false);
Toshihiro Shimizu 890ddd
		throw TCleanupException(os.str());
Toshihiro Shimizu 890ddd
		x0 = y0 = xsize = ysize = vertical = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	xlast = x0 + xsize - 1;
Toshihiro Shimizu 890ddd
	ylast = y0 + ysize - 1;
Toshihiro Shimizu 890ddd
	n_dots = 0;
Toshihiro Shimizu 890ddd
	Done_rowsize = xsize + 2;
Toshihiro Shimizu 890ddd
	Done_colsize = ysize + 2;
Toshihiro Shimizu 890ddd
	Done = (char *)calloc((size_t)((Done_rowsize * Done_colsize + 7) >> 3), sizeof(char));
Toshihiro Shimizu 890ddd
	if (!Done) {
Toshihiro Shimizu 890ddd
		throw TCleanupException("find_dots: out of memory");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (i = 0; i < Done_rowsize; i++) {
Toshihiro Shimizu 890ddd
		SET_DONE(i, 0);
Toshihiro Shimizu 890ddd
		SET_DONE(i, Done_colsize - 1);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (j = 0; j < Done_colsize; j++) {
Toshihiro Shimizu 890ddd
		SET_DONE(0, j);
Toshihiro Shimizu 890ddd
		SET_DONE(Done_rowsize - 1, j);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	buffer = img->pixels();
Toshihiro Shimizu 890ddd
	Pix_ystep = img->getWrap();
Toshihiro Shimizu 890ddd
	if (Debug_flag) {
Toshihiro Shimizu 890ddd
		printf("Zona di scansione: (%d,%d) -- (%d,%d)\n",
Toshihiro Shimizu 890ddd
			   x0, y0, xlast, ylast);
Toshihiro Shimizu 890ddd
		printf("wrap: %d\n", img->getWrap());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
	Max_level = max_area * 6 / 5;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CREATE_STACK
Toshihiro Shimizu 890ddd
	for (j = 1, y = y0; y <= ylast; j++, y++)
Toshihiro Shimizu 890ddd
		for (i = 1, x = x0, pix = buffer + x0 + y * Pix_ystep; x <= xlast; i++, x++, pix++)
Toshihiro Shimizu 890ddd
			if (NOT_DONE(i, j) && IS_BLACK_RGB(pix)) {
Toshihiro Shimizu 890ddd
				CLEARBIG(Xsum);
Toshihiro Shimizu 890ddd
				CLEARBIG(Ysum);
Toshihiro Shimizu 890ddd
				CLEARBIG(Weightsum);
Toshihiro Shimizu 890ddd
				Xmin = Xmax = x;
Toshihiro Shimizu 890ddd
				Ymin = Ymax = y;
Toshihiro Shimizu 890ddd
				Npix = 0;
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
				Level = 0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
				visit_rgb(i, j, x, y, pix);
Toshihiro Shimizu 890ddd
				dot_lx = Xmax - Xmin + 1;
Toshihiro Shimizu 890ddd
				dot_ly = Ymax - Ymin + 1;
Toshihiro Shimizu 890ddd
				if (Npix < max_area * 3 / 2 &&
Toshihiro Shimizu 890ddd
					dot_lx > 3 && dot_lx < (xsize >> 1) &&
Toshihiro Shimizu 890ddd
					dot_ly > 3 && dot_ly < (ysize >> 1) &&
Toshihiro Shimizu 890ddd
					Xmin > x0 && Xmax < xlast &&
Toshihiro Shimizu 890ddd
					Ymin > y0 && Ymax < ylast) {
Toshihiro Shimizu 890ddd
					dot_x = (float)(BIG_TO_DOUBLE(Xsum) / BIG_TO_DOUBLE(Weightsum));
Toshihiro Shimizu 890ddd
					dot_y = (float)(BIG_TO_DOUBLE(Ysum) / BIG_TO_DOUBLE(Weightsum));
Toshihiro Shimizu 890ddd
					if (vertical) {
Toshihiro Shimizu 890ddd
						for (ins = 0; ins < n_dots; ins++)
Toshihiro Shimizu 890ddd
							if (dotarray[ins].y > dot_y)
Toshihiro Shimizu 890ddd
								break;
Toshihiro Shimizu 890ddd
					} else {
Toshihiro Shimizu 890ddd
						for (ins = 0; ins < n_dots; ins++)
Toshihiro Shimizu 890ddd
							if (dotarray[ins].x > dot_x)
Toshihiro Shimizu 890ddd
								break;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					for (shift = n_dots - 1; shift >= ins; shift--)
Toshihiro Shimizu 890ddd
						dotarray[shift + 1] = dotarray[shift];
Toshihiro Shimizu 890ddd
					n_dots++;
Toshihiro Shimizu 890ddd
					dotarray[ins].x1 = Xmin;
Toshihiro Shimizu 890ddd
					dotarray[ins].x2 = Xmax;
Toshihiro Shimizu 890ddd
					dotarray[ins].y1 = Ymin;
Toshihiro Shimizu 890ddd
					dotarray[ins].y2 = Ymax;
Toshihiro Shimizu 890ddd
					dotarray[ins].lx = dot_lx;
Toshihiro Shimizu 890ddd
					dotarray[ins].ly = dot_ly;
Toshihiro Shimizu 890ddd
					dotarray[ins].area = Npix;
Toshihiro Shimizu 890ddd
					dotarray[ins].x = dot_x;
Toshihiro Shimizu 890ddd
					dotarray[ins].y = dot_y;
Toshihiro Shimizu 890ddd
					if (n_dots >= dotarray_size)
Toshihiro Shimizu 890ddd
						goto end_loop;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
end_loop:
Toshihiro Shimizu 890ddd
	DESTROY_STACK
Toshihiro Shimizu 890ddd
	free(Done);
Toshihiro Shimizu 890ddd
	Done = 0;
Toshihiro Shimizu 890ddd
	return n_dots;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
#ifdef DAFARE
Toshihiro Shimizu 890ddd
static void visit_bw(int i, int j, int x, int y, int bit, UCHAR *byte)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int ret, next_bit, prev_bit;
Toshihiro Shimizu 890ddd
	UCHAR *next_byte, *prev_byte;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
start:
Toshihiro Shimizu 890ddd
	ADDBIG(Xsum, x);
Toshihiro Shimizu 890ddd
	ADDBIG(Ysum, y);
Toshihiro Shimizu 890ddd
	ADDBIG(Weightsum, 1);
Toshihiro Shimizu 890ddd
	if (x < Xmin)
Toshihiro Shimizu 890ddd
		Xmin = x;
Toshihiro Shimizu 890ddd
	if (x > Xmax)
Toshihiro Shimizu 890ddd
		Xmax = x;
Toshihiro Shimizu 890ddd
	if (y < Ymin)
Toshihiro Shimizu 890ddd
		Ymin = y;
Toshihiro Shimizu 890ddd
	if (y > Ymax)
Toshihiro Shimizu 890ddd
		Ymax = y;
Toshihiro Shimizu 890ddd
	Npix++;
Toshihiro Shimizu 890ddd
	SET_DONE(i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	next_bit = bit - 1;
Toshihiro Shimizu 890ddd
	if (next_bit < 0) {
Toshihiro Shimizu 890ddd
		next_bit = 7;
Toshihiro Shimizu 890ddd
		next_byte = byte + 1;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		next_byte = byte;
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i + 1, j) && ((*next_byte >> next_bit) & 1) == Black_pixel) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(1, x, y, i, j, bit, byte)
Toshihiro Shimizu 890ddd
		i++;
Toshihiro Shimizu 890ddd
		x++;
Toshihiro Shimizu 890ddd
		bit = next_bit;
Toshihiro Shimizu 890ddd
		byte = next_byte;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_1:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	prev_bit = bit + 1;
Toshihiro Shimizu 890ddd
	if (prev_bit > 7) {
Toshihiro Shimizu 890ddd
		prev_bit = 0;
Toshihiro Shimizu 890ddd
		prev_byte = byte - 1;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		prev_byte = byte;
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i - 1, j) && ((*prev_byte >> prev_bit) & 1) == Black_pixel) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(2, x, y, i, j, bit, byte)
Toshihiro Shimizu 890ddd
		i--;
Toshihiro Shimizu 890ddd
		x--;
Toshihiro Shimizu 890ddd
		bit = prev_bit;
Toshihiro Shimizu 890ddd
		byte = prev_byte;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_2:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j + 1) && ((*(byte + Pix_ystep) >> bit) & 1) == Black_pixel) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(3, x, y, i, j, bit, byte)
Toshihiro Shimizu 890ddd
		j++;
Toshihiro Shimizu 890ddd
		y++;
Toshihiro Shimizu 890ddd
		byte += Pix_ystep;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_3:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j - 1) && ((*(byte - Pix_ystep) >> bit) & 1) == Black_pixel) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(4, x, y, i, j, bit, byte)
Toshihiro Shimizu 890ddd
		j--;
Toshihiro Shimizu 890ddd
		y--;
Toshihiro Shimizu 890ddd
		byte -= Pix_ystep;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_4:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!STACK_IS_EMPTY) {
Toshihiro Shimizu 890ddd
		POP_FROM_STACK_U(ret, x, y, i, j, bit, byte);
Toshihiro Shimizu 890ddd
		switch (ret) {
Toshihiro Shimizu 890ddd
			CASE 1 : goto return_1;
Toshihiro Shimizu 890ddd
			CASE 2 : goto return_2;
Toshihiro Shimizu 890ddd
			CASE 3 : goto return_3;
Toshihiro Shimizu 890ddd
			CASE 4 : goto return_4;
Toshihiro Shimizu 890ddd
		DEFAULT:
Toshihiro Shimizu 890ddd
			abort();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void visit_bw(int i, int j, int x, int y, int bit, UCHAR *byte)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int next_bit, prev_bit;
Toshihiro Shimizu 890ddd
	UCHAR *next_byte, *prev_byte;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Level >= Max_level)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		Level++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ADDBIG(Xsum, x);
Toshihiro Shimizu 890ddd
	ADDBIG(Ysum, y);
Toshihiro Shimizu 890ddd
	ADDBIG(Weightsum, 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (x < Xmin)
Toshihiro Shimizu 890ddd
		Xmin = x;
Toshihiro Shimizu 890ddd
	if (x > Xmax)
Toshihiro Shimizu 890ddd
		Xmax = x;
Toshihiro Shimizu 890ddd
	if (y < Ymin)
Toshihiro Shimizu 890ddd
		Ymin = y;
Toshihiro Shimizu 890ddd
	if (y > Ymax)
Toshihiro Shimizu 890ddd
		Ymax = y;
Toshihiro Shimizu 890ddd
	Npix++;
Toshihiro Shimizu 890ddd
	SET_DONE(i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	next_bit = bit - 1;
Toshihiro Shimizu 890ddd
	if (next_bit < 0) {
Toshihiro Shimizu 890ddd
		next_byte = byte + 1;
Toshihiro Shimizu 890ddd
		next_bit = 7;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		next_byte = byte;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	prev_bit = bit + 1;
Toshihiro Shimizu 890ddd
	if (prev_bit > 7) {
Toshihiro Shimizu 890ddd
		prev_byte = byte - 1;
Toshihiro Shimizu 890ddd
		prev_bit = 0;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		prev_byte = byte;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i + 1, j) && ((*next_byte >> next_bit) & 1) == Black_pixel)
Toshihiro Shimizu 890ddd
		visit_bw(i + 1, j, x + 1, y, next_bit, next_byte);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i - 1, j) && ((*prev_byte >> prev_bit) & 1) == Black_pixel)
Toshihiro Shimizu 890ddd
		visit_bw(i - 1, j, x - 1, y, prev_bit, prev_byte);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j + 1) && ((*(byte + Pix_ystep) >> bit) & 1) == Black_pixel)
Toshihiro Shimizu 890ddd
		visit_bw(i, j + 1, x, y + 1, bit, byte + Pix_ystep);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j - 1) && ((*(byte - Pix_ystep) >> bit) & 1) == Black_pixel)
Toshihiro Shimizu 890ddd
		visit_bw(i, j - 1, x, y - 1, bit, byte - Pix_ystep);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Level--;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void visit_gr8(int i, int j, int x, int y, UCHAR *pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int weight, ret, dummy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
start:
Toshihiro Shimizu 890ddd
	weight = BLACK_WEIGHT_GR8(pix);
Toshihiro Shimizu 890ddd
	ADDBIG(Xsum, x * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Ysum, y * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Weightsum, weight);
Toshihiro Shimizu 890ddd
	if (IS_VERY_BLACK_GR8(pix))
Toshihiro Shimizu 890ddd
		Very_black_found = TRUE;
Toshihiro Shimizu 890ddd
	if (x < Xmin)
Toshihiro Shimizu 890ddd
		Xmin = x;
Toshihiro Shimizu 890ddd
	if (x > Xmax)
Toshihiro Shimizu 890ddd
		Xmax = x;
Toshihiro Shimizu 890ddd
	if (y < Ymin)
Toshihiro Shimizu 890ddd
		Ymin = y;
Toshihiro Shimizu 890ddd
	if (y > Ymax)
Toshihiro Shimizu 890ddd
		Ymax = y;
Toshihiro Shimizu 890ddd
	Npix++;
Toshihiro Shimizu 890ddd
	SET_DONE(i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i + 1, j) && IS_BLACK_GR8(pix + 1)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(1, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		i++;
Toshihiro Shimizu 890ddd
		x++;
Toshihiro Shimizu 890ddd
		pix++;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_1:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i - 1, j) && IS_BLACK_GR8(pix - 1)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(2, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		i--;
Toshihiro Shimizu 890ddd
		x--;
Toshihiro Shimizu 890ddd
		pix--;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_2:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j + 1) && IS_BLACK_GR8(pix + Pix_ystep)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(3, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		j++;
Toshihiro Shimizu 890ddd
		y++;
Toshihiro Shimizu 890ddd
		pix += Pix_ystep;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_3:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j - 1) && IS_BLACK_GR8(pix - Pix_ystep)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(4, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		j--;
Toshihiro Shimizu 890ddd
		y--;
Toshihiro Shimizu 890ddd
		pix -= Pix_ystep;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_4:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!STACK_IS_EMPTY) {
Toshihiro Shimizu 890ddd
		POP_FROM_STACK_U(ret, x, y, i, j, dummy, pix);
Toshihiro Shimizu 890ddd
		switch (ret) {
Toshihiro Shimizu 890ddd
			CASE 1 : goto return_1;
Toshihiro Shimizu 890ddd
			CASE 2 : goto return_2;
Toshihiro Shimizu 890ddd
			CASE 3 : goto return_3;
Toshihiro Shimizu 890ddd
			CASE 4 : goto return_4;
Toshihiro Shimizu 890ddd
		DEFAULT:
Toshihiro Shimizu 890ddd
			abort();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void visit_gr8(int i, int j, int x, int y, UCHAR *pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int weight;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Level >= Max_level)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		Level++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	weight = BLACK_WEIGHT_GR8(pix);
Toshihiro Shimizu 890ddd
	ADDBIG(Xsum, x * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Ysum, y * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Weightsum, weight);
Toshihiro Shimizu 890ddd
	if (IS_VERY_BLACK_GR8(pix))
Toshihiro Shimizu 890ddd
		Very_black_found = TRUE;
Toshihiro Shimizu 890ddd
	if (x < Xmin)
Toshihiro Shimizu 890ddd
		Xmin = x;
Toshihiro Shimizu 890ddd
	if (x > Xmax)
Toshihiro Shimizu 890ddd
		Xmax = x;
Toshihiro Shimizu 890ddd
	if (y < Ymin)
Toshihiro Shimizu 890ddd
		Ymin = y;
Toshihiro Shimizu 890ddd
	if (y > Ymax)
Toshihiro Shimizu 890ddd
		Ymax = y;
Toshihiro Shimizu 890ddd
	Npix++;
Toshihiro Shimizu 890ddd
	SET_DONE(i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i + 1, j) && IS_BLACK_GR8(pix + 1))
Toshihiro Shimizu 890ddd
		visit_gr8(i + 1, j, x + 1, y, pix + 1);
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i - 1, j) && IS_BLACK_GR8(pix - 1))
Toshihiro Shimizu 890ddd
		visit_gr8(i - 1, j, x - 1, y, pix - 1);
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j + 1) && IS_BLACK_GR8(pix + Pix_ystep))
Toshihiro Shimizu 890ddd
		visit_gr8(i, j + 1, x, y + 1, pix + Pix_ystep);
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j - 1) && IS_BLACK_GR8(pix - Pix_ystep))
Toshihiro Shimizu 890ddd
		visit_gr8(i, j - 1, x, y - 1, pix - Pix_ystep);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Level--;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void visit_rgb(int i, int j, int x, int y, TPixel32 *pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int weight, ret, dummy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
start:
Toshihiro Shimizu 890ddd
	weight = BLACK_WEIGHT_RGB(pix);
Toshihiro Shimizu 890ddd
	ADDBIG(Xsum, x * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Ysum, y * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Weightsum, weight);
Toshihiro Shimizu 890ddd
	if (IS_VERY_BLACK_RGB(pix))
Toshihiro Shimizu 890ddd
		Very_black_found = TRUE;
Toshihiro Shimizu 890ddd
	if (x < Xmin)
Toshihiro Shimizu 890ddd
		Xmin = x;
Toshihiro Shimizu 890ddd
	if (x > Xmax)
Toshihiro Shimizu 890ddd
		Xmax = x;
Toshihiro Shimizu 890ddd
	if (y < Ymin)
Toshihiro Shimizu 890ddd
		Ymin = y;
Toshihiro Shimizu 890ddd
	if (y > Ymax)
Toshihiro Shimizu 890ddd
		Ymax = y;
Toshihiro Shimizu 890ddd
	Npix++;
Toshihiro Shimizu 890ddd
	SET_DONE(i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i + 1, j) && IS_BLACK_RGB(pix + 1)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(1, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		i++;
Toshihiro Shimizu 890ddd
		x++;
Toshihiro Shimizu 890ddd
		pix += 1;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_1:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i - 1, j) && IS_BLACK_RGB(pix - 1)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(2, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		i--;
Toshihiro Shimizu 890ddd
		x--;
Toshihiro Shimizu 890ddd
		pix -= 1;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_2:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j + 1) && IS_BLACK_RGB(pix + Pix_ystep)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(3, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		j++;
Toshihiro Shimizu 890ddd
		y++;
Toshihiro Shimizu 890ddd
		pix += Pix_ystep;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_3:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j - 1) && IS_BLACK_RGB(pix - Pix_ystep)) {
Toshihiro Shimizu 890ddd
		PUSH_ONTO_STACK(4, x, y, i, j, 0, pix)
Toshihiro Shimizu 890ddd
		j--;
Toshihiro Shimizu 890ddd
		y--;
Toshihiro Shimizu 890ddd
		pix -= Pix_ystep;
Toshihiro Shimizu 890ddd
		goto start;
Toshihiro Shimizu 890ddd
	return_4:;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!STACK_IS_EMPTY) {
Toshihiro Shimizu 890ddd
		POP_FROM_STACK_TPIXEL32(ret, x, y, i, j, dummy, pix);
Toshihiro Shimizu 890ddd
		switch (ret) {
Toshihiro Shimizu 890ddd
			CASE 1 : goto return_1;
Toshihiro Shimizu 890ddd
			CASE 2 : goto return_2;
Toshihiro Shimizu 890ddd
			CASE 3 : goto return_3;
Toshihiro Shimizu 890ddd
			CASE 4 : goto return_4;
Toshihiro Shimizu 890ddd
		DEFAULT:
Toshihiro Shimizu 890ddd
			abort();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef RECURSIVE_VERSION
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void visit_rgb(int i, int j, int x, int y, TPixel32 *pix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int weight;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Level >= Max_level)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		Level++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	weight = BLACK_WEIGHT_RGB(pix);
Toshihiro Shimizu 890ddd
	ADDBIG(Xsum, x * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Ysum, y * weight);
Toshihiro Shimizu 890ddd
	ADDBIG(Weightsum, weight);
Toshihiro Shimizu 890ddd
	if (IS_VERY_BLACK_RGB(pix))
Toshihiro Shimizu 890ddd
		Very_black_found = TRUE;
Toshihiro Shimizu 890ddd
	if (x < Xmin)
Toshihiro Shimizu 890ddd
		Xmin = x;
Toshihiro Shimizu 890ddd
	if (x > Xmax)
Toshihiro Shimizu 890ddd
		Xmax = x;
Toshihiro Shimizu 890ddd
	if (y < Ymin)
Toshihiro Shimizu 890ddd
		Ymin = y;
Toshihiro Shimizu 890ddd
	if (y > Ymax)
Toshihiro Shimizu 890ddd
		Ymax = y;
Toshihiro Shimizu 890ddd
	Npix++;
Toshihiro Shimizu 890ddd
	SET_DONE(i, j);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i + 1, j) && IS_BLACK_RGB(pix + 1))
Toshihiro Shimizu 890ddd
		visit_rgb(i + 1, j, x + 1, y, pix + 1);
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i - 1, j) && IS_BLACK_RGB(pix - 1))
Toshihiro Shimizu 890ddd
		visit_rgb(i - 1, j, x - 1, y, pix - 1);
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j + 1) && IS_BLACK_RGB(pix + Pix_ystep))
Toshihiro Shimizu 890ddd
		visit_rgb(i, j + 1, x, y + 1, pix + Pix_ystep);
Toshihiro Shimizu 890ddd
	if (NOT_DONE(i, j - 1) && IS_BLACK_RGB(pix - Pix_ystep))
Toshihiro Shimizu 890ddd
		visit_rgb(i, j - 1, x, y - 1, pix - Pix_ystep);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Level--;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
 * Attenzione: tutti i controlli e i calcoli vengono fatti in pixel.
Toshihiro Shimizu 890ddd
 * Quindi bisogna convertire tutti i valori in pixel prima di arrivare a
Toshihiro Shimizu 890ddd
 * questo livello.
Toshihiro Shimizu 890ddd
 * Inoltre: la pegs_side si riferisce alle coordinate di raster.
Toshihiro Shimizu 890ddd
 */
Toshihiro Shimizu 890ddd
int get_image_rotation_and_center(const TRasterP &img, int strip_width,
Toshihiro Shimizu 890ddd
								  PEGS_SIDE pegs_side,
Toshihiro Shimizu 890ddd
								  double *p_ang, double *cx, double *cy,
Toshihiro Shimizu 890ddd
								  DOT ref[], int ref_dot)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double angle;
Toshihiro Shimizu 890ddd
	int found, i;
Toshihiro Shimizu 890ddd
	float dx, dy;
Toshihiro Shimizu 890ddd
	DOT _dotarray[MAX_DOT];
Toshihiro Shimizu 890ddd
	DOT *dotarray = _dotarray;
Toshihiro Shimizu 890ddd
	int ndot, central;
Toshihiro Shimizu 890ddd
	int max_area;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	*p_ang = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Debug_flag) {
Toshihiro Shimizu 890ddd
		for (i = 0; i < ref_dot; i++) {
Toshihiro Shimizu 890ddd
			printf("Reference dot <%d>\n", i);
Toshihiro Shimizu 890ddd
			stampa_dot(ref + i);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	max_area = 0;
Toshihiro Shimizu 890ddd
	for (i = 0; i < ref_dot; i++)
Toshihiro Shimizu 890ddd
		if (ref[i].area > max_area)
Toshihiro Shimizu 890ddd
			max_area = ref[i].area;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ndot = find_dots(img, strip_width, pegs_side, dotarray, MAX_DOT, max_area);
Toshihiro Shimizu 890ddd
	if (Debug_flag)
Toshihiro Shimizu 890ddd
		printf(">>>> %d dots found\n", ndot);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	i = 0;
Toshihiro Shimizu 890ddd
	while (i < ndot) //elimino i dots troppo piccoli
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (dotarray[i].area < 500) {
Toshihiro Shimizu 890ddd
			for (int j = i; j < ndot - 1; j++)
Toshihiro Shimizu 890ddd
				dotarray[j] = dotarray[j + 1];
Toshihiro Shimizu 890ddd
			ndot--;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			i++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* controllo il pattern delle perforazioni  */
Toshihiro Shimizu 890ddd
	if (ndot <= 1) {
Toshihiro Shimizu 890ddd
		return FALSE;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	found = compare_dots(dotarray, &ndot, ref, ref_dot);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Debug_flag)
Toshihiro Shimizu 890ddd
		for (i = 0; i < ndot; i++) {
Toshihiro Shimizu 890ddd
			printf("**** Dot[%d]\n", i);
Toshihiro Shimizu 890ddd
			stampa_dot(dotarray + i);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!found)
Toshihiro Shimizu 890ddd
		return FALSE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	central = ndot / 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	angle = 0;
Toshihiro Shimizu 890ddd
	for (i = 0; i < ndot - 1; i++) {
Toshihiro Shimizu 890ddd
		dx = dotarray[i + 1].x - dotarray[i].x;
Toshihiro Shimizu 890ddd
		dy = dotarray[i + 1].y - dotarray[i].y;
Toshihiro Shimizu 890ddd
		switch (pegs_side) {
Toshihiro Shimizu 890ddd
			CASE PEGS_LEFT : __OR PEGS_RIGHT : angle += dy == 0.0 ? TConsts::pi_2 : atan(dx / dy);
Toshihiro Shimizu 890ddd
		DEFAULT:
Toshihiro Shimizu 890ddd
			angle -= dx == 0.0 ? TConsts::pi_2 : atan(dy / dx);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	*p_ang = angle / (ndot - 1);
Toshihiro Shimizu 890ddd
	*cx = dotarray[central].x;
Toshihiro Shimizu 890ddd
	*cy = dotarray[central].y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Debug_flag) {
Toshihiro Shimizu 890ddd
		printf("\nang: %g\ncx : %g\ncy : %g\n\n", *p_ang, *cx, *cy);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
#define PERCENT (40.0 / 100.0)
Toshihiro Shimizu 890ddd
#define MIN_V 100.0
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int compare_dots(DOT dots[], int *ndots,
Toshihiro Shimizu 890ddd
						DOT reference[], int ref_dot)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int found;
Toshihiro Shimizu 890ddd
	int toll, i_ok = 0, j_ok = 0, k_ok = 0;
Toshihiro Shimizu 890ddd
	float tolld;
Toshihiro Shimizu 890ddd
	int i, j, k;
Toshihiro Shimizu 890ddd
	short *dot_ok = 0;
Toshihiro Shimizu 890ddd
	float *ref_dis = 0, dx, dy;
Toshihiro Shimizu 890ddd
	float vmin, v, dist_i_j, dist_i_k, dist_j_k, del1, del2;
Toshihiro Shimizu 890ddd
	float ref_dis_0_1, ref_dis_1_2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* questa funz e' indipendente da posizione e orientamento dei dots */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (*ndots < 1 || ref_dot < 1) {
Toshihiro Shimizu 890ddd
		goto error;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* controllo quanti dots sono realmente buoni per il confronto */
Toshihiro Shimizu 890ddd
	dot_ok = (short *)calloc(*ndots, sizeof(short));
Toshihiro Shimizu 890ddd
	found = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < *ndots; i++)
Toshihiro Shimizu 890ddd
		for (j = 0; j < ref_dot; j++) {
Toshihiro Shimizu 890ddd
			toll = (int)((float)reference[j].area * PERCENT);
Toshihiro Shimizu 890ddd
			if (abs(dots[i].area - reference[j].area) < toll) {
Toshihiro Shimizu 890ddd
				dot_ok[found] = i;
Toshihiro Shimizu 890ddd
				found++;
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!found) {
Toshihiro Shimizu 890ddd
		goto error;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (found < *ndots) {
Toshihiro Shimizu 890ddd
		for (i = 0; i < found; i++) {
Toshihiro Shimizu 890ddd
			if (dot_ok[i] != i)
Toshihiro Shimizu 890ddd
				*(dots + i) = *(dots + dot_ok[i]);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		*ndots = found;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ref_dis = (float *)calloc(ref_dot, sizeof(float));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* calcolo le distanze di riferimento e la tolleranza stessa */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tolld = (float)reference[0].lx;
Toshihiro Shimizu 890ddd
	if (tolld < reference[0].ly)
Toshihiro Shimizu 890ddd
		tolld = (float)reference[0].ly;
Toshihiro Shimizu 890ddd
	for (i = 1; i < ref_dot; i++) {
Toshihiro Shimizu 890ddd
		dx = reference[0].x - reference[i].x;
Toshihiro Shimizu 890ddd
		dy = reference[0].y - reference[i].y;
Toshihiro Shimizu 890ddd
		ref_dis[i - 1] = sqrtf((dx * dx) + (dy * dy));
Toshihiro Shimizu 890ddd
		if (tolld < reference[i].lx)
Toshihiro Shimizu 890ddd
			tolld = (float)reference[i].lx;
Toshihiro Shimizu 890ddd
		if (tolld < reference[i].ly)
Toshihiro Shimizu 890ddd
			tolld = (float)reference[i].ly;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// I suspect that the following expects symmetry in the holes layout...
Toshihiro Shimizu 890ddd
	// Besides, if the layout is not symmetric, the peg is supposed to be rotated OR translated
Toshihiro Shimizu 890ddd
	// switching from, say, top to bottom? (Daniele)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	i_ok = -1;
Toshihiro Shimizu 890ddd
	v = vmin = 10000000.0;
Toshihiro Shimizu 890ddd
	for (i = 0; i < *ndots - 2; i++)
Toshihiro Shimizu 890ddd
		for (j = i + 1; j < *ndots - 1; j++)
Toshihiro Shimizu 890ddd
			for (k = j + 1; k < *ndots; k++) {
Toshihiro Shimizu 890ddd
				// Build square discrepancies from the reference relative hole distances
Toshihiro Shimizu 890ddd
				dx = dots[i].x - dots[j].x;
Toshihiro Shimizu 890ddd
				dy = dots[i].y - dots[j].y;
Toshihiro Shimizu 890ddd
				dist_i_j = sqrtf((dx * dx) + (dy * dy));
Toshihiro Shimizu 890ddd
				dx = dots[i].x - dots[k].x;
Toshihiro Shimizu 890ddd
				dy = dots[i].y - dots[k].y;
Toshihiro Shimizu 890ddd
				dist_i_k = sqrtf((dx * dx) + (dy * dy));
Toshihiro Shimizu 890ddd
				del1 = (dist_i_j - ref_dis[0]);
Toshihiro Shimizu 890ddd
				del2 = (dist_i_k - ref_dis[1]);
Toshihiro Shimizu 890ddd
				v = ((del1 * del1) + (del2 * del2));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//Furthermore, add discrepancies from the reference hole areas
Toshihiro Shimizu 890ddd
				v += abs(dots[i].area - reference[0].area); //fabs since areas are already squared
Toshihiro Shimizu 890ddd
				v += abs(dots[j].area - reference[1].area);
Toshihiro Shimizu 890ddd
				v += abs(dots[k].area - reference[2].area);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (v < vmin) {
Toshihiro Shimizu 890ddd
					i_ok = i;
Toshihiro Shimizu 890ddd
					j_ok = j;
Toshihiro Shimizu 890ddd
					k_ok = k;
Toshihiro Shimizu 890ddd
					vmin = v;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Debug_flag) {
Toshihiro Shimizu 890ddd
		printf("Ho trovato v = %f su %f per %d %d %d \n",
Toshihiro Shimizu 890ddd
			   v, vmin, i_ok, j_ok, k_ok);
Toshihiro Shimizu 890ddd
		printf("----  Dot <%d>  ----\n", i_ok);
Toshihiro Shimizu 890ddd
		stampa_dot(dots + i_ok);
Toshihiro Shimizu 890ddd
		printf("----  Dot <%d>  ----\n", j_ok);
Toshihiro Shimizu 890ddd
		stampa_dot(dots + j_ok);
Toshihiro Shimizu 890ddd
		printf("----  Dot <%d>  ----\n", k_ok);
Toshihiro Shimizu 890ddd
		stampa_dot(dots + k_ok);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (i_ok < 0)
Toshihiro Shimizu 890ddd
		goto error;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		dx = dots[i_ok].x - dots[j_ok].x;
Toshihiro Shimizu 890ddd
		dy = dots[i_ok].y - dots[j_ok].y;
Toshihiro Shimizu 890ddd
		dist_i_j = sqrtf((dx * dx) + (dy * dy));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		dx = dots[k_ok].x - dots[j_ok].x;
Toshihiro Shimizu 890ddd
		dy = dots[k_ok].y - dots[j_ok].y;
Toshihiro Shimizu 890ddd
		dist_j_k = sqrtf((dx * dx) + (dy * dy));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ref_dis_0_1 = ref_dis[0];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		dx = reference[1].x - reference[2].x;
Toshihiro Shimizu 890ddd
		dy = reference[1].y - reference[2].y;
Toshihiro Shimizu 890ddd
		ref_dis_1_2 = sqrtf((dx * dx) + (dy * dy));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (fabsf(dist_i_j - ref_dis_0_1) < tolld &&
Toshihiro Shimizu 890ddd
			fabsf(dist_j_k - ref_dis_1_2) < tolld) {
Toshihiro Shimizu 890ddd
			*ndots = 3;
Toshihiro Shimizu 890ddd
			*(dots) = *(dots + i_ok);
Toshihiro Shimizu 890ddd
			*(dots + 1) = *(dots + j_ok);
Toshihiro Shimizu 890ddd
			*(dots + 2) = *(dots + k_ok);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (ref_dis)
Toshihiro Shimizu 890ddd
		free(ref_dis);
Toshihiro Shimizu 890ddd
	if (dot_ok)
Toshihiro Shimizu 890ddd
		free(dot_ok);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TRUE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
error:
Toshihiro Shimizu 890ddd
	if (ref_dis)
Toshihiro Shimizu 890ddd
		free(ref_dis);
Toshihiro Shimizu 890ddd
	if (dot_ok)
Toshihiro Shimizu 890ddd
		free(dot_ok);
Toshihiro Shimizu 890ddd
	return FALSE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void stampa_dot(DOT *dot)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	printf("Dimensioni: %d,\t%d\n", dot->lx, dot->ly);
Toshihiro Shimizu 890ddd
	printf("Start     : %d,\t%d\n", dot->x1, dot->y1);
Toshihiro Shimizu 890ddd
	printf("End       : %d,\t%d\n", dot->x2, dot->y2);
Toshihiro Shimizu 890ddd
	printf("Baricentro: %5.3f,\t%5.3f\n", dot->x, dot->y);
Toshihiro Shimizu 890ddd
	printf("Area      : %d\n", dot->area);
Toshihiro Shimizu 890ddd
}