
#include <vcl.h>
#pragma hdrstop
#include "math.h"
#include "TabletCharacterExtract.h"
#include "InspectionAreaRevision_Form.h"
#include "Environment.h"
#include "Message_Form.h"
#include "MultiLanguage.h"
#include "Keyboard_Form.h"
#include <inifiles.hpp>

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntButtons"
#pragma link "TntComCtrls"
#pragma link "TntExtCtrls"
#pragma link "TntStdCtrls"
#pragma link "TntGrids"
#pragma resource "*.dfm"
#define CAPTURE_IMAGE_N 50          
#define SHAPE_MATCHING_RANGE 5
#define ACCEPTABLE_ROTATION_RANGE 20
#define TABLET_SHAPE_EDGE_MAX_POINT 2000
#define UNCOATING  1
#define FILMCOATING  2
#define SUGARCOATING  3
#define ROUND  1
#define OBLONG  2
#define OVAL  3
#define HEXA  4
#define TRIANGLE  5
#define ETC  10
#define STAMP 1
#define PRINT 2

#define DARK 1
#define BRIGHT 2
#define PI 3.141592
#define MAX_LABEL_COUNT 1000
#define NORMAL_INPECTION_AREA  100
#define FRONT_SHAPE_EDGE_NEIGHBOR  2
#define PRINT_NEIGHBOR  3
#define CASE1 1
#define CASE2 2
#define CASE3 3

#define NONE        0
#define ERASE       1
#define DRAW        2
#define THICK       3
#define LABELING    4

#define BLUE 0
#define GREEN 1
#define RED 2
#define NEW_CREAT 1
#define MODIFY 2
#define PRINT_ADJUST 1
#define ETC_ADJUST 2
#define DISK1 1
#define DISK2 2
#define HALF_IMAGE 2
#define FULL_IMAGE 1
#define HALF_MAX_IMAGE_WIDTH 320
#define HALF_MAX_IMAGE_HEIGHT  240
#define MAX_IMAGE_WIDTH  640
#define MAX_IMAGE_HEIGHT  480

#define MAX_SIMILAR_LABEL_PER 50

#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)

TTabletCharacterExtractForm *TabletCharacterExtractForm;
//---------------------------------------------------------------------------
__fastcall TTabletCharacterExtractForm::TTabletCharacterExtractForm(TComponent* Owner)
	: TTntForm(Owner)
{
	if (DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
		ComponentSetFontName(this, "SimSun");
  else if (DefaultLCID == 1041)
		ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

	GetDefaultString();

#ifdef PC_SIM
//	ShowHintByName(this);
#endif
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::GetDefaultString()
{
	BitBtn27->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_01;
	BitBtn16->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_02;
	BitBtn22->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_03;
	BitBtn29->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_04;
	ThreeDDiscriminationExtractButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_05;
	DiscrimiationMarkExtract->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_06;
	BitBtn12->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_07;
	BitBtn30->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_08;
	GroupBox31->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_09;
	BitBtn19->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_10;
	BitBtn18->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_10;
	BitBtn23->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_10;
	BitBtn17->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_10;
	BitBtn15->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_10;

	SetThresholdBtn->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_28;
	SetThresholdPanel->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_28;
	BitBtn21->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_11;
	BitBtn14->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_12;
	PrintMaskingButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_13;
	BitBtn3->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_14;
	BitBtn7->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_15;
	PrintManualExtractButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_16;
	GroupBox29->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_17;
	BitBtn20->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_18;
	BitBtn13->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_19;
	ManualWorkEndButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_20;
	PrintExtractWorkEndButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_20;
	BitBtn8->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_20;
	BitBtn28->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_20;

	BitBtn5->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_21;
	BitBtn2->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_21;
	BitBtn9->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_21;

	BitBtn6->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_23;
	BitBtn1->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_24;
	BitBtn4->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_25;
	BitBtn32->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_26;
	BitBtn10->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_26;
	ShapExtractButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_27;
	SpeedButton5->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_01;
	SpeedButton9->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_02;
	SpeedButton7->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_03;
	SpeedButton6->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_04;
	SpeedButton8->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_05;
	GroupBox17->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_01;
	GroupBox1->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_02;
	GroupBox23->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_03;
	GroupBox18->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_04;
	GroupBox25->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_05;

	GroupBox19->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_07;
	GroupBox26->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_08;
	GroupBox33->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_09;
	GroupBox28->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_10;
	GroupBox27->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_11;

	GroupBox15->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_14;
	GroupBox9->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_15;
	BitBtn30->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_16;
	GroupBox31->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_17;
	GroupBox13->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_18;
	GroupBox11->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_19;
	GroupBox20->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_21;
	BitBtn11->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_21;

	GroupBox21->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_22;

	GroupBox4->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_24;
	GroupBox5->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_22;
	GroupBox6->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_25;
	ImageSelectButton->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_26;

	BitBtn24->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_26;
	GroupBox24->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_27;
	GroupBox10->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_28;

	Label2->Caption = TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_01;
	Label1->Caption = TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_02;
	Label5->Caption = TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_03;
	Label4->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_14;
	RadioButton5->Caption = TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_03;

	RadioButton6->Caption = TABLETCHARACTEREXTRACTFORM_RADIOBTN_CAPTION_02;

	StaticText12->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_01;
	StaticText10->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_02;
	StaticText1->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_03;
	StaticText11->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_04;
	StaticText5->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_05;
	StaticText6->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_05;
	TntLabel2->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_06;
	TntLabel3->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_07;
	StaticText8->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_08;
	StaticText9->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_09;
	StaticText7->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_11;
	StaticText26->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_13;

	//add
	BitBtn25->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_19;
	BitBtn26->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_11;
	BitBtn15->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_10;
	SpeedButton1->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_04;
	SpeedButton2->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_03;
	GroupBox2->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_20;
	SpeedButton3->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_02;
	SpeedButton4->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_05;
	GroupBox14->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_20;
	TntLabel1->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_12;
	ETC_InformationExtractButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_08;
	BitBtn31->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_23;
	BitBtn33->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_23;

	//ID 없음. 임시
	StaticText13->Caption = DEFECTINFOFORM_STRGRID_CELL_05;

	TabletShapeSelectGB->Caption = NEW_ADD_STRING_52;
	shapeSelectionOKBtn->Caption = CALIBRATION3DFORM_BUTTON_CAPTION_01;
	shapeSelectionCancelBtn->Caption = COMPUTERSYSTEMSETTINGFORM_BUTTON_CAPTION_03;

  ManualEraseButton->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_05;
  ManualDrawButton->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_02;

  // 추가
  ExtractSplitLineBtn->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_14;
  ExtractionSplitLineGroupBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_14;
  SplitLineImageSelectionBtn->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_26;
  SplitLineExtractionBtn->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_14;
  TntBitBtn4->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_10;

  GroupBox32->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_15;
  GroupBox34->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_16;
  GroupBox35->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_17;
  Label8->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_18;
  SimilarPrintOptionGroupBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_19;
  Label7->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_20;
  SimilarPrintDrawRadioBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_21;
  SimilarPrintEraseRadioBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_22;
  InitSimilarPrintMaskBtn->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_23;
  ApplyDiffPrintAreaBtn->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_24;
  CheckPrintSimliarResultBtn->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_26;
  PrintSimliarCheckCloseBtn->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_28;
  SimilarPrintSettingBtn->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_15;
  SimilarPrintSettingBtn2->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_15;

  Extraction3DInfoGroupBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_31;
  GroupBox36->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_32;
  GetThreeDThresholdGroupBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_33;
  NormalizedThreeDImageGroupBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_34;
  GetThreeDInfoButton->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_35;

  SpeedButton10->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_36;
  GroupBox40->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_37;
  PrintLabelEditOptionBtn1->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_38;
  PrintLabelEditOptionBtn2->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_39;
  Label15->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_40;
  TntBitBtn1->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_24;
  TntBitBtn2->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_21;

  Panel25->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_41;
  ReadHistoryButton->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_42;
  ApplySetupDataButton->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_43;

  ColorRateCheckBox->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_54;
  StaticText14->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_55;
  OtherPrintSettingButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_30;

  GroupBox3->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_30;
  SaveAndExitButton->Caption = TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_31;

  ZoomOptionBox->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_31;
  GroupBox8->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_32;

  GroupBox37->Caption  = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_33 + " 1";
  GroupBox38->Caption  = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_33 + " 2";
  GroupBox39->Caption  = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_33 + " 3";

  SetThresholdCloseBtn->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_06;

  ExtractThreeInfoCloseBtn->Caption = TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_06;

  Label9->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_07 + "1";
  Label11->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_07 + "1";
  Label13->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_07 + "1";

  Label10->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_07 + "2";
  Label12->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_07 + "2";
  Label14->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_07 + "2";

  Label3->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_04;
  Label6->Caption 	= TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_05;

  GroupBox7->Caption = TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_08;

  PrintTHGB->Caption = TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_09;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ReadDataForTabletCharacterExtract(void)
{
	// For SELMA200, 20180212, Rev by moon, Camera Index
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		TabletSetupData.cameraZoom[globalCameraIndex] = MachineParams.CameraResolution[globalCameraIndex];
		TabletSetupData.DiskBaseHeightPosition[globalCameraIndex] = MachineParams.DiscCenterPos[globalCameraIndex] / 4 * 4;
	}
}

//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ShapExtractButtonClick(TObject *Sender) 
{
  BitBtn8->Visible = false;
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;

	int startX, endX, startY, endY;

	if (TabletCharacter.kind == SUGARCOATING)
	{
		TInspectionAreaRevisionForm *InspectionAreaRevisionForm = new TInspectionAreaRevisionForm(this);

		memset(&InspectionAreaRevisionForm->dstTabletSetupData, 0, sizeof(TTabletSetupData));

		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartX[0] = 10;
		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartY[0] = 10;
		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndX[0] = MAX_IMAGE_WIDTH - 10;
		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndY[0] = MAX_IMAGE_HEIGHT - 10;

		InspectionAreaRevisionForm->mode = 0;
		InspectionAreaRevisionForm->ShowModal();

		startX = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartX[0];
		endX = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndX[0];
		startY = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartY[0];
		endY = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndY[0];

		delete InspectionAreaRevisionForm;
	}
	else
	{
		startX = 10;
		endX = MAX_IMAGE_WIDTH - 10;
		startY = 10;
		endY = MAX_IMAGE_HEIGHT - 10;
	}

	if (startX < 0) startX = 0;
	if (endX > ImageWidth) endX = ImageWidth;
	if (startY < 0) startY = 0;
	if (endY > ImageHeight) endY = ImageHeight;

	if (TabletCharacter.shape == ETC && TabletCharacter.symmetric_line_count == ASYMMETRY_TABLET)
	{
		SelectedShapeImg = -1;

		TabletShapeSelectGB->Visible = true;

		Graphics::TBitmap *shapeImg;
		shapeImg = new Graphics::TBitmap();

		for (int i = 1; i <= 12; i++)
		{
			if (!ExtractImage(shapeImg, i, SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode)) continue;

			if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(shapeImg);
			}

			((TTntImage *)FindComponent("shapeSelectImage" + IntToStr(i)))->Picture->Bitmap->Assign(shapeImg);
		}

		delete shapeImg;
		return;
	}

	GroupBox13->Visible = true;

  Sleep(20);

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	Byte *ptr;

	int tabletLength;
	int tabletWidth;
	int space;
	int rotationAngle;
	unsigned char *colorSourceImage;
	unsigned char *accumulateShapeImage1;
	unsigned char *accumulateShapeImage2;
	int tempX, tempY;
	int tempImageCaptureN;
	int meanColor[3]; //B,G,R
	int threshold;
	float uLength;

	// setup data initial
	memset(TabletSetupData.FrontshapeAreaData, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
	memset(TabletSetupData.FrontshapeAreaData2, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
	TabletSetupData.FrontShapeEdgePointCount = 0;
	TabletSetupData.FrontShapeEdgePointCount2 = 0;
	memset(TabletSetupData.FrontShapeEdgePoint, 0, sizeof(short) * 2000 * 3);
	memset(TabletSetupData.FrontShapeEdgePoint2, 0, sizeof(short) * 2000 * 3);
	// end

  Image19->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
  Image19->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
  Image19->Picture->Bitmap->PixelFormat = pf24bit;
	Image19->Canvas->Brush->Style = bsSolid;
	Image19->Canvas->Brush->Color = clBlack;
	Image19->Canvas->Rectangle(0, 0, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
  
  TntImage1->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
  TntImage1->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
  TntImage1->Picture->Bitmap->PixelFormat = pf24bit;
	TntImage1->Canvas->Brush->Style = bsSolid;
	TntImage1->Canvas->Brush->Color = clBlack;
	TntImage1->Canvas->Rectangle(0, 0, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);

	meanColor[0] = meanColor[1] = meanColor[2] = 0;
	tempImageCaptureN = CAPTURE_IMAGE_N;
	colorSourceImage = new unsigned char[3 * ImageWidth * ImageHeight];
	accumulateShapeImage1 = new unsigned char[ImageWidth * ImageHeight];
	accumulateShapeImage2 = new unsigned char[ImageWidth * ImageHeight];

	if (TabletCharacter.kind != SUGARCOATING)
		threshold = 40;
	else
		threshold = 30;

	memset(accumulateShapeImage1, 0, ImageWidth*ImageHeight);
	memset(accumulateShapeImage2, 0, ImageWidth*ImageHeight);
	for (int i = 1; i <= tempImageCaptureN; i++)
	{
    ProgressBar1->BorderWidth = 5;
		ProgressBar1->Brush->Color = 0x212130;
		ProgressBar1->Position = 100 * i / tempImageCaptureN;

    int cameraIndex;
    
		// SD1
    cameraIndex = SD1_2D_FRONT_FACE_CAMERA_INDEX;
		if (!ExtractImage(img1, i, cameraIndex, TabletSetupData.ImageOffSetSW[cameraIndex - 1], TabletSetupData.referenceImageForOffset[cameraIndex - 1], ProductData.SubSamplingMode)) continue;

		if (CameraMapInfo[cameraIndex - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
		{
			ReductionImageScale(img1);
		}

		Image1->Picture->Bitmap->Assign(img1);
		Image1->Refresh();

		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				*(colorSourceImage + (y*ImageWidth + x) * 3) = ptr[3 * x];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 1) = ptr[3 * x + 1];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 2) = ptr[3 * x + 2];
			}
		}

		ShapeExtract(colorSourceImage, accumulateShapeImage1, 1, threshold, startX, endX, startY, endY, meanColor, cameraIndex);
    Application->ProcessMessages();
    
		// SD2
    if (TabletCharacter.kind == SUGARCOATING)
    {
      cameraIndex = SD1_2D_FRONT_FACE_CAMERA_INDEX;
    }
    else
    {
      cameraIndex = SD2_2D_FRONT_FACE_CAMERA_INDEX;
    }

    if (!ExtractImage(img1, i, cameraIndex, TabletSetupData.ImageOffSetSW[cameraIndex - 1], TabletSetupData.referenceImageForOffset[cameraIndex - 1], ProductData.SubSamplingMode)) continue;

		if (CameraMapInfo[cameraIndex - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
		{
			ReductionImageScale(img1);
		}

		Image1->Picture->Bitmap->Assign(img1);
		Image1->Refresh();

		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				*(colorSourceImage + (y*ImageWidth + x) * 3) = ptr[3 * x];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 1) = ptr[3 * x + 1];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 2) = ptr[3 * x + 2];
			}
		}

		ShapeExtract(colorSourceImage, accumulateShapeImage2, 1, threshold, startX, endX, startY, endY, meanColor, cameraIndex);
    Application->ProcessMessages();
	}

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			if (*(accumulateShapeImage1 + y * ImageWidth + x) > tempImageCaptureN * 0.8)  //확률 50%이상이면//
			{
				TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = NORMAL_INPECTION_AREA;

				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = *(accumulateShapeImage1 + y * ImageWidth + x) * 2;
				ptr[3 * x + 2] = *(accumulateShapeImage1 + y * ImageWidth + x) * 2;
			}
			else
			{
				TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = 0;

				*(accumulateShapeImage1 + y * ImageWidth + x) = 0;
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
		}
	}

	for (int y = 1; y < ImageHeight - 1; y++)
	{
		for (int x = 1; x < ImageWidth - 1; x++)
		{
			if (*(accumulateShapeImage1 + y * ImageWidth + x))
			{
				if (*(accumulateShapeImage1 + (y - 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
				else if (*(accumulateShapeImage1 + (y + 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
				else if (*(accumulateShapeImage1 + (y)*ImageWidth + x - 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
				else if (*(accumulateShapeImage1 + (y)*ImageWidth + x + 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
			}
		}
	}

	// uLength는 이미지 중심부와 위에서 구한 FrontShapeEdgePoint와의 거리를 의미한다.
	for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
	{
		tempX = TabletSetupData.FrontShapeEdgePoint[m][0];
		tempY = TabletSetupData.FrontShapeEdgePoint[m][1];
		uLength = sqrt((tempX - 320)*(tempX - 320) + (tempY - 240)*(tempY - 240));
		if (tempY - 240 >= 0) // Edge좌표가 Y축을 기준으로 이미지 중심부 아래에 위치한 좌표라면
		{
			TabletSetupData.FrontShapeEdgePoint[m][2] = acos(float(tempX - 320) / uLength)*180.0 / PI; // FrontShapeEdgePoint에 angle이 할당되는 이유가..
		}
		else
		{
			TabletSetupData.FrontShapeEdgePoint[m][2] = 360.0 - acos(float(tempX - 320) / uLength)*180.0 / PI;
		}
	}

	for (int r = 30; r >= 2; r--)
	{
		for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
		{
			tempX = TabletSetupData.FrontShapeEdgePoint[m][0];
			tempY = TabletSetupData.FrontShapeEdgePoint[m][1];
			for (int y = tempY - r; y <= tempY + r; y++)
			{
				for (int x = tempX - r; x <= tempX + r; x++)
				{
					if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) < (r + 1)*(r + 1))
					{
						if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) > (r - 1)*(r - 1))
						{
							if (TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)])
							{
								TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = r;
							}
						}
					}
				}
			}
		}
	}

	Image19->Picture->Bitmap->Assign(img1);
	Image19->Refresh();

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			if (*(accumulateShapeImage2 + y * ImageWidth + x) > tempImageCaptureN * 0.8)  //확률 50%이상이면//
			{
				TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = NORMAL_INPECTION_AREA;

				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = *(accumulateShapeImage2 + y * ImageWidth + x) * 2;
				ptr[3 * x + 2] = *(accumulateShapeImage2 + y * ImageWidth + x) * 2;
			}
			else
			{
				TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = 0;

				*(accumulateShapeImage2 + y * ImageWidth + x) = 0;
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
		}
	}

	for (int y = 1; y < ImageHeight - 1; y++)
	{
		for (int x = 1; x < ImageWidth - 1; x++)
		{
			if (*(accumulateShapeImage2 + y * ImageWidth + x))
			{
				if (*(accumulateShapeImage2 + (y - 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
				else if (*(accumulateShapeImage2 + (y + 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
				else if (*(accumulateShapeImage2 + (y)*ImageWidth + x - 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
				else if (*(accumulateShapeImage2 + (y)*ImageWidth + x + 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
			}
		}
	}

	// uLength는 이미지 중심부와 위에서 구한 FrontShapeEdgePoint와의 거리를 의미한다.
	for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount2; m++)
	{
		tempX = TabletSetupData.FrontShapeEdgePoint2[m][0];
		tempY = TabletSetupData.FrontShapeEdgePoint2[m][1];
		uLength = sqrt((tempX - 320)*(tempX - 320) + (tempY - 240)*(tempY - 240));
		if (tempY - 240 >= 0) // Edge좌표가 Y축을 기준으로 이미지 중심부 아래에 위치한 좌표라면
		{
			TabletSetupData.FrontShapeEdgePoint2[m][2] = acos(float(tempX - 320) / uLength)*180.0 / PI; // FrontShapeEdgePoint에 angle이 할당되는 이유가..
		}
		else
		{
			TabletSetupData.FrontShapeEdgePoint2[m][2] = 360.0 - acos(float(tempX - 320) / uLength)*180.0 / PI;
		}
	}

	for (int r = 30; r >= 2; r--)
	{
		for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount2; m++)
		{
			tempX = TabletSetupData.FrontShapeEdgePoint2[m][0];
			tempY = TabletSetupData.FrontShapeEdgePoint2[m][1];
			for (int y = tempY - r; y <= tempY + r; y++)
			{
				for (int x = tempX - r; x <= tempX + r; x++)
				{
					if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) < (r + 1)*(r + 1))
					{
						if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) > (r - 1)*(r - 1))
						{
							if (TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)])
							{
								TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = r;
							}
						}
					}
				}
			}
		}
	}

	TntImage1->Picture->Bitmap->Assign(img1);
	TntImage1->Refresh();

	delete(img1);
	delete(colorSourceImage);
	delete(accumulateShapeImage1);
	delete(accumulateShapeImage2);

  BitBtn8->Visible = true;
}

float __fastcall TTabletCharacterExtractForm::Calculation_ShapeRotationAngle(unsigned char *expansionTempData, int tabletCenterX, int tabletCenterY, int startX, int endX, int startY, int endY, int option)
{
	unsigned char *tabletOutLineNeighborPixel;
	unsigned char *rotationData;
	int rX, rY;
	int tempX, tempY;
	int breakSW;
	int edgeCheckSW;
	int minValue;
	int XasymmetryCount;
	int YasymmetryCount;
	float angle;
	int yPoisitionSum;
	int totalPixelCount;
	short y_WeightCenter[720];
	rotationData = new unsigned char[ImageWidth*ImageHeight];
	tabletOutLineNeighborPixel = new unsigned char[ImageWidth*ImageHeight];
	breakSW = false;

	int cosData[720];
	int sinData[720];
	for (int i = 0; i < 720; i++)
	{
		cosData[i] = cos((float)i / 2.0*PI / 180.0) * 1024;
		sinData[i] = sin((float)i / 2.0*PI / 180.0) * 1024;
	}
	minValue = 0x4fffffff;
	if (option == CASE1)
	{
		// 회전각은 +- 20을 허용치로함
		// 임의의 회전각을 부여하여 해당 값일때의 rotationData를 계산
		// 이때의 rotationData가 대칭을 이루는지 이루지 않는지를 판별하여 최종적인 회전각을 산출함
		// (비대칭 카운트 횟수가 최소 허용치를 벗어나지 않는다면 이때의 angle값이 최종 회전각이 된다)
		// 정제 모양에 따라 회전각을 구하는 방식을 달리함
		for (int r = -20; r <= 20; r++)
		{
			XasymmetryCount = 0;
			YasymmetryCount = 0;
			memset(rotationData, 0, ImageWidth*ImageHeight);
			for (int i = startY; i < endY; i++)
			{
				for (int j = startX; j < endX; j++)
				{
					if (*(expansionTempData + ImageWidth * i + j))
					{
						if (r >= 0)
						{
							rX = ((j - tabletCenterX) * cosData[r] - (i - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX;
							rY = ((j - tabletCenterX) * sinData[r] + (i - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY;
						}
						else
						{
							rX = ((j - tabletCenterX) * cosData[-r] + (i - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX;
							rY = (-(j - tabletCenterX) * sinData[-r] + (i - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY;
						}
						rotationData[rY*ImageWidth + rX] = 1;
					}
				}
			}
			for (int i = startY; i < endY; i++)
			{
				for (int j = startX; j < endX; j++)
				{
					if (*(rotationData + ImageWidth * i + j))
					{
						tempX = 2 * tabletCenterX - j;
						tempY = 2 * tabletCenterY - i;
						if (*(rotationData + ImageWidth * tempY + j) == 0)
							YasymmetryCount++;
						if (*(rotationData + ImageWidth * i + tempX) == 0)
							XasymmetryCount++;
					}
				}
			}
			if (minValue > XasymmetryCount*YasymmetryCount)
			{
				minValue = XasymmetryCount * YasymmetryCount;
				angle = -(float)r / 2.0;
			}
		}
	}
	else if (option == CASE2)
	{
		if (TabletCharacter.shape == TRIANGLE)
		{
			for (int r = -120; r <= 120; r++) ///삼각형 120
			{
				XasymmetryCount = 0;
				YasymmetryCount = 0;
				memset(rotationData, 0, ImageWidth*ImageHeight);
				for (int i = startY; i < endY; i++)
				{
					for (int j = startX; j < endX; j++)
					{
						if (*(expansionTempData + ImageWidth * i + j))
						{
							if (r >= 0)
							{
								rX = ((j - tabletCenterX) * cosData[r] - (i - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX;
								rY = ((j - tabletCenterX) * sinData[r] + (i - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY;
							}
							else
							{
								rX = ((j - tabletCenterX) * cosData[-r] + (i - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX;
								rY = (-(j - tabletCenterX) * sinData[-r] + (i - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY;
							}
							rotationData[rY*ImageWidth + rX] = 1;
							rotationData[rY*ImageWidth + rX - 1] = 1;
							rotationData[(rY - 1)*ImageWidth + rX] = 1;
						}
					}
				}
				for (int i = startY; i < endY; i++)
				{
					for (int j = startX; j < endX; j++)
					{
						if (*(rotationData + ImageWidth * i + j))
						{
							tempX = 2 * tabletCenterX - j;
							//                        tempY = 2*tabletCenterY - i;
							if (i <= tabletCenterY)
								YasymmetryCount++;
							if (*(rotationData + ImageWidth * i + tempX) == 0)
								XasymmetryCount++;
						}
					}
				}
				if (minValue > XasymmetryCount + YasymmetryCount)
				{
					minValue = XasymmetryCount + YasymmetryCount;
					angle = -(float)r / 2.0;
				}
			}
		}
		if (TabletCharacter.shape == HEXA)
		{
			int AccCenterX;
			int AccCenterY;
			int AccCnt;

			int rotationCenterX;
			int rotationCenterY;

			int ShapeStartX;
			int ShapeEndX;

			int pointDistance;
			int MaxDistance = 0;

			for (int r = -60; r <= 60; r++) // -30~30도 회전시켜봄
			{
				XasymmetryCount = 0;
				YasymmetryCount = 0;
				yPoisitionSum = 0;
				totalPixelCount = 0;

				AccCenterX = 0;
				AccCenterY = 0;
				AccCnt = 0;

				rotationCenterX = 0;
				rotationCenterY = 0;

				ShapeStartX = 0;
				ShapeEndX = 0;

				pointDistance = 0;

				memset(rotationData, 0, ImageWidth*ImageHeight);
				for (int i = startY; i < endY; i++)
				{
					for (int j = startX; j < endX; j++)
					{
						if (*(expansionTempData + ImageWidth * i + j))
						{
							if (r >= 0)
							{
								rX = ((j - tabletCenterX) * cosData[r] - (i - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX;
								rY = ((j - tabletCenterX) * sinData[r] + (i - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY;
							}
							else
							{
								rX = ((j - tabletCenterX) * cosData[-r] + (i - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX;
								rY = (-(j - tabletCenterX) * sinData[-r] + (i - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY;
							}
							rotationData[rY*ImageWidth + rX] = 1;
							rotationData[rY*ImageWidth + rX - 1] = 1;
							rotationData[(rY - 1)*ImageWidth + rX] = 1;
						}
					}
				}

				for (int i = startY; i < endY; i++)
				{
					for (int j = startX; j < endX; j++)
					{
						if (*(rotationData + ImageWidth * i + j))
						{
							AccCenterX += j;
							AccCenterY += i;
							AccCnt++;
						}
					}
				}

				if (AccCnt != 0)
				{
					rotationCenterX = AccCenterX / AccCnt;
					rotationCenterY = AccCenterY / AccCnt;
				}
				else
				{
					rotationCenterX = 320;
					rotationCenterY = 240;
				}

				for (int j = startX; j < endX; j++)
				{
					if (*(rotationData + ImageWidth * rotationCenterY + j))
					{
						ShapeStartX = j;
						break;
					}
				}

				for (int j = endX; j > startX; j--)
				{
					if (*(rotationData + ImageWidth * rotationCenterY + j))
					{
						ShapeEndX = j;
						break;
					}
				}

				pointDistance = abs(ShapeEndX - ShapeStartX);

				for (int i = startY; i < endY; i++)
				{
					for (int j = startX; j < endX; j++)
					{
						if (*(rotationData + ImageWidth * i + j))
						{
							tempX = 2 * tabletCenterX - j;
							if (i > tabletCenterY)
							{
								yPoisitionSum += i;
								totalPixelCount++;
							}
							if (i <= tabletCenterY)
								YasymmetryCount++;
							if (*(rotationData + ImageWidth * i + tempX) == 0)
								XasymmetryCount++;
						}
					}
				}
				if (minValue > XasymmetryCount + YasymmetryCount && pointDistance > MaxDistance)
				{
					MaxDistance = pointDistance;
					minValue = XasymmetryCount + YasymmetryCount;
					angle = -(float)r / 2.0;
				}
			}
		}
		if (TabletCharacter.shape == SQUARE)
		{
			for (int r = 0; r <= 720; r++)
			{
				if (r < 180)
				{
					XasymmetryCount = 0;
					YasymmetryCount = 0;
					yPoisitionSum = 0;
					totalPixelCount = 0;
					memset(rotationData, 0, ImageWidth*ImageHeight);
					for (int i = startY; i < endY; i++)
					{
						for (int j = startX; j < endX; j++)
						{
							if (*(expansionTempData + ImageWidth * i + j))
							{
								if (r >= 0)
								{
									rX = ((j - tabletCenterX) * cosData[r] - (i - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX;
									rY = ((j - tabletCenterX) * sinData[r] + (i - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY;
								}
								else
								{
									rX = ((j - tabletCenterX) * cosData[-r] + (i - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX;
									rY = (-(j - tabletCenterX) * sinData[-r] + (i - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY;
								}
								rotationData[rY*ImageWidth + rX] = 1;
								rotationData[rY*ImageWidth + rX - 1] = 1;
								rotationData[(rY - 1)*ImageWidth + rX] = 1;
							}
						}
					}
					for (int i = startY; i < endY; i++)
					{
						for (int j = startX; j < endX; j++)
						{
							if (*(rotationData + ImageWidth * i + j))
							{
								tempX = 2 * tabletCenterX - j;
								if (i > tabletCenterY)
								{
									yPoisitionSum += i;
									totalPixelCount++;
								}
								if (i <= tabletCenterY)
									YasymmetryCount++;
								if (*(rotationData + ImageWidth * i + tempX) == 0)
									XasymmetryCount++;
							}
						}
					}
					y_WeightCenter[r] = yPoisitionSum / (totalPixelCount + 1);
					y_WeightCenter[r + 180] = y_WeightCenter[r];
					y_WeightCenter[r + 360] = y_WeightCenter[r];
					y_WeightCenter[r + 480] = y_WeightCenter[r];
					if (minValue > XasymmetryCount + YasymmetryCount)
					{
						minValue = XasymmetryCount + YasymmetryCount;
						angle = -(float)r / 2.0;
					}
				}
			}
			if (y_WeightCenter[abs((int)angle * 2)] < y_WeightCenter[(abs((int)angle * 2) + 90)])
				angle = angle + 45;

		}
	}
	else if (option == CASE3)
	{
		if (TabletCharacter.shape == ETC && TabletCharacter.symmetric_line_count == ASYMMETRY_TABLET)
		{
			int x, y;
			int tempAddress;
			int matchingCount;
			int forwardMaxMatchingCount;
			int reverseMaxMatchingCount;
			int forwardAngle;
      int forwardShiftX;
      int forwardShiftY;
			int reverseAngle;
      int reverseShiftX;
      int reverseShiftY;
			int shiftX, shiftY;
			int tempX, tempY;
			int m;
			int rX, rY;
			int edgeSW;
      int sX, sY;
			unsigned char binaryEdgeData[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];
			memset(binaryEdgeData, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

			for (int i = startY; i < endY; i++)
			{
				for (int j = startX; j < endX; j++)
				{
					edgeSW = 0;
					if (*(expansionTempData + ImageWidth * i + j))
					{
						if (*(expansionTempData + ImageWidth * (i + 4) + (j)) == 0) edgeSW = 1;
						else if (*(expansionTempData + ImageWidth * (i - 4) + (j)) == 0) edgeSW = 1;
						else if (*(expansionTempData + ImageWidth * (i)+(j + 4)) == 0) edgeSW = 1;
						else if (*(expansionTempData + ImageWidth * (i)+(j - 4)) == 0) edgeSW = 1;


						if (edgeSW)
						{
							binaryEdgeData[ImageWidth*i + j] = 1;
						}
					}
				}
			}

			shiftX = tabletCenterX - MAX_IMAGE_WIDTH / 2;
			shiftY = tabletCenterY - MAX_IMAGE_HEIGHT / 2;

			// 정방향 회전
			forwardMaxMatchingCount = 0;

			for (int r = 0; r < 720; r+=2)
			{
        for(sY = -10; sY <= 10; sY+=2)
        {
          for(sX = -10; sX <= 10; sX+=2)
          {
            matchingCount = 0;
            for (m = 0; m < ETC_FrontShapeEdgeCount; m+=4)
            {
              tempX = ETC_FrontShapeEdgePoint[m][0] + shiftX;
              tempY = ETC_FrontShapeEdgePoint[m][1] + shiftY;

              if (r >= 0)
              {
                rX = ((tempX - tabletCenterX) * cosData[r] - (tempY - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX + sX;
                rY = ((tempX - tabletCenterX) * sinData[r] + (tempY - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY + sY;
              }
              else
              {
                rX = ((tempX - tabletCenterX) * cosData[-r] + (tempY - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX + sX;
                rY = (-(tempX - tabletCenterX) * sinData[-r] + (tempY - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY + sY;
              }

              if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
              {
                if (*(binaryEdgeData + ImageWidth * rY + rX))
                  matchingCount++;
              }
            }

            if (matchingCount > forwardMaxMatchingCount)
            {
              forwardMaxMatchingCount = matchingCount;
              forwardAngle = r;
              forwardShiftX = sX;
              forwardShiftY = sY;
            }
          }
        }
			}

			// 정제 뒤집어서 회전
			reverseMaxMatchingCount = 0;

			for (int r = 0; r < 720; r+=2)
			{
        for(sY = -10; sY <= 10; sY+=2)
        {
          for(sX = -10; sX <= 10; sX+=2)
          {
            matchingCount = 0;
            for (m = 0; m < ETC_FrontShapeEdgeCount; m+=4)
            {
              tempX = (MAX_IMAGE_WIDTH - ETC_FrontShapeEdgePoint[m][0]) + shiftX;
              tempY = ETC_FrontShapeEdgePoint[m][1] + shiftY;

              if (r >= 0)
              {
                rX = ((tempX - tabletCenterX) * cosData[r] - (tempY - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX + sX;
                rY = ((tempX - tabletCenterX) * sinData[r] + (tempY - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY + sY;
              }
              else
              {
                rX = ((tempX - tabletCenterX) * cosData[-r] + (tempY - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX + sX;
                rY = (-(tempX - tabletCenterX) * sinData[-r] + (tempY - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY + sY;
              }

              if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
              {
                if (*(binaryEdgeData + ImageWidth * rY + rX))
                  matchingCount++;
              }
            }

            if (matchingCount > reverseMaxMatchingCount)
            {
              reverseMaxMatchingCount = matchingCount;
              reverseAngle = r;
              reverseShiftX = sX;
              reverseShiftY = sY;
            }
          }
        }
			}

			int testAngle;
			if (forwardMaxMatchingCount > reverseMaxMatchingCount)
			{
				tabletETCShape_UpSideDownSW = 0;
				testAngle = forwardAngle;
				angle = (float)forwardAngle / 2.0;
        sX = forwardShiftX;
        sY = forwardShiftY;

				for (m = 0; m < ETC_FrontShapeEdgeCount; m++)
				{
					tempX = ETC_FrontShapeEdgePoint[m][0] + shiftX;
					tempY = ETC_FrontShapeEdgePoint[m][1] + shiftY;

					if (testAngle >= 0)
					{
						rX = ((tempX - tabletCenterX) * cosData[testAngle] - (tempY - tabletCenterY)* sinData[testAngle]) / 1024 + tabletCenterX + sX;
						rY = ((tempX - tabletCenterX) * sinData[testAngle] + (tempY - tabletCenterY)* cosData[testAngle]) / 1024 + tabletCenterY + sY;
					}
					else
					{
						rX = ((tempX - tabletCenterX) * cosData[-testAngle] + (tempY - tabletCenterY) * sinData[-testAngle]) / 1024 + tabletCenterX + sX;
						rY = (-(tempX - tabletCenterX) * sinData[-testAngle] + (tempY - tabletCenterY) * cosData[-testAngle]) / 1024 + tabletCenterY + sY;
					}

					if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
					{
						rotationData[rY*ImageWidth + rX] = 1;
					}
				}
			}
			else
			{
				tabletETCShape_UpSideDownSW = 1;
				testAngle = reverseAngle;
				angle = (float)-reverseAngle / 2.0;
        sX = reverseShiftX;
        sY = reverseShiftY;

				for (m = 0; m < ETC_FrontShapeEdgeCount; m++)
				{
					tempX = (MAX_IMAGE_WIDTH - ETC_FrontShapeEdgePoint[m][0]) + shiftX;
					tempY = ETC_FrontShapeEdgePoint[m][1] + shiftY;

					if (testAngle >= 0)
					{
						rX = ((tempX - tabletCenterX) * cosData[testAngle] - (tempY - tabletCenterY)* sinData[testAngle]) / 1024 + tabletCenterX + sX;
						rY = ((tempX - tabletCenterX) * sinData[testAngle] + (tempY - tabletCenterY)* cosData[testAngle]) / 1024 + tabletCenterY + sY;
					}
					else
					{
						rX = ((tempX - tabletCenterX) * cosData[-testAngle] + (tempY - tabletCenterY) * sinData[-testAngle]) / 1024 + tabletCenterX + sX;
						rY = (-(tempX - tabletCenterX) * sinData[-testAngle] + (tempY - tabletCenterY) * cosData[-testAngle]) / 1024 + tabletCenterY + sY;
					}

					if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
					{
						rotationData[rY*ImageWidth + rX] = 1;
					}
				}
			}

			Byte *ptr;
			for (int i = startY; i < endY; i++)
			{
				ptr = (Byte*)Image1->Picture->Bitmap->ScanLine[i];
				for (int j = startX; j < endX; j++)
				{
					if (*(rotationData + ImageWidth * i + j))
					{
						ptr[3 * j + 0] = ColorSrcImg[(ImageWidth*i + j) * 3 + 2];
						ptr[3 * j + 1] = ColorSrcImg[(ImageWidth*i + j) * 3 + 0];
						ptr[3 * j + 2] = 200;
					}
					else
					{
						ptr[3 * j + 0] = ColorSrcImg[(ImageWidth*i + j) * 3 + 0];
						ptr[3 * j + 1] = ColorSrcImg[(ImageWidth*i + j) * 3 + 1];
						ptr[3 * j + 2] = ColorSrcImg[(ImageWidth*i + j) * 3 + 2];
					}
				}
			}
			Image1->Canvas->Brush->Style = bsSolid;
			Image1->Canvas->Brush->Color = clRed;
			Image1->Canvas->Rectangle(tabletCenterX - 2, tabletCenterY - 2, tabletCenterX + 2, tabletCenterY + 2);

			Image1->Refresh();

			delete(tabletOutLineNeighborPixel);
			delete(rotationData);
			return(angle);
		}
		else
		{
			for (int r = -120; r < 120; r++) // -> 정렬 되는 정제이므로 회전각을 90도 이상으로는 부여하지 않음(현재는 +-60도)
			{
				if (TabletCharacter.symmetric_line_count == 1) // 좌우 대칭형
				{
					XasymmetryCount = 0;
					YasymmetryCount = 0;
					yPoisitionSum = 0;
					totalPixelCount = 0;
					memset(rotationData, 0, ImageWidth*ImageHeight);
					for (int i = startY; i < endY; i++)
					{
						for (int j = startX; j < endX; j++)
						{
							if (*(expansionTempData + ImageWidth * i + j))
							{
								if (r >= 0)
								{
									rX = ((j - tabletCenterX) * cosData[r] - (i - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX;
									rY = ((j - tabletCenterX) * sinData[r] + (i - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY;
								}
								else
								{
									rX = ((j - tabletCenterX) * cosData[-r] + (i - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX;
									rY = (-(j - tabletCenterX) * sinData[-r] + (i - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY;
								}
								rotationData[rY*ImageWidth + rX] = 1;
								rotationData[rY*ImageWidth + rX - 1] = 1;
								rotationData[(rY - 1)*ImageWidth + rX] = 1;
							}
						}
					}
					for (int i = startY; i < endY; i++)
					{
						for (int j = startX; j < endX; j++)
						{
							if (*(rotationData + ImageWidth * i + j))
							{
								tempX = 2 * tabletCenterX - j;
								if (*(rotationData + ImageWidth * i + tempX) == 0)
									XasymmetryCount++;
							}
						}
					}
					if (minValue > XasymmetryCount)
					{
						minValue = XasymmetryCount;
						angle = -(float)r / 2.0;
					}
				}
				else if (TabletCharacter.symmetric_line_count == 2 && r < 360)
				{
					XasymmetryCount = 0;
					YasymmetryCount = 0;
					yPoisitionSum = 0;
					totalPixelCount = 0;
					memset(rotationData, 0, ImageWidth*ImageHeight);
					for (int i = startY; i < endY; i++)
					{
						for (int j = startX; j < endX; j++)
						{
							if (*(expansionTempData + ImageWidth * i + j))
							{
								if (r >= 0)
								{
									rX = ((j - tabletCenterX) * cosData[r] - (i - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX;
									rY = ((j - tabletCenterX) * sinData[r] + (i - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY;
								}
								else
								{
									rX = ((j - tabletCenterX) * cosData[-r] + (i - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX;
									rY = (-(j - tabletCenterX) * sinData[-r] + (i - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY;
								}
								rotationData[rY*ImageWidth + rX] = 1;
								rotationData[rY*ImageWidth + rX - 1] = 1;
								rotationData[(rY - 1)*ImageWidth + rX] = 1;
							}
						}
					}
					for (int i = startY; i < endY; i++)
					{
						for (int j = startX; j < endX; j++)
						{
							if (*(rotationData + ImageWidth * i + j))
							{
								tempX = 2 * tabletCenterX - j;
								tempY = 2 * tabletCenterY - i;

								if (*(rotationData + ImageWidth * tempY + j) == 0)
									YasymmetryCount++;
								if (*(rotationData + ImageWidth * i + tempX) == 0)
									XasymmetryCount++;
							}
						}
					}
					//y_WeightCenter[r] = yPoisitionSum/(totalPixelCount+1);
					//y_WeightCenter[r+360] = y_WeightCenter[r];
					if (minValue > (XasymmetryCount))
					{
						minValue = (XasymmetryCount);
						angle = -(float)r / 2.0;
					}
				}
			}

			/*
			if(TabletCharacter.symmetric_line_count == 2)
			{
			if(y_WeightCenter[abs((int)angle*2)] > y_WeightCenter[ (abs((int)angle*2)+180)] )
			angle = angle + 90;
			}
			if(TabletCharacter.arrangeInfo == ARRANGE)
			angle =  angle + 90;
			*/
		}
	}

	Image1->Canvas->Pen->Width = 3;
	Image1->Canvas->Pen->Color = clBlue;
	Image1->Canvas->MoveTo(-100 + tabletCenterX, (int)(tan(angle*PI / 180.0)*(float)(-100)) + tabletCenterY);
	Image1->Canvas->LineTo(100 + tabletCenterX, (int)(tan(angle*PI / 180.0)*(float)(100)) + tabletCenterY);
	Image1->Refresh();

	delete(tabletOutLineNeighborPixel);
	delete(rotationData);
	return(angle);
}
//---------------------------------------------------------------------------
int __fastcall TTabletCharacterExtractForm::LabellingForTabletImage(short *label_Image, unsigned char *smallSizeBinaryImage, int startX, int endX, int startY, int endY, int imageWidth, int imageHeight)
{
	int i, x, y;
	int temp_address;
	int currentLabel;
	int new_count;
	short CollisionArray[MAX_LABEL_COUNT];
	int newLval;
	int temp;
	// int checkSW;
	//  int minValue;
	int tempAddress;
	// int smallSizeImagWidth;
	//  int smallSizeImagHeight;
	int maxLabelN;
	int maxLabelCount;
	int breakSW;
	unsigned short Pixel_N_Of_Label[MAX_LABEL_COUNT]; //4k
	int StartX_Label[MAX_LABEL_COUNT];
	int EndX_Label[MAX_LABEL_COUNT];
	int StartY_Label[MAX_LABEL_COUNT];
	int EndY_Label[MAX_LABEL_COUNT];

	currentLabel = 0;
	for (i = 0; i < MAX_LABEL_COUNT; i++)
	{
		CollisionArray[i] = i;
		Pixel_N_Of_Label[i] = 0;
		StartX_Label[i] = 640;
		EndX_Label[i] = 0;
		StartY_Label[i] = 640;
		EndY_Label[i] = 0;
	}
	breakSW = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			temp_address = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + temp_address))
			{
				if (*(label_Image + temp_address - imageWidth) == 0)     // up is background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is also background
					{
						currentLabel++;
						*(label_Image + temp_address) = currentLabel; // first label number is '1'  
					}
					else                        // left is not background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - 1);
					}
				}
				else                // up is not background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
					}
					else                        // left is not background
					{
						if (*(label_Image + temp_address - imageWidth) == *(label_Image + temp_address - 1))
						{
							*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
						}
						else        // collision detected
						{           // Left label이 Up label보다 항상 크다
							CollisionArray[max(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth))] =
								min(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth));
							*(label_Image + temp_address) = CollisionArray[*(label_Image + temp_address - imageWidth)];
						}
					}
				}
				if (currentLabel >= MAX_LABEL_COUNT - 1)
				{
					breakSW = 1;
					break;
				}
			}
		}
		if (breakSW == 1)
			break;
	}
	newLval = 1;
	for (i = 1; i <= currentLabel; i++)
	{
		if (CollisionArray[CollisionArray[i]] > newLval)
		{
			newLval++;
			CollisionArray[i] = newLval;
		}
		else
		{
			CollisionArray[i] = CollisionArray[CollisionArray[i]];
		}
	}
	if (newLval > MAX_LABEL_COUNT)  newLval = MAX_LABEL_COUNT - 1;
	new_count = newLval;

	for (y = 0; y < imageHeight; y++)
	{
		for (x = 0; x < imageWidth; x++)
		{
			tempAddress = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + tempAddress))
			{
				temp = *(label_Image + tempAddress);
				temp = CollisionArray[temp];
				*(label_Image + tempAddress) = temp;
				Pixel_N_Of_Label[temp]++;
				if (StartX_Label[temp] > x)  StartX_Label[temp] = x;
				if (StartY_Label[temp] > y)  StartY_Label[temp] = y;
				if (EndX_Label[temp] < x)  EndX_Label[temp] = x;
				if (EndY_Label[temp] < y)  EndY_Label[temp] = y;
			}
		}
	}
	maxLabelN = 0;
	maxLabelCount = 0;
	for (i = 1; i <= new_count; i++)
	{
		if (Pixel_N_Of_Label[i] > maxLabelCount)
		{
			maxLabelN = i;
			maxLabelCount = Pixel_N_Of_Label[i];
		}
	}
	return(maxLabelN);
}
//---------------------------------------------------------------------------
int __fastcall TTabletCharacterExtractForm::LabellingForTabletThreeDImage(short *label_Image, unsigned char *smallSizeBinaryImage, int startX, int endX, int startY, int endY)
{
	int i, j, m, x, y, r;
	int temp_address;
	int currentLabel;
	int new_count;
	short CollisionArray[MAX_LABEL_COUNT];
	unsigned short Pixel_N_Of_Label[MAX_LABEL_COUNT]; //4k
	short Pixel_N_Of_MoreDarkOfLabel[MAX_LABEL_COUNT];//4k
	short StartX_Label[MAX_LABEL_COUNT]; //4k
	short EndX_Label[MAX_LABEL_COUNT]; //4k
	short StartY_Label[MAX_LABEL_COUNT]; //4k
	short EndY_Label[MAX_LABEL_COUNT]; //4k
	int newLval;
	int temp;
	int checkSW;
	int minValue;
	int tempAddress;
	int smallSizeImagWidth;
	int smallSizeImagHeight;
	int maxLabelN;
	int maxLabelCount;
	int breakSW;
	smallSizeImagWidth = IMAGE_3D_WIDTH / 4;
	smallSizeImagHeight = IMAGE_3D_HEIGHT / 4;
	currentLabel = 0;
	for (i = 0; i < MAX_LABEL_COUNT; i++)
	{
		CollisionArray[i] = i;
		Pixel_N_Of_Label[i] = 0;
		StartX_Label[i] = IMAGE_3D_WIDTH;
		EndX_Label[i] = 0;
		StartY_Label[i] = IMAGE_3D_WIDTH;
		EndY_Label[i] = 0;
	}
	breakSW = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			temp_address = smallSizeImagWidth * (y)+x;
			if (*(smallSizeBinaryImage + temp_address))
			{
				if (*(label_Image + temp_address - smallSizeImagWidth) == 0)     // up is background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is also background
					{
						currentLabel++;
						*(label_Image + temp_address) = currentLabel; // first label number is '1'
					}
					else                        // left is not background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - 1);
					}
				}
				else                // up is not background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - smallSizeImagWidth);
					}
					else                        // left is not background
					{
						if (*(label_Image + temp_address - smallSizeImagWidth) == *(label_Image + temp_address - 1))
						{
							*(label_Image + temp_address) = *(label_Image + temp_address - smallSizeImagWidth);
						}
						else        // collision detected
						{           // Left label이 Up label보다 항상 크다
							CollisionArray[max(*(label_Image + temp_address - 1), *(label_Image + temp_address - smallSizeImagWidth))] =
								min(*(label_Image + temp_address - 1), *(label_Image + temp_address - smallSizeImagWidth));
							*(label_Image + temp_address) = CollisionArray[*(label_Image + temp_address - smallSizeImagWidth)];
						}
					}
				}
				if (currentLabel >= MAX_LABEL_COUNT - 1)
				{
					breakSW = 1;
					break;
				}
			}
		}
		if (breakSW == 1)
			break;
	}
	newLval = 1;
	for (i = 1; i <= currentLabel; i++)
	{
		if (CollisionArray[CollisionArray[i]] > newLval)
		{
			newLval++;
			CollisionArray[i] = newLval;
		}
		else
		{
			CollisionArray[i] = CollisionArray[CollisionArray[i]];
		}
	}
	if (newLval > 500)  newLval = 499;
	new_count = newLval;

	for (y = 0; y < smallSizeImagHeight; y++)
	{
		for (x = 0; x < smallSizeImagWidth; x++)
		{
			tempAddress = smallSizeImagWidth * (y)+x;
			if (*(smallSizeBinaryImage + tempAddress))
			{
				temp = *(label_Image + tempAddress);
				temp = CollisionArray[temp];
				*(label_Image + tempAddress) = temp;
				Pixel_N_Of_Label[temp]++;
				if (StartX_Label[temp] > x)  StartX_Label[temp] = x;
				if (StartY_Label[temp] > y)  StartY_Label[temp] = y;
				if (EndX_Label[temp] < x)  EndX_Label[temp] = x;
				if (EndY_Label[temp] < y)  EndY_Label[temp] = y;
			}
		}
	}
	maxLabelN = 0;
	maxLabelCount = 0;
	for (i = 1; i <= new_count; i++)
	{
		if (Pixel_N_Of_Label[i] > maxLabelCount)
		{
			maxLabelN = i;
			maxLabelCount = Pixel_N_Of_Label[i];
		}
	}
	return(maxLabelN);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ShapeExtract(unsigned char *colorSourceImage, unsigned char *accumulateShapeImage, int rgb, int protoThreshold, int startX, int endX, int startY, int endY, int *meanColor, int cameraIndex)
{
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;
	int tempCenterX, tempCenterY;
	int tCnt;
	int edgePoint[2000][2];
	int edgePointCount = 0;
	int edgeCheckSW;
	bool breakSW;
	int range = 30;
	int uLength;
	int tempPosiX;
	int tempPosiY;
	int meanGrayForInnerEdgeLine[2000] = { 0, };
	int meanGrayCountForInnerEdgeLine[2000] = { 0, };
	int neighborRange = 40;
	int resultCenterX, resultCenterY;
	int cnt;
	int tempX, tempY;
	float angle;
	int smallSizeImagWidth;
	int maxLabelN;
	int tempMeanColor[3];
	unsigned char smallSizeBinaryImage[(640 / 4)*(480 / 4)];  //19k
	short smallSizeLabelImage[(640 / 4)*(480 / 4)];  //38k  -> 2byte 변수로 선언한 이유는?

	tempMeanColor[0] = tempMeanColor[1] = tempMeanColor[2] = 0;
	unsigned char *binarizationData;
	unsigned char *edgeNeighborData;
	unsigned char *tempData;
	unsigned char *expansionTempData;

	binarizationData = new unsigned char[ImageWidth*ImageHeight];
	edgeNeighborData = new unsigned char[ImageWidth*ImageHeight];
	tempData = new unsigned char[ImageWidth*ImageHeight];
	expansionTempData = new unsigned char[ImageWidth*ImageHeight];
	smallSizeImagWidth = ImageWidth / 4;
	for (int i = 0; i < ImageHeight; i++)
	{
		for (int j = 0; j < ImageWidth; j++)
		{
			*(binarizationData + ImageWidth * i + j) = 0;
			*(edgeNeighborData + ImageWidth * i + j) = 0;
			*(tempData + ImageWidth * i + j) = 0;
			*(expansionTempData + ImageWidth * i + j) = 0;
		}
	}

	memset(smallSizeBinaryImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeLabelImage, 0, (ImageWidth / 4)*(ImageHeight / 4) * 2);

	//이때 smallSizeBinaryImage에는 정제뿐만아니라 벨트나 잡음 등의 좌표에도 역시 1이라는 값이 할당된다.
	for (int y = startY; y < endY; y++)
	{
		for (int x = startX; x < endX; x++)
		{
      if (*(colorSourceImage + (ImageWidth*y + x) * 3 + 1) > protoThreshold || *(colorSourceImage + (ImageWidth*y + x) * 3 + 2) > protoThreshold
        || *(colorSourceImage + (ImageWidth*y + x) * 3 + 2) - *(colorSourceImage + (ImageWidth*y + x) * 3) > 30)
        smallSizeBinaryImage[smallSizeImagWidth*(y / 4) + x / 4] = 1;
		}
	}
	maxLabelN = LabellingForTabletImage(smallSizeLabelImage, smallSizeBinaryImage, startX / 4, endX / 4, startY / 4, endY / 4, ImageWidth / 4, ImageHeight / 4);
	// 함수 실행 후 smallSizeLabelImage에는 임의로 정의한 Threshold값(40)을 기준으로 이 값보다 큰 Gray 값을 갖는 모든 pixel에 특정 값이 할당된다.
	// 아마 촬영된 밝기에 따라 해당 이미지에는 벨트나 정제, 기타 잡음의 위치에 특정 값이 할당될 수 있다.
	// 이때 픽셀간의 연결에 의해 형성되는 가장커다란 덩어리는 정제가 될것이고 이미지 상에서 정제의 위치에 할당된 pixel값은 maxLabelN이 될 것이다.


	// 가공된 smallSizeLabelImage는 전범위의 좌표를 스캔하면서 픽셀값이 maxLabelN인 좌표지점을 찾는다.
	// 픽셀값이 maxLabelN인 좌표는 분명 이미지상에서 정제의 위치가 될것이며 smallSizeBinaryImage에는 동일한 좌표값에 2라는 값을 할당한다.
	// 따라서 Labelling 처리에 의해 smallSizeBinaryImage에는 2라는 값으로 정제의 위치를 찾게 된다.
	for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
	{
		for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
		{
			if (smallSizeLabelImage[(y)*smallSizeImagWidth + (x)] == maxLabelN)
			{
				for (int i = y - 1; i <= y + 1; i++)
				{
					for (int j = x - 1; j <= x + 1; j++)
					{
						smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
					}
				}
			}
		}
	}

  int minX, maxX;
  int binSW;
  int tempAddress;
  for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
  {
    minX = MAX_IMAGE_WIDTH;
    maxX = 0;

    binSW = 0;
    for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
    {
      tempAddress = (y)*smallSizeImagWidth + (x);

      if(smallSizeBinaryImage[tempAddress] == 2)
      {
        binSW = 1;

        if(minX > x) minX = x;
        if(maxX < x) maxX = x;
      }
    }

    if(binSW)
    {
      for (int x = minX; x <= maxX; x++)
      {
        tempAddress = (y)*smallSizeImagWidth + (x);
        smallSizeBinaryImage[tempAddress] = 2;
      }
    }
  }


	tempCenterX = 0;
	tempCenterY = 0;
	tCnt = 0;

	// 현재 smallSizeBinaryImage에는 픽셀값에 2가 할당되면서 정제의 위치정보를 알 수 있게 되었다.
	// 해당 좌표를 토대로 정제의 Center Position과 Average Color를 산출하는 과정이 다음이다.
	// 또한 이과정에서 tempData에는 smallSizeBinaryImage의 값이 2일때의 좌표값에 1이라는 값이 할당된다.(정제모양)
	for (int y = startY; y < endY; y++)
	{
		for (int x = startX; x < endX; x++)
		{
			tempAddress = y * ImageWidth + x;
			if (smallSizeBinaryImage[(y / 4)*smallSizeImagWidth + (x / 4)] == 2)
			{
        if (*(colorSourceImage + (ImageWidth*y + x) * 3 + 1) > protoThreshold || *(colorSourceImage + (ImageWidth*y + x) * 3 + 2) > protoThreshold
					|| *(colorSourceImage + (ImageWidth*y + x) * 3 + 2) - *(colorSourceImage + (ImageWidth*y + x) * 3) > 30)
				{
          *(tempData + ImageWidth * y + x) = 1;
        }
			}
		}
	}

  for (int y = startY; y < endY; y++)
  {
    minX = MAX_IMAGE_WIDTH;
    maxX = 0;

    binSW = 0;
    for (int x = startX; x < endX; x++)
    {
      if(*(tempData + ImageWidth * y + x))
      {
        binSW = 1;

        if(minX > x) minX = x;
        if(maxX < x) maxX = x;
      }
    }

    if(binSW)
    {
      for (int x = minX; x <= maxX; x++)
      {
        *(tempData + ImageWidth * y + x) = 1;

        tempCenterX += x;
        tempCenterY += y;
        tempMeanColor[0] += *(colorSourceImage + (ImageWidth*y + x) * 3);
        tempMeanColor[1] += *(colorSourceImage + (ImageWidth*y + x) * 3 + 1);
        tempMeanColor[2] += *(colorSourceImage + (ImageWidth*y + x) * 3 + 2);
        tCnt++;
      }
    }
  }

	if (tCnt)
	{
		tempCenterX = tempCenterX / tCnt;
		tempCenterY = tempCenterY / tCnt;
		tempMeanColor[0] /= tCnt;
		tempMeanColor[1] /= tCnt;
		tempMeanColor[2] /= tCnt;
	}
	meanColor[0] += tempMeanColor[0];
	meanColor[1] += tempMeanColor[1];
	meanColor[2] += tempMeanColor[2];

	// 제대로 찍히지 않은 경우는 통과.
	if (tCnt < 6400 || tempCenterX < 100 || tempCenterX > MAX_IMAGE_WIDTH - 100 || tempCenterY < 100 || tempCenterY > MAX_IMAGE_HEIGHT - 100)
	{
		delete(img1);
		delete(binarizationData);
		delete(edgeNeighborData);
		delete(tempData);
		delete(expansionTempData);
		return;
	}

	if (TabletCharacter.kind != SUGARCOATING)
	{
		breakSW = false;

		// 현재 StartX, Y, EndX, Y는 검사하는 정제의 영역만이 아닌 이미지 전체의 범위를 의미한다.
		// tempData에는 현재 smallSizeBinaryImage에서 그 값이 2인 경우, 즉 Threshold에 의해 확인된 정제의 모양정보가 할당되어있다.
		// 이 과정은 정제의 Edge Point를 찾는 과정인데, tempData를 전범위 스캔하면서 tempData의 값이 1인 좌표를 기준으로 상하좌우의 픽셀값을 확인하여 해당 값이 0이 되는 경우 그 부분은 모서리 좌표임을 의미한다는 것을 이용한다.
		for (int i = startY; i < endY; i++)
		{
			for (int j = startX; j < endX; j++)
			{
				if (*(tempData + ImageWidth * i + j))
				{
					edgeCheckSW = 0;
					if (*(tempData + ImageWidth * (i + 1) + j) == 0)  edgeCheckSW = 1; // Up
					if (*(tempData + ImageWidth * (i - 1) + j) == 0)  edgeCheckSW = 1; // Down
					if (*(tempData + ImageWidth * (i)+j - 1) == 0)  edgeCheckSW = 1; // Left
					if (*(tempData + ImageWidth * (i)+j + 1) == 0)  edgeCheckSW = 1; // Right
					if (edgeCheckSW == 1)
					{
						edgePoint[edgePointCount][0] = j; // edgePoint는 x,y 좌표를 구분하기 위해 2차원 배열로 정의한다.
						edgePoint[edgePointCount][1] = i;
						edgePointCount++;
						if (edgePointCount >= 2000) // edge의 총 개수는 2000개로 제한해두었다.
						{
							breakSW = true;
							break;
						}
					}
				}
			}
			if (breakSW == true)
				break;
		}


		// 정제의 중심부로부터 특정 EdgePonint까지의 거리를 산출한다...
		// 아래의 코딩에 대해 임의 값을 적용하여 계산해본 결과 tempPosX,Y는 edgePoint를 기준으로 정제 내부의 좌표지점을 의미하게 된다.
		// 이에 따라 아래의 과정은 edgePoint를 기준으로 일정크기로 정제모양의 테두리를 형성하기 위한 작업이 아닌가 예상한다.
		for (int n = 0; n < edgePointCount; n++)
		{
			uLength = (edgePoint[n][0] - tempCenterX)*(edgePoint[n][0] - tempCenterX)	+ (edgePoint[n][1] - tempCenterY)*(edgePoint[n][1] - tempCenterY);
			uLength = sqrt(uLength + 1); // a^2 + b^2 = c^2

																	 // 산출된 거리정보를 이용하여 edgeNeighborData의 값을 입력하는데..
																	 // edgePoint[n][0], edgePoint[n][1]은 중심부와의 거리를 산출할때의 좌표값 
			for (int i = 0; i < range; i++) // range = 30, range가 의미하는 바는? -> 정제 테두리의 크기를 의미하는 것이 아닌가?
			{
				tempPosiX = (edgePoint[n][0] * (uLength - i) + tempCenterX * i) / uLength;
				tempPosiY = (edgePoint[n][1] * (uLength - i) + tempCenterY * i) / uLength;

				if (tempPosiX < 4 || tempPosiX > MAX_IMAGE_WIDTH - 4 || tempPosiY < 4 || tempPosiY > MAX_IMAGE_HEIGHT - 4)
					continue;

				for (int m = tempPosiY - 1; m <= tempPosiY + 1; m++)
				{
					for (int n = tempPosiX - 1; n <= tempPosiX + 1; n++)
					{
						*(tempData + ImageWidth * (m)+n) = 0;
						if (*(edgeNeighborData + ImageWidth * (m)+n) != 2)
							*(edgeNeighborData + ImageWidth * (m)+n) = 1;
					}
				}
				if (i >= range - 3) // 30 - 3
				{
					*(edgeNeighborData + ImageWidth * (tempPosiY)+tempPosiX) = 2;
				}
			}
		}

		// edgeNeighborData를 바탕으로 해당 좌표에서의 평균 색상을 산출한다.
		// edgeNeighborData는 정제의 최외곽선이 아닌 내부 테두리 정보를 가지고 있다.
		for (int n = 0; n < edgePointCount; n++)
		{
			uLength = (edgePoint[n][0] - tempCenterX)*(edgePoint[n][0] - tempCenterX)
				+ (edgePoint[n][1] - tempCenterY)*(edgePoint[n][1] - tempCenterY);
			if (uLength)
			{
				uLength = sqrt(uLength + 1);
				tempPosiX = (edgePoint[n][0] * (uLength - range) + tempCenterX * range) / uLength;
				tempPosiY = (edgePoint[n][1] * (uLength - range) + tempCenterY * range) / uLength;

				if (tempPosiX < 4 + neighborRange || tempPosiX > MAX_IMAGE_WIDTH - 4 - neighborRange || tempPosiY < 4 + neighborRange || tempPosiY > MAX_IMAGE_HEIGHT - 4 - neighborRange)
					continue;

				for (int i = tempPosiY - neighborRange; i <= tempPosiY + neighborRange; i++) // neighborRange = 40
				{
					for (int j = tempPosiX - neighborRange; j <= tempPosiX + neighborRange; j++)
					{
						if (i >= 1 && i < ImageHeight - 1 && j >= 1 && j < ImageWidth - 1)
						{
							if (*(edgeNeighborData + ImageWidth * (i)+j) == 2)
							{
								meanGrayForInnerEdgeLine[n] += *(colorSourceImage + (ImageWidth*(i)+j) * 3 + rgb);
								meanGrayCountForInnerEdgeLine[n]++;
							}
						}
					}
				}
			}
			if (meanGrayCountForInnerEdgeLine[n])
				meanGrayForInnerEdgeLine[n] /= meanGrayCountForInnerEdgeLine[n];
		}

		// 정제의 테두리 위치를 기준으로 상하좌우로 Color이미지와 meanGrayForInnerEdgeLine값을 비교하여 외곽 라운드로 추정되는 위치를 tempData에 저장한다. 
		// 결과적으로 tempData에는 정제 전체 좌표와 더불어 외곽선정보가 입력된다.
		// tempData : 1)정제 전체에 1이라는 값을 입력, 2)정제 외곽에 대해 Range범위 만큼 0이라는 값을 입력, 3)정제 외곽에서 meanGrayForInnerEdgeLine기준으로 Color이미지의 픽셀값이 큰 좌표 위치에 다시 1이라는 값을 입력
		for (int n = 0; n < edgePointCount; n++)
		{
			uLength = (edgePoint[n][0] - tempCenterX)*(edgePoint[n][0] - tempCenterX)
				+ (edgePoint[n][1] - tempCenterY)*(edgePoint[n][1] - tempCenterY);
			if (uLength)
			{
				uLength = sqrt(uLength);
				for (int i = 0; i < range; i++)
				{
					tempPosiX = (edgePoint[n][0] * (uLength - i) + tempCenterX * i) / uLength;
					tempPosiY = (edgePoint[n][1] * (uLength - i) + tempCenterY * i) / uLength;

					if (tempPosiX < 4 || tempPosiX > MAX_IMAGE_WIDTH - 4 || tempPosiY < 4 || tempPosiY > MAX_IMAGE_HEIGHT - 4)
						continue;

					for (int y = tempPosiY - 1; y <= tempPosiY + 1; y++)
					{
						for (int x = tempPosiX - 1; x <= tempPosiX + 1; x++)
						{
							if (*(colorSourceImage + (ImageWidth*(y)+x) * 3 + rgb) > meanGrayForInnerEdgeLine[n] * 2 / 3)
								*(tempData + ImageWidth * (y)+x) = 1;
						}
					}
				}
			}
		}
	}
	resultCenterX = 0;
	resultCenterY = 0;
	cnt = 0;

	//tempData를 확장..  = expansionTempData
	if (TabletCharacter.shape == OVAL || TabletCharacter.shape == OBLONG)
	{
		for (int i = startY; i < endY; i++)
		{
			for (int j = startX; j < endX; j++)
			{
				if (*(tempData + ImageWidth * i + j))
				{
					*(expansionTempData + ImageWidth * (i - 1) + j - 1) = 1;
					*(expansionTempData + ImageWidth * (i - 1) + j) = 1;
					*(expansionTempData + ImageWidth * (i - 1) + j + 1) = 1;
					*(expansionTempData + ImageWidth * (i)+j - 1) = 1;
					*(expansionTempData + ImageWidth * (i)+j) = 1;
					*(expansionTempData + ImageWidth * (i)+j + 1) = 1;
					*(expansionTempData + ImageWidth * (i + 1) + j - 1) = 1;
					*(expansionTempData + ImageWidth * (i + 1) + j) = 1;
					*(expansionTempData + ImageWidth * (i + 1) + j + 1) = 1;
					resultCenterX += j;
					resultCenterY += i;
					cnt++;
				}
			}
		}
	}
	else
	{
		for (int i = startY; i < endY; i++)
		{
			for (int j = startX; j < endX; j++)
			{
				if (*(tempData + ImageWidth * i + j))
				{
					*(expansionTempData + ImageWidth * (i)+j) = 1;
					resultCenterX += j;
					resultCenterY += i;
					cnt++;
				}
			}
		}
	}

	// 이미지 확장에 의해 CenterX,Y를 다시 계산
	if (cnt)
	{
		resultCenterX /= cnt;
		resultCenterY /= cnt;
	}

	if (TabletCharacter.shape == OVAL || TabletCharacter.shape == OBLONG)
	{
		angle = Calculation_ShapeRotationAngle(expansionTempData, resultCenterX, resultCenterY, startX, endX, startY, endY, CASE1);
	}
	else if (TabletCharacter.shape == TRIANGLE)
	{
		angle = Calculation_ShapeRotationAngle(expansionTempData, resultCenterX, resultCenterY, startX, endX, startY, endY, CASE2);
	}
	else if (TabletCharacter.shape == SQUARE)
	{
		angle = Calculation_ShapeRotationAngle(expansionTempData, resultCenterX, resultCenterY, startX, endX, startY, endY, CASE2);
	}
	else if (TabletCharacter.shape == HEXA)
	{
		angle = Calculation_ShapeRotationAngle(expansionTempData, resultCenterX, resultCenterY, startX, endX, startY, endY, CASE2);
	}
	else if (TabletCharacter.shape == ETC)
	{
		angle = Calculation_ShapeRotationAngle(expansionTempData, resultCenterX, resultCenterY, startX, endX, startY, endY, CASE3);
	}

	// 최종 회전각을 이용하여 expansionTempData의 자세보정을 시도한다. 보정된 데이터는 binarizationData에 할당된다.
  Image2->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
  Image2->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
  Image2->Picture->Bitmap->PixelFormat = pf24bit;
	Image2->Canvas->Brush->Style = bsSolid;
	Image2->Canvas->Brush->Color = clWhite;
  Image2->Canvas->Pen->Color = clBlue;
	Image2->Canvas->Rectangle(0, 0, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
	if (TabletCharacter.shape == OVAL || TabletCharacter.shape == OBLONG || TabletCharacter.shape == TRIANGLE || TabletCharacter.shape == SQUARE || TabletCharacter.shape == HEXA)
	{
		for (int i = startY; i < endY; i++)
		{
			for (int j = startX; j < endX; j++)
			{
				if (*(expansionTempData + ImageWidth * i + j))
				{
					tempX = (int)((float)(j - resultCenterX)*cos(-angle * PI / 180.0) - (float)(i - resultCenterY)*sin(-angle * PI / 180.0)) + resultCenterX;
					tempY = (int)((float)(j - resultCenterX)*sin(-angle * PI / 180.0) + (float)(i - resultCenterY)*cos(-angle * PI / 180.0)) + resultCenterY;

					if (tempX > 10 && tempX < 640 - 10 && tempY > 10 && tempY < 480 - 10)
					{
						*(binarizationData + ImageWidth * tempY + tempX) = 1;
						*(binarizationData + ImageWidth * tempY + tempX - 1) = 1;
					}
				}
			}
		}
	}
	else if (TabletCharacter.shape == ETC)
	{
		if (TabletCharacter.symmetric_line_count != ASYMMETRY_TABLET)
		{
			for (int i = startY; i < endY; i++)
			{
				for (int j = startX; j < endX; j++)
				{
					if (*(expansionTempData + ImageWidth * i + j))
					{
						tempX = (int)((float)(j - resultCenterX)*cos(-angle * PI / 180.0) - (float)(i - resultCenterY)*sin(-angle * PI / 180.0)) + resultCenterX;
						tempY = (int)((float)(j - resultCenterX)*sin(-angle * PI / 180.0) + (float)(i - resultCenterY)*cos(-angle * PI / 180.0)) + resultCenterY;

						if (tempX > 10 && tempX < 640 - 10 && tempY > 10 && tempY < 480 - 10)
						{
							*(binarizationData + ImageWidth * tempY + tempX) = 1;
							*(binarizationData + ImageWidth * tempY + tempX - 1) = 1;
						}
					}
				}
			}
		}
		else
		{
			if (tabletETCShape_UpSideDownSW)
			{
				int shiftX;
				int shiftCenterX;
				shiftCenterX = MAX_IMAGE_WIDTH - resultCenterX;
				shiftCenterX = shiftCenterX - resultCenterX;

				for (int i = startY; i < endY; i++)
				{
					for (int j = startX; j < endX; j++)
					{
						if (*(expansionTempData + ImageWidth * i + j))
						{
							shiftX = MAX_IMAGE_WIDTH - j;
							shiftX = shiftX - shiftCenterX;

							tempX = (int)((float)(shiftX - resultCenterX)*cos(-angle * PI / 180.0) - (float)(i - resultCenterY)*sin(-angle * PI / 180.0)) + resultCenterX;
							tempY = (int)((float)(shiftX - resultCenterX)*sin(-angle * PI / 180.0) + (float)(i - resultCenterY)*cos(-angle * PI / 180.0)) + resultCenterY;

							if (tempX > 10 && tempX < 640 - 10 && tempY > 10 && tempY < 480 - 10)
							{
								*(binarizationData + ImageWidth * tempY + tempX) = 1;
								*(binarizationData + ImageWidth * tempY + tempX - 1) = 1;
							}
						}
					}
				}
			}
			else
			{
				for (int i = startY; i < endY; i++)
				{
					for (int j = startX; j < endX; j++)
					{
						if (*(expansionTempData + ImageWidth * i + j))
						{
							tempX = (int)((float)(j - resultCenterX)*cos(-angle * PI / 180.0) - (float)(i - resultCenterY)*sin(-angle * PI / 180.0)) + resultCenterX;
							tempY = (int)((float)(j - resultCenterX)*sin(-angle * PI / 180.0) + (float)(i - resultCenterY)*cos(-angle * PI / 180.0)) + resultCenterY;

							if (tempX > 10 && tempX < 640 - 10 && tempY > 10 && tempY < 480 - 10)
							{
								*(binarizationData + ImageWidth * tempY + tempX) = 1;
								*(binarizationData + ImageWidth * tempY + tempX - 1) = 1;
							}
						}
					}
				}
			}
		}
	}
	else if (TabletCharacter.shape == ROUND)
	{
		for (int i = startY; i < endY; i++)
		{
			for (int j = startX; j < endX; j++)
			{
				if (*(expansionTempData + ImageWidth * i + j))
				{
					*(binarizationData + ImageWidth * i + j) = 1;
				}
			}
		}
	}

  if (TabletCharacter.discriminationDisplay_kind == PRINT)
  {
    int maxShiftSize = 60;
    int leftSW, rightSW, topSW, bottomSW;
    for (int i = 10; i < MAX_IMAGE_HEIGHT - 10; i++)
    {
      for (int j = 10; j < MAX_IMAGE_WIDTH - 10; j++)
      {
        tempAddress = ImageWidth * i + j;
        if (*(binarizationData + tempAddress) == 0)
        {
          leftSW = rightSW = topSW = bottomSW = 0;
        
          for(int shift = 1; shift <= maxShiftSize; shift++)
          {
            if(*(binarizationData + tempAddress - shift))
            {
              leftSW = 1;
              break;
            }
            else if(j - shift < 10)
            {
              break;
            }
          }

          for(int shift = 1; shift <= maxShiftSize; shift++)
          {
            if(*(binarizationData + tempAddress + shift))
            {
              rightSW = 1;
              break;
            }
            else if(j + shift > MAX_IMAGE_WIDTH - 10)
            {
              break;
            }
          }

          for(int shift = 1; shift <= maxShiftSize; shift++)
          {
            if(*(binarizationData + tempAddress - shift * MAX_IMAGE_WIDTH))
            {
              topSW = 1;
              break;
            }
            else if(i - shift < 10)
            {
              break;
            }
          }

          for(int shift = 1; shift <= maxShiftSize; shift++)
          {
            if(*(binarizationData + tempAddress + shift * MAX_IMAGE_WIDTH))
            {
              bottomSW = 1;
              break;
            }
            else if(i + shift > MAX_IMAGE_HEIGHT - 10)
            {
              break;
            }
          }

          if(topSW && bottomSW && leftSW && rightSW)
          {
            *(binarizationData + tempAddress) = 1;
          }
        }
      }
    }
  }

	int translationX;
	int translationY;

	// binarizationData가 구성되면 마지막으로 촬영된 이미지를 누적하여 평균모양을 구한다.
	for (int i = startY; i < endY; i++)
	{
		for (int j = startX; j < endX; j++)
		{
			if (*(binarizationData + ImageWidth * i + j))
			{
				translationX = j - (resultCenterX - ImageWidth / 2);
				translationY = i - (resultCenterY - ImageHeight / 2);

				if (translationX > 10 && translationX < 640 - 10 && translationY > 10 && translationY < 480 - 10)
				{
					(*(accumulateShapeImage + ImageWidth * translationY + translationX))++;
				}
			}
		}
	}

	//////////////////////////////Display////////////////////////
  for (int i = startY; i < endY; i++)
  {
    ptr = (Byte*) Image2->Picture->Bitmap->ScanLine[i];
    for (int j = startX; j < endX; j++)
    {
      if(binarizationData[ImageWidth * i + j] == 1)
      {
        ptr[3*j + 0] = 255;
        ptr[3*j + 1] = 0;
        ptr[3*j + 2] = 0;
      }
      else
      {
        ptr[3*j + 0] = 255;
        ptr[3*j + 1] = 255;
        ptr[3*j + 2] = 255;
      }
    }
  }
	Image2->Refresh();

	Image1->Canvas->Pen->Width = 2;
  unsigned char edgeArea[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];
  memset(edgeArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (int i = 10; i < img1->Height - 10; i++)
	{
		for (int j = 10; j < img1->Width - 10; j++)
		{
			if (*(tempData + ImageWidth * i + j))
			{
				edgeCheckSW = 0;
				if (*(tempData + ImageWidth * (i + 1) + j) == 0)  edgeCheckSW = 1;
				if (*(tempData + ImageWidth * (i - 1) + j) == 0)   edgeCheckSW = 1;
				if (*(tempData + ImageWidth * (i)+j - 1) == 0)    edgeCheckSW = 1;
				if (*(tempData + ImageWidth * (i)+j + 1) == 0)    edgeCheckSW = 1;
				if (edgeCheckSW == 1)
				{
          edgeArea[ImageWidth * i + j] = 1;
				}
			}
		}
	}

  for (int i = startY; i < endY; i++)
  {
    for (int j = startX; j < endX; j++)
    {
      if(*(edgeArea + ImageWidth * i + j) == 1)
      {
        ptr = (Byte*) Image1->Picture->Bitmap->ScanLine[i];
        ptr[3*j + 0] = 0;
        ptr[3*j + 1] = 0;
        ptr[3*j + 2] = 255;

        ptr[3*(j - 1) + 0] = 0;
        ptr[3*(j - 1) + 1] = 0;
        ptr[3*(j - 1) + 2] = 255;

        ptr[3*(j + 1) + 0] = 0;
        ptr[3*(j + 1) + 1] = 0;
        ptr[3*(j + 1) + 2] = 255;

        ptr = (Byte*) Image1->Picture->Bitmap->ScanLine[i - 1];
        ptr[3*j + 0] = 0;
        ptr[3*j + 1] = 0;
        ptr[3*j + 2] = 255;

        ptr[3*(j - 1) + 0] = 0;
        ptr[3*(j - 1) + 1] = 0;
        ptr[3*(j - 1) + 2] = 255;

        ptr[3*(j + 1) + 0] = 0;
        ptr[3*(j + 1) + 1] = 0;
        ptr[3*(j + 1) + 2] = 255;

        ptr = (Byte*) Image1->Picture->Bitmap->ScanLine[i + 1];
        ptr[3*j + 0] = 0;
        ptr[3*j + 1] = 0;
        ptr[3*j + 2] = 255;

        ptr[3*(j - 1) + 0] = 0;
        ptr[3*(j - 1) + 1] = 0;
        ptr[3*(j - 1) + 2] = 255;

        ptr[3*(j + 1) + 0] = 0;
        ptr[3*(j + 1) + 1] = 0;
        ptr[3*(j + 1) + 2] = 255;
      }
    }
  }
  
	Image1->Refresh();
	/////////////////////////////////////////////////////////////

	delete(img1);
	delete(binarizationData);
	delete(edgeNeighborData);
	delete(tempData);
	delete(expansionTempData);

}
int __fastcall TTabletCharacterExtractForm::Optimal_Threshold(int *histo, int st_gray, int end_gray, int *grayMean)
{
	int opti_threshold;
	int new_opti_threshold;
	int gl;
	int low_mean;
	int low_mean_cnt;
	int high_mean;
	int high_mean_cnt;
	int repeat_cnt;
	int tcnt;
	repeat_cnt = 0;
	tcnt = 0;
	new_opti_threshold = 0;
	for (gl = st_gray; gl < end_gray; gl++)
	{
		new_opti_threshold += histo[gl] * gl;
		tcnt += histo[gl];
	}
	if (tcnt != 0)
		new_opti_threshold /= tcnt;
	else
		new_opti_threshold = 0;
	do
	{
		low_mean = 0;
		high_mean = 0;
		low_mean_cnt = 0;
		high_mean_cnt = 0;
		opti_threshold = new_opti_threshold;
		for (gl = st_gray; gl < opti_threshold; gl++)
		{
			low_mean += histo[gl] * gl;
			low_mean_cnt += (histo[gl]);
		}
		for (gl = opti_threshold; gl < end_gray; gl++)
		{
			high_mean += histo[gl] * gl;
			high_mean_cnt += (histo[gl]);
		}
		if (low_mean_cnt != 0)
			low_mean /= low_mean_cnt;
		if (high_mean_cnt != 0)
			high_mean /= high_mean_cnt;
		new_opti_threshold = (low_mean + high_mean) / 2;
		repeat_cnt++;
	} while (abs(new_opti_threshold - opti_threshold) > 2 && repeat_cnt < 10);
	grayMean[0] = low_mean;
	grayMean[1] = high_mean;
	return(new_opti_threshold);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::IP_Thinning(byte *DstBitmap, byte *SrcBitmap, int Width, int Height)
{
	bool bChanged;
	int trans;
	byte *pImage[9];
	int count;
	byte *TempBitmap = new byte[Width * Height];
	memcpy(DstBitmap, SrcBitmap, Width * Height);
	memcpy(TempBitmap, DstBitmap, Width * Height);
	while (true)
	{
		bChanged = false;
		//loop 1
		for (int y = 1; y < Height - 1; y++)
		{
			//  0 7 6
			//  1 8 5
			//  2 3 4
			pImage[8] = DstBitmap + (y * Width + 1);
			pImage[7] = pImage[8] - Width;
			pImage[3] = pImage[8] + Width;
			pImage[0] = pImage[7] - 1;
			pImage[1] = pImage[8] - 1;
			pImage[2] = pImage[3] - 1;
			pImage[6] = pImage[7] + 1;
			pImage[5] = pImage[8] + 1;
			pImage[4] = pImage[3] + 1;
			for (int x = 1; x < Width - 1; x++)
			{
				if (*pImage[8] != 0)
				{
					count = 0;
					for (int i = 0; i < 9; i++)
					{
						if (*pImage[i] != 0) count++;
					}
					if (count > 2 && count < 8)
					{
						trans = 0;
						for (int i = 0; i < 7; i++)
						{
							if (*pImage[i] != 0 && *pImage[i + 1] == 0)
							{
								trans++;
							}
						}
						if (*pImage[7] != 0 && *pImage[0] == 0)
						{
							trans++;
						}
						if (trans == 1)
						{
							if ((*pImage[1] == 0 || *pImage[7] == 0 || *pImage[5] == 0) &&
								(*pImage[3] == 0 || *pImage[1] == 0 || *pImage[7] == 0))
							{
								TempBitmap[y * Width + x] = 0;
								bChanged = true;
							}
						}
					}
				}
				pImage[0]++;
				pImage[1]++;
				pImage[2]++;
				pImage[3]++;
				pImage[4]++;
				pImage[5]++;
				pImage[6]++;
				pImage[7]++;
				pImage[8]++;
			}
		}
		if (bChanged)
		{
			memcpy(DstBitmap, TempBitmap, Width * Height);
		}
		//loop 2
		for (int y = 1; y < Height - 1; y++)
		{
			//  0 7 6
			//  1 8 5
			//  2 3 4
			pImage[8] = DstBitmap + (y * Width + 1);
			pImage[7] = pImage[8] - Width;
			pImage[3] = pImage[8] + Width;
			pImage[0] = pImage[7] - 1;
			pImage[1] = pImage[8] - 1;
			pImage[2] = pImage[3] - 1;
			pImage[6] = pImage[7] + 1;
			pImage[5] = pImage[8] + 1;
			pImage[4] = pImage[3] + 1;
			for (int x = 1; x < Width - 1; x++)
			{
				if (*pImage[8] != 0)
				{
					count = 0;
					for (int i = 0; i < 9; i++)
					{
						if (*pImage[i] != 0) count++;
					}
					if (count > 2 && count < 8)
					{
						trans = 0;
						for (int i = 0; i < 7; i++)
						{
							if (*pImage[i] != 0 && *pImage[i + 1] == 0)
							{
								trans++;
							}
						}
						if (*pImage[7] != 0 && *pImage[0] == 0)
						{
							trans++;
						}
						if (trans == 1)
						{
							if ((*pImage[1] == 0 || *pImage[3] == 0 || *pImage[5] == 0) &&
								(*pImage[3] == 0 || *pImage[5] == 0 || *pImage[7] == 0))
							{
								TempBitmap[y * Width + x] = 0;
								bChanged = true;
							}
						}
					}
				}
				pImage[0]++;
				pImage[1]++;
				pImage[2]++;
				pImage[3]++;
				pImage[4]++;
				pImage[5]++;
				pImage[6]++;
				pImage[7]++;
				pImage[8]++;
			}
		}
		if (bChanged)
		{
			memcpy(DstBitmap, TempBitmap, Width * Height);
		}
		else
		{
			break;
		}
	}
	// 가늘게 만들기 위해 한번 더 지운다.
	for (int y = 1; y < Height - 1; y++)
	{
		//  0 7 6
		//  1 8 5
		//  2 3 4
		pImage[8] = DstBitmap + (y * Width + 1);
		pImage[7] = pImage[8] - Width;
		pImage[3] = pImage[8] + Width;
		pImage[0] = pImage[7] - 1;
		pImage[1] = pImage[8] - 1;
		pImage[2] = pImage[3] - 1;
		pImage[6] = pImage[7] + 1;
		pImage[5] = pImage[8] + 1;
		pImage[4] = pImage[3] + 1;
		for (int x = 1; x < Width - 1; x++)
		{
			if (*pImage[8] != 0)
			{
				if ((*pImage[3] != 0 && *pImage[5] != 0) ||
					(*pImage[3] != 0 && *pImage[1] != 0))
				{
					TempBitmap[y * Width + x] = 0;
				}
			}
			pImage[0]++;
			pImage[1]++;
			pImage[2]++;
			pImage[3]++;
			pImage[4]++;
			pImage[5]++;
			pImage[6]++;
			pImage[7]++;
			pImage[8]++;
		}
	}
	memcpy(DstBitmap, TempBitmap, Width * Height);
	for (int y = 1; y < Height - 1; y++)
	{
		//  0 7 6
		//  1 8 5
		//  2 3 4
		pImage[8] = DstBitmap + (y * Width + 1);
		pImage[7] = pImage[8] - Width;
		pImage[3] = pImage[8] + Width;
		pImage[0] = pImage[7] - 1;
		pImage[1] = pImage[8] - 1;
		pImage[2] = pImage[3] - 1;
		pImage[6] = pImage[7] + 1;
		pImage[5] = pImage[8] + 1;
		pImage[4] = pImage[3] + 1;
		for (int x = 1; x < Width - 1; x++)
		{
			if (*pImage[8] != 0)
			{
				if ((*pImage[7] != 0 && *pImage[5] != 0) ||
					(*pImage[7] != 0 && *pImage[1] != 0))
				{
					TempBitmap[y * Width + x] = 0;
				}
			}
			pImage[0]++;
			pImage[1]++;
			pImage[2]++;
			pImage[3]++;
			pImage[4]++;
			pImage[5]++;
			pImage[6]++;
			pImage[7]++;
			pImage[8]++;
		}
	}
	memcpy(DstBitmap, TempBitmap, Width * Height);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::DiscrimiationMarkExtractClick(TObject *Sender)
{
	Panel5->Visible = true;

	ShapExtractButton->Enabled = false;
	DiscrimiationMarkExtract->Enabled = false;
	SaveAndExitButton->Enabled = false;
  ReadHistoryButton->Enabled = false;
	ThreeDDiscriminationExtractButton->Enabled = false;
	SetThresholdBtn->Enabled = false;
  GetThreeDInfoButton->Enabled = false;

	ImageSelectActiveSW = 0;
	for (int i = 1000; i >= 370; i -= 30)
	{
		Panel5->Left = i;
		Sleep(5);
	}
	Panel5->BringToFront();
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage1Click(TObject *Sender)
{
	ImageSelectDisplay(1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage2Click(TObject *Sender)
{
	ImageSelectDisplay(2);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage3Click(TObject *Sender)
{
	ImageSelectDisplay(3);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage4Click(TObject *Sender)
{
	ImageSelectDisplay(4);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage5Click(TObject *Sender)
{
	ImageSelectDisplay(5);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage6Click(TObject *Sender)
{
	ImageSelectDisplay(6);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage7Click(TObject *Sender)
{
	ImageSelectDisplay(7);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage8Click(TObject *Sender)
{
	ImageSelectDisplay(8);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage9Click(TObject *Sender)
{
	ImageSelectDisplay(9);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage10Click(TObject *Sender)
{
	ImageSelectDisplay(10);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage11Click(TObject *Sender)
{
	ImageSelectDisplay(11);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage12Click(TObject *Sender)
{
	ImageSelectDisplay(12);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage13Click(TObject *Sender)
{
	ImageSelectDisplay(13);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage14Click(TObject *Sender)
{
	ImageSelectDisplay(14);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage15Click(TObject *Sender)
{
	ImageSelectDisplay(15);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage16Click(TObject *Sender)
{
	ImageSelectDisplay(16);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage17Click(TObject *Sender)
{
	ImageSelectDisplay(17);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage18Click(TObject *Sender)
{
	ImageSelectDisplay(18);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage19Click(TObject *Sender)
{
	ImageSelectDisplay(19);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage20Click(TObject *Sender)
{
	ImageSelectDisplay(20);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage21Click(TObject *Sender)
{
	ImageSelectDisplay(21);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage22Click(TObject *Sender)
{
	ImageSelectDisplay(22);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage23Click(TObject *Sender)
{
	ImageSelectDisplay(23);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage24Click(TObject *Sender)
{
	ImageSelectDisplay(24);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage25Click(TObject *Sender)
{
	ImageSelectDisplay(25);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage26Click(TObject *Sender)
{
	ImageSelectDisplay(26);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage27Click(TObject *Sender)
{
	ImageSelectDisplay(27);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage28Click(TObject *Sender)
{
	ImageSelectDisplay(28);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage29Click(TObject *Sender)
{
	ImageSelectDisplay(29);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CaptureImage30Click(TObject *Sender)
{
	ImageSelectDisplay(30);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ImageSelectDisplay(int imageWindowN)
{
	if (ImageSelectActiveSW)
	{
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		AnsiString str;
		if (SelectedImageN[SelectedFace])
		{
			if (TabletCharacter.discriminationDisplay_kind != PRINT && TabletCharacter.tabletColorN != TWOCOLOR)
			{
				ExtractImage(img1, SelectedImageN[SelectedFace], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1] , ProductData.SubSamplingMode, EIK_NORMAL);
			}
			else
			{
				ExtractImage(img1, SelectedImageN[SelectedFace], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			}

			if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img1);
			}

			((TTntImage *)FindComponent("CaptureImage" + IntToStr(SelectedImageN[SelectedFace])))->Picture->Bitmap->Assign(img1);
			((TTntImage *)FindComponent("CaptureImage" + IntToStr(SelectedImageN[SelectedFace])))->Stretch = true;
		}
		SelectedImageN[SelectedFace] = imageWindowN;
		SelectedWorkSW[SelectedFace] = 1;

    if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
    {
      if (TabletCharacter.discriminationDisplay_num == ONE_FACE ||
        TabletCharacter.discriminationDisplay_num == TWO_FACE_SAME)
      {
        if (SelectedWorkSW[0] == 1 && TabletCharacter.tabletColorN != TWOCOLOR)
        {
          BitBtn9->Visible = true;
        }
        else if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1 && TabletCharacter.tabletColorN == TWOCOLOR)
        {
          BitBtn9->Visible = true;
        }
      }
      else if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
      {
        if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
        {
          BitBtn9->Visible = true;
        }
      }
    }
    else
    {
      if (SelectedWorkSW[0] == 1)
      {
        BitBtn9->Visible = true;
      }
    }

		if (SelectedFace == 0)
		{
			if (TabletCharacter.discriminationDisplay_kind != PRINT && TabletCharacter.tabletColorN != TWOCOLOR)
			{
				ExtractImage(SelectedImage1, SelectedImageN[SelectedFace], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1] , ProductData.SubSamplingMode, EIK_NORMAL);
			}
			else
			{
				ExtractImage(SelectedImage1, SelectedImageN[SelectedFace], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);
			}

			if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(SelectedImage1);
			}

      if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
      {
			  Image24->Picture->Bitmap->Assign(SelectedImage1);
			  Image24->Stretch = true;
			  Image24->Refresh();
      }
      else
      {
        SplitLineSelectedImage->Picture->Bitmap->Assign(SelectedImage1);
			  SplitLineSelectedImage->Stretch = true;
			  SplitLineSelectedImage->Refresh();
      }
		}
		else
		{
			if (TabletCharacter.discriminationDisplay_kind != PRINT && TabletCharacter.tabletColorN != TWOCOLOR)
			{
				ExtractImage(SelectedImage2, SelectedImageN[SelectedFace], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1] , ProductData.SubSamplingMode ,EIK_NORMAL);
			}
			else
			{
				ExtractImage(SelectedImage2, SelectedImageN[SelectedFace], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);
			}

			if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(SelectedImage2);
			}

			Image25->Picture->Bitmap->Assign(SelectedImage2);
			Image25->Stretch = true;
			Image25->Refresh();
		}

		((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Pen->Color = clRed;
		((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Pen->Width = 30;
		((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Brush->Style = bsClear;
		((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Rectangle(1, 1, 640 - 1, 480 - 1);

    if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
    {
      if (SelectedFace == 0)
      {
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Brush->Style = bsSolid;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Brush->Color = clWhite;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Pen->Color = clBlue;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Pen->Width = 1;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Font->Size = 28;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Font->Color = clRed;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->TextOutW(CaptureImage1->Width / 2, CaptureImage1->Height / 2,"  "+TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_04+"  ");
      }
      else
      {
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Brush->Style = bsSolid;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Brush->Color = clWhite;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Pen->Color = clBlue;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Pen->Width = 1;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Font->Size = 28;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->Font->Color = clBlue;
        ((TTntImage *)FindComponent("CaptureImage" + IntToStr(imageWindowN)))->Canvas->TextOutW(CaptureImage1->Width / 2, CaptureImage1->Height / 2,"  "+TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_03+"  ");
      }
    }

		if (img1) delete(img1);
	}
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ThreeDImageSelectDisplay(int imageWindowN)
{
	if (ImageSelectActiveSW)
	{
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		Graphics::TBitmap *img2;
		img2 = new Graphics::TBitmap();
		AnsiString str;
		if (SelectDisk == DISK1)
		{
			if (SelectedImageN[SelectedFace])
			{
				ExtractImage(img1, SelectedImageN[SelectedFace], SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(img1);
				}

				ExtractImage(img2, SelectedImageN[SelectedFace], SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(img2);
				}

				img2->Width = img1->Width * 2;
				img2->Height = img1->Height;
				Byte *ptr;
				Byte *tr;
				for (int y = 0; y < img1->Height; y++)
				{
					ptr = (byte*)img1->ScanLine[y];
					tr = (byte*)img2->ScanLine[y];
					for (int x = 0; x < img1->Width * 2; x++)
					{
						tr[x] = ptr[x / 2];
					}
				}
				((TTntImage *)FindComponent("Image" + IntToStr(SelectedImageN[SelectedFace])))->Picture->Bitmap->Assign(img2);
				((TTntImage *)FindComponent("Image" + IntToStr(SelectedImageN[SelectedFace])))->Stretch = true;
			}
		}
		else if (SelectDisk == DISK2)
		{
			if (SelectedImageN[SelectedFace])
			{
				ExtractImage(img1, SelectedImageN[SelectedFace], SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(img1);
				}

				ExtractImage(img2, SelectedImageN[SelectedFace], SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(img1);
				}

				img2->Width = img1->Width * 2;
				img2->Height = img1->Height;
				Byte *ptr;
				Byte *tr;
				for (int y = 0; y < img1->Height; y++)
				{
					ptr = (byte*)img1->ScanLine[y];
					tr = (byte*)img2->ScanLine[y];
					for (int x = 0; x < img1->Width * 2; x++)
					{
						tr[x] = ptr[x / 2];
					}
				}
				((TTntImage *)FindComponent("Image" + IntToStr(SelectedImageN[SelectedFace])))->Picture->Bitmap->Assign(img2);
				((TTntImage *)FindComponent("Image" + IntToStr(SelectedImageN[SelectedFace])))->Stretch = true;
			}
		}
		SelectedImageN[SelectedFace] = imageWindowN;
		SelectedWorkSW[SelectedFace] = 1;

		if (TabletCharacter.discriminationDisplay_kind == PRINT)
		{
			if (TabletCharacter.tabletDivisionLineInfo == NONE_DIVISION_LINE)
			{
				if (TabletCharacter.discriminationDisplay_num == ONE_FACE ||
					TabletCharacter.discriminationDisplay_num == TWO_FACE_SAME)
				{
					if (SelectedWorkSW[0] == 1)
					{
						BitBtn6->Visible = true;
					}
				}
				else if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
				{
					if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
					{
						BitBtn6->Visible = true;
					}
				}
			}
			else
			{
				if (TabletCharacter.tabletDivisionLineInfo == ONESIDE_DIVISION_LINE)
				{
					if (SelectedWorkSW[0] == 1)
					{
						BitBtn6->Visible = true;
					}
				}
				else
				{
					if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
					{
						BitBtn6->Visible = true;
					}
				}
			}
		}
		else
		{
			if (TabletCharacter.discriminationDisplay_num == ONE_FACE ||
				TabletCharacter.discriminationDisplay_num == TWO_FACE_SAME)
			{
				if (SelectedWorkSW[0] == 1)
				{
					BitBtn6->Visible = true;
				}
			}
			else if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
			{
				if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
				{
					BitBtn6->Visible = true;
				}
			}
		}

		if (SelectDisk == DISK1)
		{
			if (SelectedFace == 0)
			{
				Image21->Visible = true;
				ExtractImage(SelectedImage1, SelectedImageN[SelectedFace], SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(SelectedImage1);
				}

				Image21->Picture->Bitmap->Assign(SelectedImage1);
				Image21->Stretch = true;
				Image21->Refresh();
			}
			else
			{
				Image22->Visible = true;
				ExtractImage(SelectedImage2, SelectedImageN[SelectedFace], SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(SelectedImage2);
				}

				Image22->Picture->Bitmap->Assign(SelectedImage2);
				Image22->Stretch = true;
				Image22->Refresh();
			}
		}
		else if (SelectDisk == DISK2)
		{
			if (SelectedFace == 0)
			{
				Image21->Visible = true;
				ExtractImage(SelectedImage1, SelectedImageN[SelectedFace], SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(SelectedImage1);
				}

				Image21->Picture->Bitmap->Assign(SelectedImage1);
				Image21->Stretch = true;
				Image21->Refresh();
			}
			else
			{
				Image22->Visible = true;
				ExtractImage(SelectedImage2, SelectedImageN[SelectedFace], SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

				if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(SelectedImage2);
				}

				Image22->Picture->Bitmap->Assign(SelectedImage2);
				Image22->Stretch = true;
				Image22->Refresh();
			}
		}

		((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Pen->Color = clRed;
		((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Pen->Width = 30;
		((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Brush->Style = bsClear;
		((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Rectangle(1, 1, 640 - 1, 480 - 1);
		if (SelectedFace == 0)
		{
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Brush->Style = bsSolid;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Brush->Color = clWhite;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Pen->Color = clBlue;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Pen->Width = 1;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Font->Size = 28;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Font->Color = clRed;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->TextOutW(Image32->Width / 2, Image32->Height / 2,"  "+TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_04+"  ");// "  First Imprint  "
		}
		else
		{
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Brush->Style = bsSolid;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Brush->Color = clWhite;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Pen->Color = clBlue;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Pen->Width = 1;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Font->Size = 28;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->Font->Color = clBlue;
			((TTntImage *)FindComponent("Image" + IntToStr(imageWindowN)))->Canvas->TextOutW(Image32->Width / 2, Image32->Height / 2,"  "+TABLETCHARACTEREXTRACTFORM_BUTTON_CAPTION_03+"  ");
		}
		if (img1) delete(img1);
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn1Click(TObject *Sender)
{
  PrintEditSW = 0;

	int tx, ty;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth * 2;
	img1->Height = ImageHeight * 2;
	img1->PixelFormat = pf24bit;

	Byte *ptr, *tr1, *tr2;
	memset(PrintBinarizationData, 0, ImageWidth*ImageHeight);
	memset(PrintBinarizationDataForThickModify, 0, ImageWidth*ImageHeight);
  memset(PrintEditResult, 0, ImageWidth*ImageHeight);

	if (SelectedFace == 0)
	{
		for (int m = 0; m < TabletSetupData.printData1Count; m++)
		{
			tx = TabletSetupData.position_printData1[m][0];
			ty = TabletSetupData.position_printData1[m][1];
			PrintBinarizationData[ty*ImageWidth + tx] = 1;
			PrintBinarizationDataForThickModify[ty*ImageWidth + tx] = 1;
		}
	}
	else if (SelectedFace == 1)
	{
		for (int m = 0; m < TabletSetupData.printData2Count; m++)
		{
			tx = TabletSetupData.position_printData2[m][0];
			ty = TabletSetupData.position_printData2[m][1];
			PrintBinarizationData[ty*ImageWidth + tx] = 1;
			PrintBinarizationDataForThickModify[ty*ImageWidth + tx] = 1;
		}
	}
	for (int y = 0; y < ImageHeight * 2; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth * 2; x++)
		{
			ptr[3 * x] = 0;
			ptr[3 * x + 1] = 0;
			ptr[3 * x + 2] = 0;
		}
	}
	for (int y = 0; y < ImageHeight * 2; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth * 2; x++)
		{
			if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)])
			{
				ptr[3 * x + 1] = 255;
				ptr[3 * x + 2] = 255;
			}
		}
	}
	Image3->Picture->Bitmap->Assign(img1);
	Image3->Refresh();
	delete(img1);

  memcpy(PrintEditResult, PrintBinarizationData, ImageWidth*ImageHeight);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Modify_ETC_PrintInformation_Save(void)
{
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn2Click(TObject *Sender)
{
  if(PrintEditSW)
  {
    memcpy(PrintBinarizationData, PrintEditResult, ImageWidth*ImageHeight);
    memcpy(PrintBinarizationDataForThickModify, PrintBinarizationData, ImageWidth*ImageHeight);

    if (SelectedFace == 0)
    {
      if (AdjustWorkingKind1 == PRINT_ADJUST)
      {
        PrintInformationCalculation(PRINT_MODIFY);
      }
      else if (AdjustWorkingKind1 == ETC_ADJUST)
      {
        Modify_ETC_PrintInformation_Save();
      }
    }
    else if (SelectedFace == 1)
    {
      if (AdjustWorkingKind2 == PRINT_ADJUST)
      {
        PrintInformationCalculation(PRINT_MODIFY);
      }
      else if (AdjustWorkingKind2 == ETC_ADJUST)
      {
        Modify_ETC_PrintInformation_Save();
      }
    }
  }

  LoadExtractedPrintLabelData();
  
	GroupBox4->Visible = false;
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;
	GroupBox21->Visible = true;
	Panel5->Visible = true;
}
//---------------------------------------------------------------------------
bool __fastcall TTabletCharacterExtractForm::PrintInformationCalculation(int mode)
{
	unsigned char expansionData[640 * 480];
	int Pixel_N_Of_Label[MAX_LABEL_COUNT];
	int rX, rY;
	int tx, ty;
	int i, j;
	int n, m, k;
	short label_Image[640 * 480];
	int printCenterX, printCenterY;
	int tempCount;
	int labelN;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;
	memset(expansionData, 0, 640 * 480);

  memset(TabletSetupData.SimilarPrint1MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  memset(TabletSetupData.SimilarPrint2MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  TabletSetupData.ApplySimilarPrintMatchingAlgorithm = 0;

  unsigned char *PrintSrcData;
  TTntImage *dstImage;

  if(mode == PRINT_NEW)
  {
    PrintSrcData = PrintBinarizationData;

    if (SelectedFace == 0)
    {
      dstImage = Image26;
    }
    else
    {
      dstImage = Image27;
    }
  }
  else
  {
    PrintSrcData = PrintBinarizationDataForThickModify;

    if (SelectedFace == 0)
    {
      dstImage = Image30;
    }
    else
    {
      dstImage = Image31;
    }
  }

	if (SelectedFace == 0)
	{
		TabletSetupData.printData1Count = 0;
		TabletSetupData.expansion_printData1Count = 0;
    print1ExtractUnusalSW = 0;
  }
  else
  {
    TabletSetupData.printData2Count = 0;
		TabletSetupData.expansion_printData2Count = 0;
    print2ExtractUnusalSW = 0;
  }

  labelN = PrintLabeling(PrintSrcData, label_Image, Pixel_N_Of_Label);

  if (TabletCharacter.discriminationDisplay_kind == PRINT)
  {
    printCenterX = 0;
    printCenterY = 0;
    tempCount = 0;
    for (int y = 10; y < ImageHeight - 10; y++)
    {
      for (int x = 10; x < ImageWidth - 10; x++)
      {
        if (PrintSrcData[y*ImageWidth + x])
        {
          printCenterX += x;
          printCenterY += y;
          tempCount++;
        }
      }
    }
    if (tempCount)
    {
      printCenterX /= tempCount;
      printCenterY /= tempCount;
    }
    else
    {
      if(mode == PRINT_NEW)
      {
        printCenterX = AdjustCenterXInImage;
        printCenterY = AdjustCenterYInImage;
      }
      else
      {
        printCenterX = ImageWidth / 2;
        printCenterY = ImageHeight / 2;
      }
    }
  }
  else
  {
    if(mode == PRINT_NEW)
    {
      printCenterX = AdjustCenterXInImage;
      printCenterY = AdjustCenterYInImage;
    }
    else
    {
      printCenterX = ImageWidth / 2;
      printCenterY = ImageHeight / 2;
    }
  }

  for (int y = 10; y < ImageHeight - 10; y++)
  {
    for (int x = 10; x < ImageWidth - 10; x++)
    {
      if (PrintSrcData[y*ImageWidth + x])
      {
        if(mode == PRINT_NEW)
        {
          // 인쇄 추출 이미지에 대해 회전 상태를 확인하여 수평이 적용된 print data 적용
          if (SelectedFace == 0)
          {
            rX = cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) - sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterX;
            rY = sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) + cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterY;

            TabletSetupData.position_printData1[TabletSetupData.printData1Count][0] = rX - (printCenterX - ImageWidth / 2);
            TabletSetupData.position_printData1[TabletSetupData.printData1Count][1] = rY - (printCenterY - ImageHeight / 2);
            expansionData[TabletSetupData.position_printData1[TabletSetupData.printData1Count][1] * ImageWidth + TabletSetupData.position_printData1[TabletSetupData.printData1Count][0]] = 1;
            TabletSetupData.printData1Count++;
          }
          else
          {
            rX = cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) - sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterX;
            rY = sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) + cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterY;

            TabletSetupData.position_printData2[TabletSetupData.printData2Count][0] = rX - (printCenterX - ImageWidth / 2);
            TabletSetupData.position_printData2[TabletSetupData.printData2Count][1] = rY - (printCenterY - ImageHeight / 2);
            expansionData[TabletSetupData.position_printData2[TabletSetupData.printData2Count][1] * ImageWidth + TabletSetupData.position_printData2[TabletSetupData.printData2Count][0]] = 1;
            TabletSetupData.printData2Count++;
          }
        }
        else
        {
          // 수정모드의 경우 이미 회전이 적용된 결과이므로 진행할 필요 없음
          if (SelectedFace == 0)
          {
            TabletSetupData.position_printData1[TabletSetupData.printData1Count][0] = x - (printCenterX - ImageWidth / 2);
            TabletSetupData.position_printData1[TabletSetupData.printData1Count][1] = y - (printCenterY - ImageHeight / 2);
            expansionData[TabletSetupData.position_printData1[TabletSetupData.printData1Count][1] * ImageWidth + TabletSetupData.position_printData1[TabletSetupData.printData1Count][0]] = 1;
            TabletSetupData.printData1Count++;
          }
          else
          {
            TabletSetupData.position_printData2[TabletSetupData.printData2Count][0] = x - (printCenterX - ImageWidth / 2);
            TabletSetupData.position_printData2[TabletSetupData.printData2Count][1] = y - (printCenterY - ImageHeight / 2);
            expansionData[TabletSetupData.position_printData2[TabletSetupData.printData2Count][1] * ImageWidth + TabletSetupData.position_printData2[TabletSetupData.printData2Count][0]] = 1;
            TabletSetupData.printData2Count++;
          }
        }
      }
    }
  }

  int tempLabelN;
  tempLabelN = 0;
  for (int n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
  {
    TabletSetupData.printLabelDataCnt[SelectedFace][n] = 0;
  }
  
  for (int n = 0; n < labelN; n++)
  {
    if (Pixel_N_Of_Label[n + 1] > 7)
    {
      for (int y = 10; y < ImageHeight - 10; y++)
      {
        for (int x = 10; x < ImageWidth - 10; x++)
        {
          if (label_Image[y*ImageWidth + x] == n + 1)
          {
            if (TabletSetupData.printLabelDataCnt[SelectedFace][tempLabelN] < PRINT_LABEL_DATA_SIZE)
            {
              if(mode == PRINT_NEW)
              {
                rX = cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) - sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterX;
								rY = sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) + cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterY;

								TabletSetupData.printLabelData[SelectedFace][tempLabelN][TabletSetupData.printLabelDataCnt[SelectedFace][tempLabelN]][0] = rX - (printCenterX - ImageWidth / 2);
								TabletSetupData.printLabelData[SelectedFace][tempLabelN][TabletSetupData.printLabelDataCnt[SelectedFace][tempLabelN]][1] = rY - (printCenterY - ImageHeight / 2);
								TabletSetupData.printLabelDataCnt[SelectedFace][tempLabelN]++;
              }
              else
              {
                TabletSetupData.printLabelData[SelectedFace][tempLabelN][TabletSetupData.printLabelDataCnt[SelectedFace][tempLabelN]][0] = x - (printCenterX - ImageWidth / 2);
                TabletSetupData.printLabelData[SelectedFace][tempLabelN][TabletSetupData.printLabelDataCnt[SelectedFace][tempLabelN]][1] = y - (printCenterY - ImageHeight / 2);
                TabletSetupData.printLabelDataCnt[SelectedFace][tempLabelN]++;
              }
            }
            else
            {
              if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
              {
                tempLabelN++;
              }
              else
              {
                ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);

                if (SelectedFace == 0)
                {
                  print1ExtractUnusalSW = 1;
                }
                else
                {
                  print2ExtractUnusalSW = 1;
                }
                return(0);
              }
            }
          }
        }
      }
      if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
      {
        tempLabelN++;
      }
      else
      {
        ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);

        if (SelectedFace == 0)
        {
          print1ExtractUnusalSW = 1;
        }
        else
        {
          print2ExtractUnusalSW = 1;
        }
        return(0);
      }
    }
  }

  TabletSetupData.printLabelCount[SelectedFace] = tempLabelN;

  // 라벨별 인쇄의 유사도 확인
  int overlapLabelCount[THREED_PRINT_MAX_LABEL_COUNT];
  int maxLabelShiftSize = 14;
  int existSimilarLabel;
  int similarRate;
  int conversionLabelN;
  int x, y;
  int PrintLabelCount[THREED_PRINT_MAX_LABEL_COUNT];
  int tempX, tempY;
  int tempAddress;
  int labelCount;
  int maxSimilarRate;
  int srcGroup, dstGroup;
  
  memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  for(n = 0; n < TabletSetupData.printLabelCount[SelectedFace]; n++)
  {
    for(m = 0; m < TabletSetupData.printLabelDataCnt[SelectedFace][n]; m++)
    {
      tempX = TabletSetupData.printLabelData[SelectedFace][n][m][0];
      tempY = TabletSetupData.printLabelData[SelectedFace][n][m][1];

      TempImage[MAX_IMAGE_WIDTH * tempY + tempX] = 1;
    }
  }
  
  labelN = PrintLabeling(TempImage, label_Image, Pixel_N_Of_Label);

retry:
  memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  for(n = 0; n < TabletSetupData.printLabelCount[SelectedFace]; n++)
  {
    for(m = 0; m < TabletSetupData.printLabelDataCnt[SelectedFace][n]; m++)
    {
      tempX = TabletSetupData.printLabelData[SelectedFace][n][m][0];
      tempY = TabletSetupData.printLabelData[SelectedFace][n][m][1];

      TempImage[MAX_IMAGE_WIDTH * tempY + tempX] = n + 1;
    }
  }

  existSimilarLabel = 0;
  for(n = 0; n < TabletSetupData.printLabelCount[SelectedFace]; n++)
  {
    maxSimilarRate = 0;
    existSimilarLabel = 0;
    for(y = - maxLabelShiftSize; y <= maxLabelShiftSize; y++)
    {
      for(x = - maxLabelShiftSize; x <= maxLabelShiftSize; x++)
      {
        memset(overlapLabelCount, 0, sizeof(int) * THREED_PRINT_MAX_LABEL_COUNT);
        tempCount = TabletSetupData.printLabelDataCnt[SelectedFace][n];
        for(m = 0; m < TabletSetupData.printLabelDataCnt[SelectedFace][n]; m++)
        {
          tempX = TabletSetupData.printLabelData[SelectedFace][n][m][0];
          tempY = TabletSetupData.printLabelData[SelectedFace][n][m][1];
          tempAddress = MAX_IMAGE_WIDTH * tempY + tempX;
          srcGroup = label_Image[tempAddress];

          tempX = TabletSetupData.printLabelData[SelectedFace][n][m][0] + x;
          tempY = TabletSetupData.printLabelData[SelectedFace][n][m][1] + y;

          if(tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
          {
            tempAddress = MAX_IMAGE_WIDTH * tempY + tempX;

            dstGroup = label_Image[tempAddress];

            if(TempImage[tempAddress] && srcGroup && dstGroup)
            {
              if(srcGroup != dstGroup)
              {
                if(TempImage[tempAddress] != (n + 1))
                {
                  overlapLabelCount[TempImage[tempAddress] - 1]++;
                }
                else
                {
                  tempCount--;
                }
              }
            }
          }
        }

        for(k = 0; k < THREED_PRINT_MAX_LABEL_COUNT; k++)
        {
          if(overlapLabelCount[k] && tempCount)
          {
            similarRate = overlapLabelCount[k] * 100 / tempCount;

            if(maxSimilarRate < similarRate)
            {
              maxSimilarRate = similarRate;
              conversionLabelN = k;
            }
          }
        }
      }
    }

    if(maxSimilarRate > MAX_SIMILAR_LABEL_PER)
    {
      if(TabletSetupData.printLabelDataCnt[SelectedFace][conversionLabelN] + TabletSetupData.printLabelDataCnt[SelectedFace][n] < PRINT_LABEL_DATA_SIZE)
      {
        existSimilarLabel = 1;

        for(m = 0; m < TabletSetupData.printLabelDataCnt[SelectedFace][n]; m++)
        {
          tempX = TabletSetupData.printLabelData[SelectedFace][n][m][0];
          tempY = TabletSetupData.printLabelData[SelectedFace][n][m][1];

          TempImage[MAX_IMAGE_WIDTH * tempY + tempX] = conversionLabelN + 1;
        }

        break;
      }
    }
  }

  if(existSimilarLabel)
  {
    memset(PrintLabelCount, 0, sizeof(int) * THREED_PRINT_MAX_LABEL_COUNT);

    for (y = 0; y < ImageHeight; y++)
    {
      for (x = 0; x < ImageWidth; x++)
      {
        tempAddress = ImageWidth * y + x;

        if(TempImage[tempAddress])
        {
          PrintLabelCount[TempImage[tempAddress] - 1]++;
        }
      }
    }

    for (n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
    {
      TabletSetupData.printLabelDataCnt[SelectedFace][n] = 0;
    }

    labelCount = 0;
    for(m = 0; m < THREED_PRINT_MAX_LABEL_COUNT; m++)
    {
      if(PrintLabelCount[m])
      {
        for (y = 0; y < ImageHeight; y++)
        {
          for (x = 0; x < ImageWidth; x++)
          {
            tempAddress = ImageWidth * y + x;

            if(TempImage[tempAddress] == m + 1)
            {
              if(TabletSetupData.printLabelDataCnt[SelectedFace][labelCount] < PRINT_LABEL_DATA_SIZE)
              {
                TabletSetupData.printLabelData[SelectedFace][labelCount][TabletSetupData.printLabelDataCnt[SelectedFace][labelCount]][0] = x;
                TabletSetupData.printLabelData[SelectedFace][labelCount][TabletSetupData.printLabelDataCnt[SelectedFace][labelCount]][1] = y;
                TabletSetupData.printLabelDataCnt[SelectedFace][labelCount]++;
              }
            }
          }
        }

        labelCount++;
      }
    }

    TabletSetupData.printLabelCount[SelectedFace] = labelCount;

    goto retry;
  }
  // end 라벨별 인쇄의 유사도 확인

  for (int y = 10; y < ImageHeight - 10; y++)
  {
    for (int x = 10; x < ImageWidth - 10; x++)
    {
      if (expansionData[y*ImageWidth + x] == 1)
      {
        for (i = y - 7; i <= y + 7; i++)
        {
          for (j = x - 7; j <= x + 7; j++)
          {
            if (expansionData[i*ImageWidth + j] == 0)
            {
              expansionData[i*ImageWidth + j] = 2;
            }
          }
        }
      }
    }
  }

  for (int y = 10; y < ImageHeight - 10; y++)
  {
    for (int x = 10; x < ImageWidth - 10; x++)
    {
      if (expansionData[y*ImageWidth + x] == 2)
      {
        if (SelectedFace == 0)
        {
          TabletSetupData.expansion_position_printData1[TabletSetupData.expansion_printData1Count][0] = x;
          TabletSetupData.expansion_position_printData1[TabletSetupData.expansion_printData1Count][1] = y;
          TabletSetupData.expansion_printData1Count++;
        }
        else
        {
          TabletSetupData.expansion_position_printData2[TabletSetupData.expansion_printData2Count][0] = x;
					TabletSetupData.expansion_position_printData2[TabletSetupData.expansion_printData2Count][1] = y;
					TabletSetupData.expansion_printData2Count++;
        }
      }
    }
  }

  if(mode == PRINT_NEW)
  {
    if (SelectedFace == 0)
    {
      // 신규인경우에만 TabletSetupData.OpenCloseSearchArea 초기화. 단, 2번 인쇄(각인)을 진행할때는 초기화하지 않음
      memset(TabletSetupData.OpenCloseSearchArea, 0, 640 * 480);
    }
  }

  if (SelectedFace == 0)
  {
    if (TabletCharacter.shape == OVAL || TabletCharacter.shape == OBLONG)
    {
      for (m = 0; m < TabletSetupData.printData1Count; m++)
      {
        tx = TabletSetupData.position_printData1[m][0];
        ty = TabletSetupData.position_printData1[m][1];
        rX = cos(PI)*(float)(tx - 320) - sin(PI)*(float)(ty - 240) + 320;
        rY = sin(PI)*(float)(tx - 320) + cos(PI)*(float)(ty - 240) + 240;
        for (int y = ty - 20; y <= ty + 20; y++)
        {
          for (int x = tx - 20; x <= tx + 20; x++)
          {
            TabletSetupData.OpenCloseSearchArea[y * 640 + x] = 1;
          }
        }
        for (int y = rY - 20; y <= rY + 20; y++)
        {
          for (int x = rX - 20; x <= rX + 20; x++)
          {
            TabletSetupData.OpenCloseSearchArea[y * 640 + x] = 1;
          }
        }
      }
    }
    else if (TabletCharacter.shape == ROUND)
    {
      for (m = 0; m < TabletSetupData.printData1Count; m++)
      {
        tx = TabletSetupData.position_printData1[m][0];
        ty = TabletSetupData.position_printData1[m][1];
        for (int r = 0; r < 360; r += 2)
        {
          rX = cos(r*PI / 180.0)*(float)(tx - 320) - sin(r*PI / 180.0)*(float)(ty - 240) + 320;
          rY = sin(r*PI / 180.0)*(float)(tx - 320) + cos(r*PI / 180.0)*(float)(ty - 240) + 240;
          for (int y = rY - 10; y <= rY + 10; y++)
          {
            for (int x = rX - 10; x < rX + 10; x++)
            {
              TabletSetupData.OpenCloseSearchArea[y * 640 + x] = 1;
            }
          }
        }
      }
    }

    for (int m = 0; m < TabletSetupData.printData1Count; m++)
    {
      tx = TabletSetupData.position_printData1[m][0];
      ty = TabletSetupData.position_printData1[m][1];
      ptr = (byte*)img1->ScanLine[ty];
      ptr[3 * tx] = 0;
      ptr[3 * tx + 1] = 0;
      ptr[3 * tx + 2] = 0;
    }
  }
  else
  {
    if (TabletCharacter.shape == OVAL || TabletCharacter.shape == OBLONG)
		{
			for (m = 0; m < TabletSetupData.printData2Count; m++)
			{
				tx = TabletSetupData.position_printData2[m][0];
				ty = TabletSetupData.position_printData2[m][1];
				rX = cos(PI)*(float)(tx - 320) - sin(PI)*(float)(ty - 240) + 320;
				rY = sin(PI)*(float)(tx - 320) + cos(PI)*(float)(ty - 240) + 240;
				for (int y = ty - 20; y <= ty + 20; y++)
				{
					for (int x = tx - 20; x <= tx + 20; x++)
					{
						TabletSetupData.OpenCloseSearchArea[y * 640 + x] = 1;
					}
				}
				for (int y = rY - 20; y <= rY + 20; y++)
				{
					for (int x = rX - 20; x <= rX + 20; x++)
					{
						TabletSetupData.OpenCloseSearchArea[y * 640 + x] = 1;
					}
				}
			}
		}
		else if (TabletCharacter.shape == ROUND)
		{
			for (m = 0; m < TabletSetupData.printData2Count; m++)
			{
				tx = TabletSetupData.position_printData2[m][0];
				ty = TabletSetupData.position_printData2[m][1];
				for (int r = 0; r < 360; r += 2)
				{
					rX = cos(r*PI / 180.0)*(float)(tx - 320) - sin(r*PI / 180.0)*(float)(ty - 240) + 320;
					rY = sin(r*PI / 180.0)*(float)(tx - 320) + cos(r*PI / 180.0)*(float)(ty - 240) + 240;
					for (int y = rY - 10; y <= rY + 10; y++)
					{
						for (int x = rX - 10; x < rX + 10; x++)
						{
							TabletSetupData.OpenCloseSearchArea[y * 640 + x] = 1;
						}
					}
				}
			}
		}
    
    for (int m = 0; m < TabletSetupData.printData2Count; m++)
		{
			tx = TabletSetupData.position_printData2[m][0];
			ty = TabletSetupData.position_printData2[m][1];
			ptr = (byte*)img1->ScanLine[ty];
			ptr[3 * tx] = 0;
			ptr[3 * tx + 1] = 0;
			ptr[3 * tx + 2] = 0;
		}
  }

  if(mode == PRINT_NEW)
  {
    Image5->Picture->Bitmap->Assign(img1);
		Image5->Refresh();
  }

  dstImage->Picture->Bitmap->Assign(img1);
	dstImage->Stretch = true;
	dstImage->Refresh();

  delete(img1);
}
//---------------------------------------------------------------------------
int __fastcall TTabletCharacterExtractForm::PrintLabelingForThreeDImage(unsigned char *src, short *label_Image, int *Pixel_N_Of_Label)
{
	int i, m, x, y;
	int temp_address;
	int currentLabel;
	int new_count;
	short CollisionArray[MAX_LABEL_COUNT];
	int newLval;
	int temp;
	int breakSW;
	int gridWidth;
	int gridWidthBack;
	int gX, gY;
	int minValue;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = IMAGE_3D_WIDTH;
	img1->Height = IMAGE_3D_HEIGHT;
	img1->PixelFormat = pf24bit;

	Byte *ptr;

	currentLabel = 0;
	memset(label_Image, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT * 2);
	for (i = 0; i < MAX_LABEL_COUNT; i++)
	{
		CollisionArray[i] = i;
		Pixel_N_Of_Label[i] = 0;
	}
	breakSW = 0;
	for (y = 1; y < IMAGE_3D_HEIGHT - 1; y++)
	{
		for (x = 1; x < IMAGE_3D_WIDTH - 1; x++)
		{
			temp_address = IMAGE_3D_WIDTH * (y)+x;
			if (src[y*IMAGE_3D_WIDTH + x])
			{
				if (*(label_Image + temp_address - IMAGE_3D_WIDTH) == 0)     // up is background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is also background
					{
						currentLabel++;
						*(label_Image + temp_address) = currentLabel; // first label number is '1'
					}
					else                        // left is not background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - 1);
					}
				}
				else                // up is not background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - IMAGE_3D_WIDTH);
					}
					else                        // left is not background
					{
						if (*(label_Image + temp_address - IMAGE_3D_WIDTH) == *(label_Image + temp_address - 1))
						{
							*(label_Image + temp_address) = *(label_Image + temp_address - IMAGE_3D_WIDTH);
						}
						else        // collision detected
						{           // Left label이 Up label보다 항상 크다
							CollisionArray[max(*(label_Image + temp_address - 1), *(label_Image + temp_address - IMAGE_3D_WIDTH))] =
								min(*(label_Image + temp_address - 1), *(label_Image + temp_address - IMAGE_3D_WIDTH));
							*(label_Image + temp_address) = CollisionArray[*(label_Image + temp_address - IMAGE_3D_WIDTH)];
						}
					}
				}
				if (currentLabel >= MAX_LABEL_COUNT - 1)
				{
					breakSW = 1;
					break;
				}
			}
		}
		if (breakSW == 1)
			break;
	}
	newLval = 1;
	for (i = 1; i <= currentLabel; i++)
	{
		if (CollisionArray[CollisionArray[i]] > newLval)
		{
			newLval++;
			CollisionArray[i] = newLval;
		}
		else
		{
			CollisionArray[i] = CollisionArray[CollisionArray[i]];
		}
	}
	if (newLval > 500)  newLval = 499;
	new_count = newLval;

	for (y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (x = 0; x < IMAGE_3D_WIDTH; x++)
		{
			if (src[y*IMAGE_3D_WIDTH + x])
			{
				temp = *(label_Image + IMAGE_3D_WIDTH * y + x);
				*(label_Image + IMAGE_3D_WIDTH * y + x) = CollisionArray[temp];
				Pixel_N_Of_Label[CollisionArray[temp]]++;
				//                ptr[3*x] =  *(label_Image + ImageWidth*y+x)*32%256;
				//                ptr[3*x+1] =  *(label_Image + ImageWidth*y+x)*62%256;
				//                ptr[3*x+2] =  *(label_Image + ImageWidth*y+x)*152%256;
			}
		}
	}
	//    Image62->Picture->Bitmap->Assign(img1);
	//    Image62->Refresh();
	return(newLval);
}
//---------------------------------------------------------------------------
int __fastcall TTabletCharacterExtractForm::PrintLabeling(unsigned char *src, short *label_Image, int *Pixel_N_Of_Label)
{
	int i, m, x, y;
	int temp_address;
	int currentLabel;
	int new_count;
	short CollisionArray[MAX_LABEL_COUNT];
	int newLval;
	int temp;
	int breakSW;
	int gridWidth;
	int gridWidthBack;
	int gX, gY;
	int minValue;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;

	currentLabel = 0;
	memset(label_Image, 0, ImageWidth*ImageHeight * 2);
	for (i = 0; i < MAX_LABEL_COUNT; i++)
	{
		CollisionArray[i] = i;
		Pixel_N_Of_Label[i] = 0;
	}
	breakSW = 0;
	for (y = 1; y < ImageHeight - 1; y++)
	{
		for (x = 1; x < ImageWidth - 1; x++)
		{
			temp_address = ImageWidth * (y)+x;
			if (src[y*ImageWidth + x])
			{
				if (*(label_Image + temp_address - ImageWidth) == 0)     // up is background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is also background
					{
						currentLabel++;
						*(label_Image + temp_address) = currentLabel; // first label number is '1'
					}
					else                        // left is not background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - 1);
					}
				}
				else                // up is not background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - ImageWidth);
					}
					else                        // left is not background
					{
						if (*(label_Image + temp_address - ImageWidth) == *(label_Image + temp_address - 1))
						{
							*(label_Image + temp_address) = *(label_Image + temp_address - ImageWidth);
						}
						else        // collision detected
						{           // Left label이 Up label보다 항상 크다
							CollisionArray[max(*(label_Image + temp_address - 1), *(label_Image + temp_address - ImageWidth))] =
								min(*(label_Image + temp_address - 1), *(label_Image + temp_address - ImageWidth));
							*(label_Image + temp_address) = CollisionArray[*(label_Image + temp_address - ImageWidth)];
						}
					}
				}
				if (currentLabel >= MAX_LABEL_COUNT - 1)
				{
					breakSW = 1;
					break;
				}
			}
		}
		if (breakSW == 1)
			break;
	}
	newLval = 1;
	for (i = 1; i <= currentLabel; i++)
	{
		if (CollisionArray[CollisionArray[i]] > newLval)
		{
			newLval++;
			CollisionArray[i] = newLval;
		}
		else
		{
			CollisionArray[i] = CollisionArray[CollisionArray[i]];
		}
	}
	if (newLval > 500)  newLval = 499;
	new_count = newLval;

	for (y = 0; y < ImageHeight; y++)
	{
		//   ptr = (byte*) img1->ScanLine[y];
		for (x = 0; x < ImageWidth; x++)
		{
			if (src[y*ImageWidth + x])
			{
				temp = *(label_Image + ImageWidth * y + x);
				*(label_Image + ImageWidth * y + x) = CollisionArray[temp];
				Pixel_N_Of_Label[CollisionArray[temp]]++;
				//    ptr[3*x] =  *(label_Image + ImageWidth*y+x)*32%256;
				//     ptr[3*x+1] =  *(label_Image + ImageWidth*y+x)*62%256;
				//     ptr[3*x+2] =  *(label_Image + ImageWidth*y+x)*152%256;
			}
		}
	}
	//  Image7->Picture->Bitmap->Assign(img1);
	//  Image7->Refresh();
	return(newLval);
}
//-------------------------------------------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::FindSensitiveStickingArea(short *label_Image, int labelN, int option, int option2)
{
	unsigned char *tempImage_src;
	unsigned char *tempImage_expansion;
	unsigned char *tempImage_shrink;
	unsigned char *tempImage_StickingArea;
	unsigned char *tempImage;
	short *tempLabelImage;
	int limit_pixel_N;
	int expansionAcceptSW;
	int edgeCheckSW;
	int tempLabel;
	int areaN;
	int Pixel_N_Of_Label[MAX_LABEL_COUNT];
	int rX, rY;
	tempImage_src = new unsigned char[ImageWidth*ImageHeight];
	tempImage_expansion = new unsigned char[ImageWidth*ImageHeight];
	tempImage_shrink = new unsigned char[ImageWidth*ImageHeight];
	tempImage_StickingArea = new unsigned char[ImageWidth*ImageHeight];
	tempImage = new unsigned char[ImageWidth*ImageHeight];
	tempLabelImage = new short[640 * 480];
	int checkSW;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;

	limit_pixel_N = 25;
	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			ptr[3 * x] = 0;
			ptr[3 * x + 1] = 0;
			ptr[3 * x + 2] = 0;
			tempLabelImage[ImageWidth*y + x] = label_Image[ImageWidth*y + x];
		}
	}
	memset(tempImage_StickingArea, 0, ImageWidth*ImageHeight);
	for (int n = 1; n <= labelN; n++)
	{
		memset(tempImage_src, 0, ImageWidth*ImageHeight);
		memset(tempImage_expansion, 0, ImageWidth*ImageHeight);
		memset(tempImage, 0, ImageWidth*ImageHeight);
		for (int y = 10; y < ImageHeight - 10; y++)
		{
			for (int x = 10; x < ImageWidth - 10; x++)
			{
				if (tempLabelImage[y*ImageWidth + x] == n)
				{
					tempImage_src[y*ImageWidth + x] = 1;
					tempImage_expansion[y*ImageWidth + x] = 1;
					tempImage[y*ImageWidth + x] = 1;
				}
			}
		}
		for (int r = 0; r < 12; r++)
		{
			for (int y = 10; y < ImageHeight - 10; y++)
			{
				for (int x = 10; x < ImageWidth - 10; x++)
				{
					if (tempImage_expansion[y*ImageWidth + x] == 1)
					{
						for (int i = y - 1; i <= y + 1; i++)
						{
							for (int j = x - 1; j <= x + 1; j++)
							{
								tempImage[i*ImageWidth + j] = 1;
							}
						}
					}
				}
			}
			for (int y = 10; y < ImageHeight - 10; y++)
			{
				for (int x = 10; x < ImageWidth - 10; x++)
				{
					tempImage_expansion[y*ImageWidth + x] = tempImage[y*ImageWidth + x];
				}
			}
		}
		memset(tempImage_shrink, 0, ImageWidth*ImageHeight);
		memset(tempImage, 0, ImageWidth*ImageHeight);
		for (int y = 10; y < ImageHeight - 10; y++)
		{
			for (int x = 10; x < ImageWidth - 10; x++)
			{
				if (tempImage_expansion[y*ImageWidth + x])
				{
					tempImage_shrink[y*ImageWidth + x] = 1;
					tempImage[y*ImageWidth + x] = 1;
				}
			}
		}
		for (int r = 0; r < 12; r++)
		{
			for (int y = 10; y < ImageHeight - 10; y++)
			{
				for (int x = 10; x < ImageWidth - 10; x++)
				{
					if (tempImage_shrink[y*ImageWidth + x] == 1)
					{
						checkSW = 0;
						for (int i = y - 1; i <= y + 1; i++)
						{
							for (int j = x - 1; j <= x + 1; j++)
							{
								if (tempImage_shrink[i*ImageWidth + j] == 0)
								{
									checkSW = 1;
								}
							}
						}
						if (checkSW == 1)
							tempImage[y*ImageWidth + x] = 0;
					}
				}
			}
			for (int y = 10; y < ImageHeight - 10; y++)
			{
				for (int x = 10; x < ImageWidth - 10; x++)
				{
					tempImage_shrink[y*ImageWidth + x] = tempImage[y*ImageWidth + x];
				}
			}
		}
		memset(tempImage, 0, ImageWidth*ImageHeight);
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				if (tempImage_shrink[y*ImageWidth + x] - tempImage_src[y*ImageWidth + x] == 1)
				{
					tempImage_StickingArea[y*ImageWidth + x] = 1;
					tempImage[y*ImageWidth + x] = 1;
				}
			}
		}
		for (int y = 1; y < ImageHeight - 1; y++)
		{
			for (int x = 1; x < ImageWidth - 1; x++)
			{
				if (tempImage_StickingArea[y*ImageWidth + x] == 1)
				{
					checkSW = 0;
					for (int i = y - 1; i <= y + 1; i++)
					{
						for (int j = x - 1; j <= x + 1; j++)
						{
							if (tempImage_StickingArea[i*ImageWidth + j] == 0)
								checkSW = 1;
						}
					}
					if (checkSW == 1)
						tempImage[y*ImageWidth + x] = 0;
				}
			}
		}
		for (int y = 1; y < ImageHeight - 1; y++)
		{
			for (int x = 1; x < ImageWidth - 1; x++)
			{
				tempImage_StickingArea[y*ImageWidth + x] = tempImage[y*ImageWidth + x];
			}
		}
		areaN = PrintLabeling(tempImage_StickingArea, label_Image, Pixel_N_Of_Label);
		//.열린 구간만 확장한다.
		int repeatCnt = 0;
		do
		{
			for (int y = 1; y < ImageHeight - 1; y++)
			{
				for (int x = 1; x < ImageWidth - 1; x++)
				{
					tempImage[y*ImageWidth + x] = (unsigned char)label_Image[y*ImageWidth + x];
				}
			}
			for (int y = 10; y < ImageHeight - 10; y++)
			{
				for (int x = 10; x < ImageWidth - 10; x++)
				{
					if (Pixel_N_Of_Label[tempImage[y*ImageWidth + x]] > limit_pixel_N)
					{
						tempLabel = label_Image[y*ImageWidth + x];
						edgeCheckSW = 0;
						for (int i = y - 1; i <= y + 1; i++)
						{
							for (int j = x - 1; j <= x + 1; j++)
							{
								if (tempImage[i*ImageWidth + j] == 0)
									edgeCheckSW = 1;
							}
						}
						if (edgeCheckSW == 1)
						{
							expansionAcceptSW = 0;
							for (int i = y - 2; i <= y + 2; i++)
							{
								for (int j = x - 2; j <= x + 2; j++)
								{
									if (PrintBinarizationData[i*ImageWidth + j])
									{
										expansionAcceptSW = 1;
									}
								}
							}
							if (expansionAcceptSW == 0)
							{
								for (int i = y - 1; i <= y + 1; i++)
								{
									for (int j = x - 1; j <= x + 1; j++)
									{
										if (PrintBinarizationData[i*ImageWidth + j] == 0)
											label_Image[i*ImageWidth + j] = tempLabel;
									}
								}
							}
						}
					}
				}
			}
			repeatCnt++;
		} while (repeatCnt < 15);
	}

	//    Image7->Picture->Bitmap->Assign(img1);
	//    Image7->Refresh();
	delete(img1);
	delete(tempImage_src);
	delete(tempImage_expansion);
	delete(tempImage_shrink);
	delete(tempImage);
	delete(tempImage_StickingArea);
	delete(tempLabelImage);
}
void __fastcall TTabletCharacterExtractForm::FindSensitiveStickingAreaForThreeDImage(short *label_Image, int labelN, int option, int option2)
{
	/*    unsigned char *tempImage_src;
	unsigned char *tempImage_expansion;
	unsigned char *tempImage_shrink;
	unsigned char *tempImage_StickingArea;
	unsigned char *tempImage;
	short *tempLabelImage;
	int limit_pixel_N;
	int expansionAcceptSW;
	int edgeCheckSW;
	int tempLabel;
	int areaN;
	int Pixel_N_Of_Label[MAX_LABEL_COUNT];
	int rX, rY;
	tempImage_src = new unsigned char[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	tempImage_expansion = new unsigned char[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	tempImage_shrink = new unsigned char[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	tempImage_StickingArea = new unsigned char[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	tempImage = new unsigned char[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	tempLabelImage = new short[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	int checkSW;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;

	limit_pixel_N = 25;
	for(int y = 0 ; y < IMAGE_3D_HEIGHT; y++)
	{
	ptr = (byte*) img1->ScanLine[y];
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	ptr[3*x] =  0;
	ptr[3*x+1] =  0;
	ptr[3*x+2] =  0;
	tempLabelImage[IMAGE_3D_WIDTH*y + x] = label_Image[IMAGE_3D_WIDTH*y + x];
	}
	}
	memset( tempImage_StickingArea, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	for(int n= 1; n <= labelN; n++)
	{
	memset( tempImage_src, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	memset( tempImage_expansion, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	memset( tempImage, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	for(int y = 10 ; y < IMAGE_3D_HEIGHT-10; y++)
	{
	for(int x =10; x < IMAGE_3D_WIDTH-10; x++)
	{
	if(tempLabelImage[y*IMAGE_3D_WIDTH + x] == n)
	{
	tempImage_src[y*IMAGE_3D_WIDTH + x] = 1;
	tempImage_expansion[y*IMAGE_3D_WIDTH + x] = 1;
	tempImage[y*IMAGE_3D_WIDTH + x] = 1;
	}
	}
	}
	for(int r = 0 ; r < 12; r++)
	{
	for(int y = 10 ; y < IMAGE_3D_HEIGHT-10; y++)
	{
	for(int x =10; x < IMAGE_3D_WIDTH-10; x++)
	{
	if(tempImage_expansion[y*IMAGE_3D_WIDTH + x] == 1)
	{
	for(int i = y - 1 ; i <= y+ 1; i++)
	{
	for(int j = x - 1; j <= x + 1; j++)
	{
	tempImage[i*IMAGE_3D_WIDTH + j] = 1;
	}
	}
	}
	}
	}
	for(int y = 10 ; y < IMAGE_3D_HEIGHT-10; y++)
	{
	for(int x =10; x < IMAGE_3D_WIDTH-10; x++)
	{
	tempImage_expansion[y*IMAGE_3D_WIDTH + x] = tempImage[y*IMAGE_3D_WIDTH + x];
	}
	}
	}
	memset( tempImage_shrink, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	memset( tempImage, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	for(int y = 10 ; y < IMAGE_3D_HEIGHT-10; y++)
	{
	for(int x =10; x < IMAGE_3D_WIDTH-10; x++)
	{
	if(tempImage_expansion[y*IMAGE_3D_WIDTH + x])
	{
	tempImage_shrink[y*IMAGE_3D_WIDTH + x] = 1;
	tempImage[y*IMAGE_3D_WIDTH + x] = 1;
	}
	}
	}
	for(int r = 0 ; r < 12; r++)
	{
	for(int y = 10 ; y < IMAGE_3D_HEIGHT-10; y++)
	{
	for(int x =10; x < IMAGE_3D_WIDTH-10; x++)
	{
	if(tempImage_shrink[y*IMAGE_3D_WIDTH + x] == 1)
	{
	checkSW = 0;
	for(int i = y - 1 ; i <= y+ 1; i++)
	{
	for(int j = x - 1; j <= x + 1; j++)
	{
	if(tempImage_shrink[i*IMAGE_3D_WIDTH + j] == 0)
	{
	checkSW = 1;
	}
	}
	}
	if(checkSW == 1)
	tempImage[y*IMAGE_3D_WIDTH + x] = 0;
	}
	}
	}
	for(int y = 10 ; y < IMAGE_3D_HEIGHT-10; y++)
	{
	for(int x =10; x < IMAGE_3D_WIDTH-10; x++)
	{
	tempImage_shrink[y*IMAGE_3D_WIDTH + x] = tempImage[y*IMAGE_3D_WIDTH + x];
	}
	}
	}
	memset( tempImage, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	for(int y = 0 ; y < IMAGE_3D_HEIGHT; y++)
	{
	//    ptr = (byte*) img1->ScanLine[y];
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if( tempImage_shrink[y*IMAGE_3D_WIDTH + x] - tempImage_src[y*IMAGE_3D_WIDTH + x] == 1)
	{
	tempImage_StickingArea[y*IMAGE_3D_WIDTH + x] = 1;
	tempImage[y*IMAGE_3D_WIDTH + x] = 1;
	}
	}
	}
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 1 ; x < IMAGE_3D_WIDTH-1 ;x++)
	{
	if(tempImage_StickingArea[y*IMAGE_3D_WIDTH + x] ==1)
	{
	checkSW = 0;
	for(int i = y - 1; i <= y + 1; i++)
	{
	for(int j = x - 1; j <= x + 1; j++)
	{
	if(tempImage_StickingArea[i*IMAGE_3D_WIDTH + j] == 0)
	checkSW = 1;
	}
	}
	if(checkSW == 1)
	tempImage[y*IMAGE_3D_WIDTH + x] = 0;
	}
	}
	}
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 1 ; x < IMAGE_3D_WIDTH-1 ;x++)
	{
	tempImage_StickingArea[y*IMAGE_3D_WIDTH + x] = tempImage[y*IMAGE_3D_WIDTH + x];
	}
	}
	areaN = PrintLabelingForThreeDImage(tempImage_StickingArea, label_Image,Pixel_N_Of_Label);
	//.열린 구간만 확장한다.
	int repeatCnt =0;
	do
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 1 ; x < IMAGE_3D_WIDTH-1 ;x++)
	{
	tempImage[y*IMAGE_3D_WIDTH + x] = (unsigned char)label_Image[y*IMAGE_3D_WIDTH + x];
	}
	}
	for(int y = 10 ; y < IMAGE_3D_HEIGHT - 10; y++)
	{
	for(int x = 10 ; x < IMAGE_3D_WIDTH - 10 ;x++)
	{
	if(Pixel_N_Of_Label[tempImage[y*IMAGE_3D_WIDTH + x]] > limit_pixel_N)
	{
	tempLabel = label_Image[y*IMAGE_3D_WIDTH + x];
	edgeCheckSW = 0;
	for(int i = y - 1; i <= y + 1; i++)
	{
	for(int j = x - 1; j <= x + 1; j++)
	{
	if(tempImage[i*IMAGE_3D_WIDTH + j] == 0)
	edgeCheckSW = 1;
	}
	}
	if(edgeCheckSW == 1)
	{
	expansionAcceptSW = 0;
	for(int i = y - 2; i <= y + 2; i++)
	{
	for(int j = x - 2; j <= x + 2; j++)
	{
	if(PrintBinarizationDataForThreeD[i*IMAGE_3D_WIDTH + j])
	{
	expansionAcceptSW = 1;
	}
	}
	}
	if(expansionAcceptSW == 0)
	{
	for(int i = y - 1; i <= y + 1; i++)
	{
	for(int j = x - 1; j <= x + 1; j++)
	{
	if(PrintBinarizationDataForThreeD[i*IMAGE_3D_WIDTH + j] == 0)
	label_Image[i*IMAGE_3D_WIDTH + j] = tempLabel;
	}
	}
	}
	}
	}
	}
	}
	repeatCnt++;
	}
	while(repeatCnt < 15);


	if(option == CASE1)
	{
	if(option2 == MODIFY)
	{
	if(SelectDisk == DISK1)
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1] < 2000)
	{
	Tablet3DSetupData.Disk1SensitiveStickingAreaData1[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1]*2] = x ;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData1[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1]*2 + 1] = y;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1++;
	}
	}
	}
	else if(SelectDisk == DISK2)
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1] < 2000)
	{
	Tablet3DSetupData.Disk2SensitiveStickingAreaData1[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1]*2] = x ;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData1[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1]*2 + 1] = y;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1++;
	}
	}
	}
	}
	else
	{
	RotationAngleInSelectedImage = 0;  //회전할 필요가 없으므로
	if(SelectDisk == DISK1)
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1] < 2000)
	{
	rX = cos(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) - sin(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_WIDTH/2;
	rY = sin(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) + cos(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_HEIGHT/2;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData1[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1]*2] = rX ;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData1[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1]*2 + 1] = rY ;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN1++;
	}
	}
	}
	else
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1] < 2000)
	{
	rX = cos(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) - sin(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_WIDTH/2;
	rY = sin(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) + cos(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_HEIGHT/2;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData1[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1]*2] = rX ;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData1[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1][Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1]*2 + 1] = rY ;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData1Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN1++;
	}
	}
	}
	}
	}
	else if(option == CASE2)
	{
	if(option2 == MODIFY)
	{
	if(SelectDisk == DISK1)
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2] < 2000)
	{
	Tablet3DSetupData.Disk1SensitiveStickingAreaData2[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2]*2] = x;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData2[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2]*2 + 1] = y;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2++;
	}
	}
	}
	else if(SelectDisk == DISK2)
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2] < 2000)
	{
	Tablet3DSetupData.Disk2SensitiveStickingAreaData2[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2]*2] = x;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData2[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2]*2 + 1] = y;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2++;
	}
	}
	}
	}
	else
	{
	RotationAngleInSelectedImage = 0;  //회전할 필요가 없으므로
	if(SelectDisk == DISK1)
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2] < 2000)
	{
	rX = cos(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) - sin(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_WIDTH/2;
	rY = sin(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) + cos(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_HEIGHT/2;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData2[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2]*2] = rX ;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData2[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2]*2 + 1] = rY ;
	Tablet3DSetupData.Disk1SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk1SensitiveStickingAreaLabelN2++;
	}
	}
	}
	else if(SelectDisk == DISK2)
	{
	for(int m = 1; m <= areaN; m++)
	{
	if(Pixel_N_Of_Label[m] > limit_pixel_N)
	{
	for(int y = 1 ; y < IMAGE_3D_HEIGHT-1; y++)
	{
	for(int x = 0 ; x < IMAGE_3D_WIDTH ;x++)
	{
	if(label_Image[y*IMAGE_3D_WIDTH + x] == m)
	{
	if(Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2] < 2000)
	{
	rX = cos(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) - sin(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_WIDTH/2;
	rY = sin(RotationAngleInSelectedImage*PI/180.0)*(float)(x-IMAGE_3D_WIDTH/2) + cos(RotationAngleInSelectedImage*PI/180.0)*(float)(y-IMAGE_3D_HEIGHT/2) + IMAGE_3D_HEIGHT/2;
	Tablet3DSetupData.Disk2SensitiveStickingAreaData2[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2]*2] = rX - (AdjustCenterXInImage -IMAGE_3D_WIDTH/2);
	Tablet3DSetupData.Disk2SensitiveStickingAreaData2[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2][Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2]*2 + 1] = rY - (AdjustCenterYInImage - IMAGE_3D_HEIGHT/2);
	Tablet3DSetupData.Disk2SensitiveStickingAreaData2Count[Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2]++;
	}
	}
	}
	}
	Tablet3DSetupData.Disk2SensitiveStickingAreaLabelN2++;
	}
	}
	}

	}
	}
	/////////////////////////////Display//////////////////////////////////////////
	}

	//    Image62->Picture->Bitmap->Assign(img1);
	//    Image62->Refresh();
	delete(img1);
	delete(tempImage_src);
	delete(tempImage_expansion);
	delete(tempImage_shrink);
	delete(tempImage);
	delete(tempImage_StickingArea);
	delete(tempLabelImage);
	*/
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::PrintExtractWorkEndButtonClick(TObject *Sender)
{
	GroupBox6->Visible = false;   //식별마크 추출 작업
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;

  if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
  {
    GroupBox20->Visible = true;
    ExtractionSplitLineGroupBox->Visible = false;
  }
  else
  {
    GroupBox20->Visible = false;
    ExtractionSplitLineGroupBox->Visible = true;
  }

	Panel5->Visible = true;
	ZoomOptionBox->Visible = false;

	Panel18->Color = clBlack;
	Panel19->Color = clBlack;

	zoomInOutShiftX = 0;
	zoomInOutShiftY = 0;
	zoomInOutSize = 2;

  if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
  {
	  ExtractPrintColor();
  }

  if(TabletSetupData.printData1Count && TabletSetupData.printData2Count)
  {
    SimilarPrintSettingBtn->Enabled = true;
  }
  else
  {
    SimilarPrintSettingBtn->Enabled = false;
  }
}
//---------------------------------------------------------------------------
int  __fastcall TTabletCharacterExtractForm::ReadSetupData(TTabletSetupData *tabletSetupData)
{
	int existFileSize;
	AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt";
	if (FileExists(setupDataFileName))
	{
		TFileStream *fileStream = new TFileStream(setupDataFileName, fmOpenRead);
		int readDataN;
		if (fileStream)
		{
			memset(tabletSetupData, 0, sizeof(TTabletSetupData));
			existFileSize = fileStream->Size;
			readDataN = fileStream->Read(tabletSetupData, sizeof(TTabletSetupData));
			delete fileStream;

			return(existFileSize);
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}
//---------------------------------------------------------------------------
int  __fastcall TTabletCharacterExtractForm::Read3DSetupData(TTablet3DSetupData *tablet3DSetupData)
{
	AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt_3D";
	if (FileExists(setupDataFileName))
	{
		TFileStream *fileStream = new TFileStream(setupDataFileName, fmOpenRead);
		int readDataN;
		if (fileStream)
		{
			readDataN = fileStream->Read(tablet3DSetupData, sizeof(TTablet3DSetupData));
			delete fileStream;
			return(readDataN);
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::FormDestroy(TObject *Sender)
{
	if (SelectedImage)
		delete(SelectedImage);
	if (SelectedImage1)
		delete(SelectedImage1);
	if (SelectedImage2)
		delete(SelectedImage2);
	if (ThreeDSelectedImage1)
		delete(ThreeDSelectedImage1);
	if (ThreeDSelectedImage2)
		delete(ThreeDSelectedImage2);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image5MouseDown(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	//ImageDownSW = 1;

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image5MouseMove(TObject *Sender, TShiftState Shift,
	int X, int Y)
{
	/*    if(PrintMaskSW && ImageDownSW)
	{
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;
	Byte *ptr, *tr;
	for(int y = 0; y < ImageHeight; y++)
	{
	ptr = (byte*) SelectedImage->ScanLine[y];
	tr = (byte*) img1->ScanLine[y];
	for(int x = 0 ; x < ImageWidth; x++)
	{
	tr[3*x] = ptr[3*x];
	tr[3*x+1] = ptr[3*x+1];
	tr[3*x+2] = ptr[3*x+2];
	}
	}
	for(int y = Y - MaskWidth/2 ; y <= Y + MaskWidth/2; y++)
	{
	for(int x = X - MaskWidth/2 ; x <= X + MaskWidth/2; x++)
	{
	PrintMaskArea[y*ImageWidth + x] = true;
	}
	}
	for(int y = 0; y < ImageHeight; y++)
	{
	ptr = (byte*) img1->ScanLine[y];
	for(int x = 0 ; x < ImageWidth; x++)
	{
	if(PrintMaskArea[y*ImageWidth + x])
	{
	ptr[3*x] = 255;
	}
	}
	}
	Image5->Picture->Bitmap->Assign(img1);
	Image5->Refresh();
	delete(img1);
	///////////////////////////////////////////////////
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth*2;
	img1->Height = ImageHeight*2;
	img1->PixelFormat = pf24bit;
	Byte  *tr1,*tr2 ;
	for(int y = 0; y < ImageHeight; y++)
	{
	ptr = (byte*) SelectedImage->ScanLine[y];
	tr1 = (byte*) img1->ScanLine[y*2];
	tr2 = (byte*) img1->ScanLine[y*2+1];
	for(int x = 0 ; x < ImageWidth; x++)
	{
	for(int j =2*x ; j <= 2*x+1 ; j++)
	{
	tr1[3*j] = ptr[3*x];
	tr1[3*j+1] = ptr[3*x+1];
	tr1[3*j+2] = ptr[3*x+2];
	tr2[3*j] = ptr[3*x];
	tr2[3*j+1] = ptr[3*x+1];
	tr2[3*j+2] = ptr[3*x+2];
	}
	}
	}
	for(int y = 0; y < ImageHeight*2; y++)
	{
	ptr = (byte*) img1->ScanLine[y];
	for(int x = 0 ; x < ImageWidth*2; x++)
	{
	if(PrintMaskArea[(y/2)*ImageWidth + (x/2)])
	{
	ptr[3*x] = 255;
	}
	}
	}
	Image9->Visible = true;
	Image9->Picture->Bitmap->Assign(img1);
	Image9->Refresh();
	delete(img1);
	///////////////////////////////////////////////
	}
	*/
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image5MouseUp(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y)
{
	//    ImageDownSW = 0;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn3Click(TObject *Sender)
{
	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 1);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 1);
	else
		refreshZoomInTabletImage(NULL, 1);

	Image5->Picture->Bitmap->Assign(SelectedImage);
	Image5->Refresh();

	Panel17->Visible = true;
	Image9->Visible = true;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::PrintMaskingButtonClick(TObject *Sender)
{
	int zoomInOutROIWidth;
	int zoomInOutROIHeight;

	zoomInOutSize = 2;

	zoomInOutROIWidth = MAX_ZOOM_W_PIXEL / zoomInOutSize;
	zoomInOutROIHeight = MAX_ZOOM_H_PIXEL / zoomInOutSize;

	zoomROIX1 = 0;
	zoomROIY1 = 0;

	zoomROIX2 = zoomROIX1 + zoomInOutROIWidth;
	zoomROIY2 = zoomROIY1 + zoomInOutROIHeight;

	zoomInOutShiftX = 0;
	zoomInOutShiftY = 0;

	GroupBox7->Visible = true;
	PrintMaskingButton->Visible = true;
	PrintManualExtractButton->Visible = false;
	ETC_InformationExtractButton->Visible = false;
	PrintExtractWorkEndButton->Visible = false;
	PrintMaskSW = 1;

	Graphics::TBitmap *img2;
	img2 = new Graphics::TBitmap();
	img2->Width = ImageWidth * 2;
	img2->Height = ImageHeight * 2;
	img2->PixelFormat = pf24bit;
	///////////////////////////////////////////////////
	Byte *ptr, *tr1, *tr2;

	Panel17->Visible = true;
	Image9->Visible = true;

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		tr1 = (byte*)img2->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			tr1[3 * x] = ptr[3 * x];
			tr1[3 * x + 1] = ptr[3 * x + 1];
			tr1[3 * x + 2] = ptr[3 * x + 2];
		}
	}
	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img2->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			if (PrintMaskArea[(y)*ImageWidth + (x)])
			{
				ptr[3 * x] = 255;
			}
		}
	}
	Image5->Visible = true;
	Image5->Picture->Bitmap->Assign(img2);
	Image5->Refresh();
	delete(img2);

	///////////////////////////////////////////////
	Image6->Canvas->Pen->Color = clRed;
	Image6->Canvas->Brush->Style = bsSolid;
	Image6->Canvas->Brush->Color = clWhite;
	Image6->Canvas->Rectangle(0, 0, Image6->Width, Image6->Height);
	Image6->Canvas->Brush->Color = clRed;
	Image6->Canvas->Ellipse(Image6->Width / 2 - (((float)MaskWidth) / 2.0 + 0.5), Image6->Height / 2 - (((float)MaskWidth) / 2.0 + 0.5), Image6->Width / 2 + (((float)MaskWidth) / 2.0 + 0.5), Image6->Height / 2 + (((float)MaskWidth) / 2.0 + 0.5));

	ZoomOptionBox->Visible = true;

	LoadZoomInOutNavigationImage();

	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 0);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 0);
	else
		refreshZoomInTabletImage(NULL, 0);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::UpDown1Click(TObject *Sender, TUDBtnType Button)
{
	if (Button == 0)
	{
		MaskWidth++;
		Image6->Canvas->Brush->Style = bsSolid;
		Image6->Canvas->Brush->Color = clWhite;
		Image6->Canvas->Rectangle(0, 0, Image6->Width, Image6->Height);
		Image6->Canvas->Pen->Color = clRed;
		Image6->Canvas->Brush->Color = clRed;
		Image6->Canvas->Ellipse(Image6->Width / 2 - (((float)MaskWidth) / 2.0 + 0.5), Image6->Height / 2 - (((float)MaskWidth) / 2.0 + 0.5), Image6->Width / 2 + (((float)MaskWidth) / 2.0 + 0.5), Image6->Height / 2 + (((float)MaskWidth) / 2.0 + 0.5));
	}
	else
	{
		MaskWidth--;
		if (MaskWidth < 1)
			MaskWidth = 1;
		Image6->Canvas->Brush->Style = bsSolid;
		Image6->Canvas->Brush->Color = clWhite;
		Image6->Canvas->Rectangle(0, 0, Image6->Width, Image6->Height);
		Image6->Canvas->Pen->Color = clRed;
		Image6->Canvas->Brush->Color = clRed;
		Image6->Canvas->Ellipse(Image6->Width / 2 - (((float)MaskWidth) / 2.0 + 0.5), Image6->Height / 2 - (((float)MaskWidth) / 2.0 + 0.5), Image6->Width / 2 + (((float)MaskWidth) / 2.0 + 0.5), Image6->Height / 2 + (((float)MaskWidth) / 2.0 + 0.5));
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn7Click(TObject *Sender)
{
	GroupBox7->Visible = false;
	PrintMaskSW = 0;
	DiscrimiationMarkExtractF(ImageWidth, ImageHeight);
	PrintMaskingButton->Visible = true;
	PrintManualExtractButton->Visible = true;
	ETC_InformationExtractButton->Visible = false;
	PrintExtractWorkEndButton->Visible = false;

	memcpy(tempPrintBinarizationData, PrintBinarizationData, 640 * 480);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::AuctoPrintExtractButtonClick(TObject *Sender)
{

	//    delete(colorSourceImage);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ShapeMatching(int a, int b)
{
	int startX, endX, startY, endY;
	int tabletLength;
	int tabletWidth;
	int space;
	unsigned char *ColorImageData;
	unsigned char *GradientData;
	int rgb;
	int shiftSize;
	int gradientSum[SHAPE_MATCHING_RANGE * 2 + 1][SHAPE_MATCHING_RANGE * 2 + 1];  //yx;
	int gradientSum2[ACCEPTABLE_ROTATION_RANGE * 2 + 1][SHAPE_MATCHING_RANGE * 2 + 1][SHAPE_MATCHING_RANGE * 2 + 1];  //yx;
	Byte *ptr;
	Byte *tr;
	int maxG = -1;
	int gradX, gradY;
	int rotateX, rotateY;
	int tempX, tempY;
	int protoShiftX, protoShiftY;
	int tempCount;
	int tabletCenterX, tabletCenterY;
	int rotationRange;
	int rotationTempPoint[2000][2];
	int tempFrontShapeEdgePoint[2000][2];
	int CosData[720];
	int SinData[720];
	int angle;
	int tempShiftXForAngleRange[4];
	int tempShiftYForAngleRange[4];
	int tempTabletRotationAngleForAngleRange[4];
	short tempFrontShapeEdgePointForAngle[4][1000][2];
	int tempFrontShapeEdgePointCountForAngle[4];
	int matchingValue;
	int smallSizeImagWidth;
	int maxLabelN;
	int cameraIndex;
	unsigned char smallSizeBinaryImage[(640 / 4)*(480 / 4)];  //19k
	short smallSizeLabelImage[(640 / 4)*(480 / 4)];  //38k
	unsigned char  smallSizeOneColorImage[(640 / 4)*(480 / 4)];  //19k
	unsigned char  smallSizeGradientImage[(640 / 4)*(480 / 4)];  //19k
	for (int m = 0; m < 2000; m++)
	{
		tempFrontShapeEdgePoint[m][0] = 0;
		tempFrontShapeEdgePoint[m][1] = 0;
	}
	for (int m = 0; m < 4; m++)
	{
		tempFrontShapeEdgePointCountForAngle[m] = 0;
		for (int i = 0; i < 1000; i++)
		{
			tempFrontShapeEdgePointForAngle[m][i][0] = 0;
			tempFrontShapeEdgePointForAngle[m][i][1] = 0;
		}
	}
  
	for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
	{
		tempFrontShapeEdgePoint[m][0] = (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2)*TabletSetupData.cameraZoom[0] / TabletSetupData.cameraZoom[0] + ImageWidth / 2;
		tempFrontShapeEdgePoint[m][1] = (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)*TabletSetupData.cameraZoom[0] / TabletSetupData.cameraZoom[0] + ImageHeight / 2;
	}

	for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
	{
		if (TabletSetupData.FrontShapeEdgePoint[m][2] >= 0 && TabletSetupData.FrontShapeEdgePoint[m][2] < 180)
		{
			if (TabletSetupData.FrontShapeEdgePoint[m][2] % 2 == 0)
			{
				tempFrontShapeEdgePointForAngle[0][tempFrontShapeEdgePointCountForAngle[0]][0] = tempFrontShapeEdgePoint[m][0];
				tempFrontShapeEdgePointForAngle[0][tempFrontShapeEdgePointCountForAngle[0]][1] = tempFrontShapeEdgePoint[m][1];
				tempFrontShapeEdgePointCountForAngle[0]++;
			}
		}
		if (TabletSetupData.FrontShapeEdgePoint[m][2] >= 90 && TabletSetupData.FrontShapeEdgePoint[m][2] < 270)
		{
			if (TabletSetupData.FrontShapeEdgePoint[m][2] % 2 == 0)
			{
				tempFrontShapeEdgePointForAngle[1][tempFrontShapeEdgePointCountForAngle[1]][0] = tempFrontShapeEdgePoint[m][0];
				tempFrontShapeEdgePointForAngle[1][tempFrontShapeEdgePointCountForAngle[1]][1] = tempFrontShapeEdgePoint[m][1];
				tempFrontShapeEdgePointCountForAngle[1]++;
			}
		}
		if (TabletSetupData.FrontShapeEdgePoint[m][2] >= 180 && TabletSetupData.FrontShapeEdgePoint[m][2] < 360)
		{
			if (TabletSetupData.FrontShapeEdgePoint[m][2] % 2 == 0)
			{
				tempFrontShapeEdgePointForAngle[2][tempFrontShapeEdgePointCountForAngle[2]][0] = tempFrontShapeEdgePoint[m][0];
				tempFrontShapeEdgePointForAngle[2][tempFrontShapeEdgePointCountForAngle[2]][1] = tempFrontShapeEdgePoint[m][1];
				tempFrontShapeEdgePointCountForAngle[2]++;
			}
		}
		if ((TabletSetupData.FrontShapeEdgePoint[m][2] >= 270 && TabletSetupData.FrontShapeEdgePoint[m][2] < 360)
			|| (TabletSetupData.FrontShapeEdgePoint[m][2] >= 0 && TabletSetupData.FrontShapeEdgePoint[m][2] < 90))
		{
			if (TabletSetupData.FrontShapeEdgePoint[m][2] % 2 == 0)
			{
				tempFrontShapeEdgePointForAngle[3][tempFrontShapeEdgePointCountForAngle[3]][0] = tempFrontShapeEdgePoint[m][0];
				tempFrontShapeEdgePointForAngle[3][tempFrontShapeEdgePointCountForAngle[3]][1] = tempFrontShapeEdgePoint[m][1];
				tempFrontShapeEdgePointCountForAngle[3]++;
			}
		}
	}

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	ColorImageData = new byte[3 * ImageWidth*ImageHeight];
	GradientData = new byte[ImageWidth*ImageHeight];

	shiftSize = SHAPE_MATCHING_RANGE;
	rotationRange = ACCEPTABLE_ROTATION_RANGE;

	if (TabletCharacter.kind == SUGARCOATING)
	{
		TInspectionAreaRevisionForm *InspectionAreaRevisionForm = new TInspectionAreaRevisionForm(this);

		memset(&InspectionAreaRevisionForm->dstTabletSetupData, 0, sizeof(TTabletSetupData));

		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartX[0] = 10;
		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartY[0] = 10;
		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndX[0] = MAX_IMAGE_WIDTH - 10;
		InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndY[0] = MAX_IMAGE_HEIGHT - 10;

		InspectionAreaRevisionForm->mode = 0;
		InspectionAreaRevisionForm->ShowModal();

		startX = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartX[0];
		endX = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndX[0];
		startY = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutStartY[0];
		endY = InspectionAreaRevisionForm->dstTabletSetupData.ImageCutEndY[0];

		delete InspectionAreaRevisionForm;
	}
	else
	{
		startX = 10;
		endX = MAX_IMAGE_WIDTH - 10;
		startY = 10;
		endY = MAX_IMAGE_HEIGHT - 10;
	}

	if (startX < 0) startX = 0;
	if (endX > ImageWidth) endX = ImageWidth;
	if (startY < 0) startY = 0;
	if (endY > ImageHeight) endY = ImageHeight;


	rgb = 1;
	for (int m = 0; m < 720; m++)
	{
		CosData[m] = cos((float)m / 2.0*PI / 180.0) * 1024;
		SinData[m] = sin((float)m / 2.0*PI / 180.0) * 1024;
	}
	for (int y = 0; y < shiftSize * 2 + 1; y++)
	{
		for (int x = 0; x < shiftSize * 2 + 1; x++)
		{
			gradientSum[y][x] = 0;
		}
	}
	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		tr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			for (int c = 0; c < 3; c++)
			{
				ColorImageData[(y*ImageWidth + x) * 3 + c] = ptr[3 * x + c];
				tr[3 * x + c] = ptr[3 * x + c];
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////
	tabletCenterX = 0;
	tabletCenterY = 0;
	tempCount = 0;
	smallSizeImagWidth = ImageWidth / 4;
	memset(smallSizeBinaryImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeLabelImage, 0, (ImageWidth / 4)*(ImageHeight / 4) * 2);
	memset(smallSizeOneColorImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeGradientImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	for (int y = startY; y < endY; y += 4)
	{
		for (int x = startX; x < endX; x += 4)
		{
      smallSizeOneColorImage[smallSizeImagWidth*(y / 4) + x / 4] = ColorImageData[(y*ImageWidth + (x)) * 3 + rgb];
      if (*(ColorImageData + (ImageWidth*y + x) * 3 + 1) > 30
        || *(ColorImageData + (ImageWidth*y + x) * 3 + 2) - *(ColorImageData + (ImageWidth*y + x) * 3) > 15)
        smallSizeBinaryImage[smallSizeImagWidth*(y / 4) + x / 4] = 1;
		}
	}
	maxLabelN = LabellingForTabletImage(smallSizeLabelImage, smallSizeBinaryImage, startX / 4, endX / 4, startY / 4, endY / 4, ImageWidth / 4, ImageHeight / 4);
	for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
	{
		for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
		{
			if (smallSizeLabelImage[(y)*smallSizeImagWidth + (x)] == maxLabelN)
			{
				for (int i = y - 1; i <= y + 1; i++)
				{
					for (int j = x - 1; j <= x + 1; j++)
					{
						smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
					}
				}
			}
		}
	}
	int tempAddress;
	for (int y = startY; y < endY; y++)
	{
		for (int x = startX; x < endX; x++)
		{
			tempAddress = y * ImageWidth + x;
			if (smallSizeBinaryImage[(y / 4)*smallSizeImagWidth + (x / 4)] == 2)
			{
				if (*(ColorImageData + (ImageWidth*y + x) * 3 + 1) > 30
					|| *(ColorImageData + (ImageWidth*y + x) * 3 + 2) - *(ColorImageData + (ImageWidth*y + x) * 3) > 15)
				{
					tabletCenterX += x;
					tabletCenterY += y;
					tempCount++;
				}
			}
		}
	}
	if (tempCount)
	{
		tabletCenterX /= tempCount;
		tabletCenterY /= tempCount;
	}
	AdjustCenterXInImage = tabletCenterX;
	AdjustCenterYInImage = tabletCenterY;
	ProtoTabletRotationAngle = 0;
	if (TabletCharacter.shape == TRIANGLE)
	{
		for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
		{
			for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
			{
				tempAddress = y * smallSizeImagWidth + x;
				gradX = abs(smallSizeOneColorImage[tempAddress + 1] - smallSizeOneColorImage[tempAddress - 1]);
				gradY = abs(smallSizeOneColorImage[tempAddress + smallSizeImagWidth] - smallSizeOneColorImage[tempAddress - smallSizeImagWidth]);
				if (gradX > gradY)
					smallSizeGradientImage[smallSizeImagWidth*(y)+x] = gradX;
				else
					smallSizeGradientImage[smallSizeImagWidth*(y)+x] = gradY;
			}
		}
		maxG = -1;
		for (int r = 0; r <= 720 / 3; r += 4) // 삼각형 720/3
		{
			matchingValue = 0;
			for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
			{
				rotateX = ((CosData[r] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) - SinData[r] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) >> 10) + AdjustCenterXInImage;
				rotateY = ((SinData[r] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + CosData[r] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) >> 10) + AdjustCenterYInImage;
				matchingValue += (smallSizeGradientImage[(rotateY / 4)*smallSizeImagWidth + (rotateX / 4)]);
			}
			if (maxG < (matchingValue))
			{
				maxG = (matchingValue);
				ProtoTabletRotationAngle = r;
			}
		}
	}
	if (TabletCharacter.shape == SQUARE)
	{
		for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
		{
			for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
			{
				tempAddress = y * smallSizeImagWidth + x;
				gradX = abs(smallSizeOneColorImage[tempAddress + 1] - smallSizeOneColorImage[tempAddress - 1]);
				gradY = abs(smallSizeOneColorImage[tempAddress + smallSizeImagWidth] - smallSizeOneColorImage[tempAddress - smallSizeImagWidth]);
				if (gradX > gradY)
					smallSizeGradientImage[smallSizeImagWidth*(y)+x] = gradX;
				else
					smallSizeGradientImage[smallSizeImagWidth*(y)+x] = gradY;
			}
		}
		maxG = -1;
		for (int r = 0; r <= 720 / 4; r += 2) // 삼각형 720/3
		{
			matchingValue = 0;
			for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
			{
				rotateX = ((CosData[r] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) - SinData[r] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) >> 10) + AdjustCenterXInImage;
				rotateY = ((SinData[r] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + CosData[r] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) >> 10) + AdjustCenterYInImage;
				matchingValue += (smallSizeGradientImage[(rotateY / 4)*smallSizeImagWidth + (rotateX / 4)]);
			}
			if (maxG < (matchingValue))
			{
				maxG = (matchingValue);
				ProtoTabletRotationAngle = r;
			}
		}
	}
	else if (TabletCharacter.shape == ETC)
	{
		for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
		{
			for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
			{
				tempAddress = y * smallSizeImagWidth + x;
				gradX = abs(smallSizeOneColorImage[tempAddress + 1] - smallSizeOneColorImage[tempAddress - 1]);
				gradY = abs(smallSizeOneColorImage[tempAddress + smallSizeImagWidth] - smallSizeOneColorImage[tempAddress - smallSizeImagWidth]);
				if (gradX > gradY)
					smallSizeGradientImage[smallSizeImagWidth*(y)+x] = gradX;
				else
					smallSizeGradientImage[smallSizeImagWidth*(y)+x] = gradY;
			}
		}
		maxG = -1;
		for (int r = 0; r <= 720; r += 4) // 
		{
			matchingValue = 0;
			for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
			{
				rotateX = ((CosData[r] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) - SinData[r] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) >> 10) + AdjustCenterXInImage;
				rotateY = ((SinData[r] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + CosData[r] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) >> 10) + AdjustCenterYInImage;
				matchingValue += (smallSizeGradientImage[(rotateY / 4)*smallSizeImagWidth + (rotateX / 4)]);
			}
			if (maxG < (matchingValue))
			{
				maxG = (matchingValue);
				ProtoTabletRotationAngle = r;
			}
		}
	}
	///////////////////////////////////////////////////////////////////////////////////
	for (int y = 1; y < ImageHeight - 1; y++)
	{
		for (int x = 1; x < ImageWidth - 1; x++)
		{
			gradX = abs(ColorImageData[(y*ImageWidth + (x - 1)) * 3 + rgb] - ColorImageData[(y*ImageWidth + (x + 1)) * 3 + rgb]);
			gradY = abs(ColorImageData[((y - 1)*ImageWidth + (x)) * 3 + rgb] - ColorImageData[((y + 1)*ImageWidth + (x)) * 3 + rgb]);
			if (gradX > gradY)
				GradientData[y*ImageWidth + x] = gradX;
			else
				GradientData[y*ImageWidth + x] = gradY;
		}
	}

	///원형정인 경우에 ////////////////////////////////
	if (TabletCharacter.shape == ROUND)     // 일반 x,y 매칭
	{
		int tempShiftXForAngleRange[4];
		int tempShiftYForAngleRange[4];
		maxG = -1;
		shiftSize = 8;
		for (int n = 0; n < 4; n++)
		{
			maxG = -1;
			tempShiftXForAngleRange[n] = 0;
			tempShiftYForAngleRange[n] = 0;
			tempTabletRotationAngleForAngleRange[n] = 0;
			for (int i = -shiftSize; i <= shiftSize; i += 2)
			{
				for (int j = -shiftSize; j <= shiftSize; j += 2)
				{
					matchingValue = 0;
					for (int m = 0; m < tempFrontShapeEdgePointCountForAngle[n]; m++)
					{
						tempX = tempFrontShapeEdgePointForAngle[n][m][0] + (AdjustCenterXInImage - ImageWidth / 2) + j;
						tempY = tempFrontShapeEdgePointForAngle[n][m][1] + (AdjustCenterYInImage - ImageHeight / 2) + i;
						matchingValue += (GradientData[tempY*ImageWidth + tempX]);
					}
					if (maxG < (matchingValue))
					{
						maxG = (matchingValue);
						tempShiftXForAngleRange[n] = j;
						tempShiftYForAngleRange[n] = i;
						//tempTabletRotationAngleForAngleRange[n] = r;
					}
				}
			}
		}
		//TabletMatchingResult.TabletRotationAngle = 0;//(tempTabletRotationAngleForAngleRange[0] + tempTabletRotationAngleForAngleRange[2]+ tempTabletRotationAngleForAngleRange[1] + tempTabletRotationAngleForAngleRange[3])/4;
		AdjustCenterXInImage = AdjustCenterXInImage + (2 * tempShiftXForAngleRange[0] + tempShiftXForAngleRange[1] + 2 * tempShiftXForAngleRange[2] + tempShiftXForAngleRange[3]) / 6;
		AdjustCenterXInImage = AdjustCenterXInImage + (tempShiftYForAngleRange[0] + 2 * tempShiftYForAngleRange[1] + tempShiftYForAngleRange[2] + 2 * tempShiftYForAngleRange[3]) / 6;
		//////////Display///////////////////
		Image5->Picture->Bitmap->Assign(img1);
		Image5->Canvas->Pen->Color = clRed;
		for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
		{
			tempX = TabletSetupData.FrontShapeEdgePoint[m][0] + (AdjustCenterXInImage - ImageWidth / 2);
			tempY = TabletSetupData.FrontShapeEdgePoint[m][1] + (AdjustCenterYInImage - ImageHeight / 2);
			Image5->Canvas->MoveTo(tempX, tempY);
			Image5->Canvas->LineTo(tempX, tempY + 1);
		}
	}
	else if (TabletCharacter.shape == OVAL || TabletCharacter.shape == OBLONG || TabletCharacter.shape == TRIANGLE || TabletCharacter.shape == SQUARE)
	{
		int maxMatchingValue[4];
		for (int n = 0; n < 4; n++)
		{
			maxG = -1;
			maxMatchingValue[n] = 0;
			tempShiftXForAngleRange[n] = 0;
			tempShiftYForAngleRange[n] = 0;
			tempTabletRotationAngleForAngleRange[n] = 0;
			for (int r = -rotationRange + ProtoTabletRotationAngle; r <= rotationRange + ProtoTabletRotationAngle; r += 2)
			{
				for (int m = 0; m < tempFrontShapeEdgePointCountForAngle[n]; m++)
				{
					if (r >= 0)
					{
						rotationTempPoint[m][0] = (CosData[r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) - SinData[r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterXInImage;
						rotationTempPoint[m][1] = (SinData[r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) + CosData[r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterYInImage;
					}
					else
					{
						rotationTempPoint[m][0] = (CosData[-r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) + SinData[-r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterXInImage;
						rotationTempPoint[m][1] = (-SinData[-r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) + CosData[-r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterYInImage;
					}
				}
				for (int i = -shiftSize; i <= shiftSize; i += 2)
				{
					for (int j = -shiftSize; j <= shiftSize; j += 2)
					{
						matchingValue = 0;
						for (int m = 0; m < tempFrontShapeEdgePointCountForAngle[n]; m++)
						{
							tempX = rotationTempPoint[m][0] + j;
							tempY = rotationTempPoint[m][1] + i;
							matchingValue += (GradientData[tempY*ImageWidth + tempX]);
						}
						if (maxG < (matchingValue))
						{
							maxG = (matchingValue);
							if (tempFrontShapeEdgePointCountForAngle[n]);
							maxMatchingValue[n] = maxG * 1024 / tempFrontShapeEdgePointCountForAngle[n];
							tempShiftXForAngleRange[n] = j;
							tempShiftYForAngleRange[n] = i;
							tempTabletRotationAngleForAngleRange[n] = r;
						}
					}
				}
			}
		}
		angle = (tempTabletRotationAngleForAngleRange[0] * maxMatchingValue[0]
			+ tempTabletRotationAngleForAngleRange[2] * maxMatchingValue[2]
			+ tempTabletRotationAngleForAngleRange[1] * maxMatchingValue[1]
			+ tempTabletRotationAngleForAngleRange[3] * maxMatchingValue[3]) / (maxMatchingValue[0] + maxMatchingValue[1] + maxMatchingValue[2] + maxMatchingValue[3]);
		TabletshiftX =
			(tempShiftXForAngleRange[0] * maxMatchingValue[0]
				+ tempShiftXForAngleRange[1] * maxMatchingValue[1]
				+ tempShiftXForAngleRange[2] * maxMatchingValue[2]
				+ tempShiftXForAngleRange[3] * maxMatchingValue[3]) / (maxMatchingValue[0] + maxMatchingValue[1] + maxMatchingValue[2] + maxMatchingValue[3]);
		TabletshiftY =
			(tempShiftYForAngleRange[0] * maxMatchingValue[0]
				+ tempShiftYForAngleRange[1] * maxMatchingValue[1]
				+ tempShiftYForAngleRange[2] * maxMatchingValue[2]
				+ tempShiftYForAngleRange[3] * maxMatchingValue[3]) / (maxMatchingValue[0] + maxMatchingValue[1] + maxMatchingValue[2] + maxMatchingValue[3]);


		AdjustCenterXInImage += TabletshiftX;
		AdjustCenterYInImage += TabletshiftY;
		RotationAngleInSelectedImage = -angle / 2;

		//////////Display///////////////////
		Image5->Canvas->Pen->Color = clRed;
		Image5->Picture->Bitmap->Assign(img1);

		for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
		{
			if (angle >= 0)
			{
				rotationTempPoint[m][0] = (CosData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) - SinData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageWidth / 2;
				rotationTempPoint[m][1] = (SinData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + CosData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageHeight / 2;
			}
			else
			{
				rotationTempPoint[m][0] = (CosData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + SinData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageWidth / 2;
				rotationTempPoint[m][1] = (-SinData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + CosData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageHeight / 2;
			}
			tempX = rotationTempPoint[m][0] + (AdjustCenterXInImage - ImageWidth / 2);
			tempY = rotationTempPoint[m][1] + (AdjustCenterYInImage - ImageHeight / 2);
			Image5->Canvas->MoveTo(tempX, tempY);
			Image5->Canvas->LineTo(tempX, tempY + 1);
		}
		Image5->Refresh();
	}
	else if (TabletCharacter.shape == ETC) // // 회전  고려한 x,y 매칭
	{
		if (TabletCharacter.symmetric_line_count == ASYMMETRY_TABLET)
		{
			int x, y;
			int tempAddress;
			int matchingValue;
			int forwardMaxMatchingValue;
			int reverseMaxMatchingValue;
			int forwardAngle;
      int forwardShiftX;
      int forwardShiftY;
			int reverseAngle;
      int reverseShiftX;
      int reverseShiftY;
			int shiftX, shiftY;
			int tempX, tempY;
			int m;
			int rX, rY;
			int edgeSW;
      int sX, sY;

			shiftX = AdjustCenterXInImage - MAX_IMAGE_WIDTH / 2;
			shiftY = AdjustCenterYInImage - MAX_IMAGE_HEIGHT / 2;

			// 정방향 회전
			forwardMaxMatchingValue = 0;

			for (int r = 0; r < 720; r++)
			{
        for(sY = -10; sY <= 10; sY+=2)
        {
          for(sX = -10; sX <= 10; sX+=2)
          {
            matchingValue = 0;
            for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m+=4)
            {
              tempX = TabletSetupData.FrontShapeEdgePoint[m][0] + shiftX;
              tempY = TabletSetupData.FrontShapeEdgePoint[m][1] + shiftY;

              if (r >= 0)
              {
                rX = ((tempX - AdjustCenterXInImage) * CosData[r] - (tempY - AdjustCenterYInImage)* SinData[r]) / 1024 + AdjustCenterXInImage + sX;
                rY = ((tempX - AdjustCenterXInImage) * SinData[r] + (tempY - AdjustCenterYInImage)* CosData[r]) / 1024 + AdjustCenterYInImage + sY;
              }
              else
              {
                rX = ((tempX - AdjustCenterXInImage) * CosData[-r] + (tempY - AdjustCenterYInImage) * SinData[-r]) / 1024 + AdjustCenterXInImage + sX;
                rY = (-(tempX - AdjustCenterXInImage) * SinData[-r] + (tempY - AdjustCenterYInImage) * CosData[-r]) / 1024 + AdjustCenterYInImage + sY;
              }

              if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
              {
                if (*(GradientData + ImageWidth * rY + rX))
                  matchingValue += *(GradientData + ImageWidth * rY + rX);
              }
            }

            if (matchingValue > forwardMaxMatchingValue)
            {
              forwardMaxMatchingValue = matchingValue;
              forwardAngle = r;
              forwardShiftX = sX;
              forwardShiftY = sY;
            }
          }
        }
			}

			// 정제 뒤집어서 회전
			reverseMaxMatchingValue = 0;

			for (int r = 0; r < 720; r++)
			{
        for(sY = -10; sY <= 10; sY+=2)
        {
          for(sX = -10; sX <= 10; sX+=2)
          {
            matchingValue = 0;
            for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m+=4)
            {
              tempX = (MAX_IMAGE_WIDTH - TabletSetupData.FrontShapeEdgePoint[m][0]) + shiftX;
              tempY = TabletSetupData.FrontShapeEdgePoint[m][1] + shiftY;

              if (r >= 0)
              {
                rX = ((tempX - AdjustCenterXInImage) * CosData[r] - (tempY - AdjustCenterYInImage)* SinData[r]) / 1024 + AdjustCenterXInImage + sX;
                rY = ((tempX - AdjustCenterXInImage) * SinData[r] + (tempY - AdjustCenterYInImage)* CosData[r]) / 1024 + AdjustCenterYInImage + sY;
              }
              else
              {
                rX = ((tempX - AdjustCenterXInImage) * CosData[-r] + (tempY - AdjustCenterYInImage) * SinData[-r]) / 1024 + AdjustCenterXInImage + sX;
                rY = (-(tempX - AdjustCenterXInImage) * SinData[-r] + (tempY - AdjustCenterYInImage) * CosData[-r]) / 1024 + AdjustCenterYInImage + sY;
              }

              if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
              {
                if (*(GradientData + ImageWidth * rY + rX))
                  matchingValue += *(GradientData + ImageWidth * rY + rX);
              }
            }

            if (matchingValue > reverseMaxMatchingValue)
            {
              reverseMaxMatchingValue = matchingValue;
              reverseAngle = r;
              reverseShiftX = sX;
              reverseShiftY = sY;
            }
          }
        }
			}

			if (forwardMaxMatchingValue > reverseMaxMatchingValue)
			{
				tabletETCShape_UpSideDownSW = 0;
				angle = forwardAngle;
        sX = forwardShiftX;
        sY = forwardShiftY;
			}
			else
			{
				tabletETCShape_UpSideDownSW = 1;
				angle = reverseAngle;
        sX = reverseShiftX;
        sY = reverseShiftY;
			}

      RotationAngleInSelectedImage = (float)forwardAngle / 2.0;
      RotationAngleInSelectedImage = -RotationAngleInSelectedImage;

			Image5->Canvas->Pen->Color = clRed;
			Image5->Picture->Bitmap->Assign(img1);

			if (tabletETCShape_UpSideDownSW)
			{
				for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
				{
					tempX = (MAX_IMAGE_WIDTH - TabletSetupData.FrontShapeEdgePoint[m][0]);
					tempY = TabletSetupData.FrontShapeEdgePoint[m][1];

					if (angle >= 0)
					{
						rotationTempPoint[m][0] = (CosData[angle] * (tempX - ImageWidth / 2) - SinData[angle] * (tempY - ImageHeight / 2)) / 1024 + ImageWidth / 2 + sX;
						rotationTempPoint[m][1] = (SinData[angle] * (tempX - ImageWidth / 2) + CosData[angle] * (tempY - ImageHeight / 2)) / 1024 + ImageHeight / 2 + sY;
					}
					else
					{
						rotationTempPoint[m][0] = (CosData[-angle] * (tempX - ImageWidth / 2) + SinData[-angle] * (tempY - ImageHeight / 2)) / 1024 + ImageWidth / 2 + sX;
						rotationTempPoint[m][1] = (-SinData[-angle] * (tempX - ImageWidth / 2) + CosData[-angle] * (tempY - ImageHeight / 2)) / 1024 + ImageHeight / 2 + sY;
					}
					tempX = rotationTempPoint[m][0] + (AdjustCenterXInImage - ImageWidth / 2);
					tempY = rotationTempPoint[m][1] + (AdjustCenterYInImage - ImageHeight / 2);

					if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
					{
						Image5->Canvas->MoveTo(tempX, tempY);
						Image5->Canvas->LineTo(tempX, tempY + 1);
					}
				}
				Image5->Refresh();
			}
			else
			{
				for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
				{
					tempX = TabletSetupData.FrontShapeEdgePoint[m][0];
					tempY = TabletSetupData.FrontShapeEdgePoint[m][1];

					if (angle >= 0)
					{
						rotationTempPoint[m][0] = (CosData[angle] * (tempX - ImageWidth / 2) - SinData[angle] * (tempY - ImageHeight / 2)) / 1024 + ImageWidth / 2;
						rotationTempPoint[m][1] = (SinData[angle] * (tempX - ImageWidth / 2) + CosData[angle] * (tempY - ImageHeight / 2)) / 1024 + ImageHeight / 2;
					}
					else
					{
						rotationTempPoint[m][0] = (CosData[-angle] * (tempX - ImageWidth / 2) + SinData[-angle] * (tempY - ImageHeight / 2)) / 1024 + ImageWidth / 2;
						rotationTempPoint[m][1] = (-SinData[-angle] * (tempX - ImageWidth / 2) + CosData[-angle] * (tempY - ImageHeight / 2)) / 1024 + ImageHeight / 2;
					}
					tempX = rotationTempPoint[m][0] + (AdjustCenterXInImage - ImageWidth / 2);
					tempY = rotationTempPoint[m][1] + (AdjustCenterYInImage - ImageHeight / 2);

					if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
					{
						Image5->Canvas->MoveTo(tempX, tempY);
						Image5->Canvas->LineTo(tempX, tempY + 1);
					}
				}
				Image5->Refresh();
			}
		}
		else
		{
			int maxMatchingValue[4];
			for (int n = 0; n < 4; n++)
			{
				maxG = -1;
				maxMatchingValue[n] = 0;
				tempShiftXForAngleRange[n] = 0;
				tempShiftYForAngleRange[n] = 0;
				tempTabletRotationAngleForAngleRange[n] = 0;
				for (int r = -rotationRange + ProtoTabletRotationAngle; r <= rotationRange + ProtoTabletRotationAngle; r += 2)
				{
					for (int m = 0; m < tempFrontShapeEdgePointCountForAngle[n]; m++)
					{
						if (r >= 0)
						{
							rotationTempPoint[m][0] = (CosData[r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) - SinData[r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterXInImage;
							rotationTempPoint[m][1] = (SinData[r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) + CosData[r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterYInImage;
						}
						else
						{
							rotationTempPoint[m][0] = (CosData[-r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) + SinData[-r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterXInImage;
							rotationTempPoint[m][1] = (-SinData[-r] * (tempFrontShapeEdgePointForAngle[n][m][0] - ImageWidth / 2) + CosData[-r] * (tempFrontShapeEdgePointForAngle[n][m][1] - ImageHeight / 2)) / 1024 + AdjustCenterYInImage;
						}
					}
					for (int i = -shiftSize; i <= shiftSize; i += 2)
					{
						for (int j = -shiftSize; j <= shiftSize; j += 2)
						{
							matchingValue = 0;
							for (int m = 0; m < tempFrontShapeEdgePointCountForAngle[n]; m++)
							{
								tempX = rotationTempPoint[m][0] + j;
								tempY = rotationTempPoint[m][1] + i;
								matchingValue += (GradientData[tempY*ImageWidth + tempX]);
							}
							if (maxG < (matchingValue))
							{
								maxG = (matchingValue);
								if (tempFrontShapeEdgePointCountForAngle[n]);
								maxMatchingValue[n] = maxG * 1024 / tempFrontShapeEdgePointCountForAngle[n];
								tempShiftXForAngleRange[n] = j;
								tempShiftYForAngleRange[n] = i;
								tempTabletRotationAngleForAngleRange[n] = r;
							}
						}
					}
				}
			}
			angle = (tempTabletRotationAngleForAngleRange[0] * maxMatchingValue[0]
				+ tempTabletRotationAngleForAngleRange[2] * maxMatchingValue[2]
				+ tempTabletRotationAngleForAngleRange[1] * maxMatchingValue[1]
				+ tempTabletRotationAngleForAngleRange[3] * maxMatchingValue[3]) / (maxMatchingValue[0] + maxMatchingValue[1] + maxMatchingValue[2] + maxMatchingValue[3]);
			TabletshiftX =
				(tempShiftXForAngleRange[0] * maxMatchingValue[0]
					+ tempShiftXForAngleRange[1] * maxMatchingValue[1]
					+ tempShiftXForAngleRange[2] * maxMatchingValue[2]
					+ tempShiftXForAngleRange[3] * maxMatchingValue[3]) / (maxMatchingValue[0] + maxMatchingValue[1] + maxMatchingValue[2] + maxMatchingValue[3]);
			TabletshiftY =
				(tempShiftYForAngleRange[0] * maxMatchingValue[0]
					+ tempShiftYForAngleRange[1] * maxMatchingValue[1]
					+ tempShiftYForAngleRange[2] * maxMatchingValue[2]
					+ tempShiftYForAngleRange[3] * maxMatchingValue[3]) / (maxMatchingValue[0] + maxMatchingValue[1] + maxMatchingValue[2] + maxMatchingValue[3]);


			AdjustCenterXInImage += TabletshiftX;
			AdjustCenterYInImage += TabletshiftY;
			RotationAngleInSelectedImage = -angle / 2;

			//////////Display///////////////////
			Image5->Canvas->Pen->Color = clRed;
			Image5->Picture->Bitmap->Assign(img1);

			for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
			{
				if (angle >= 0)
				{
					rotationTempPoint[m][0] = (CosData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) - SinData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageWidth / 2;
					rotationTempPoint[m][1] = (SinData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + CosData[angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageHeight / 2;
				}
				else
				{
					rotationTempPoint[m][0] = (CosData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + SinData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageWidth / 2;
					rotationTempPoint[m][1] = (-SinData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][0] - ImageWidth / 2) + CosData[-angle] * (TabletSetupData.FrontShapeEdgePoint[m][1] - ImageHeight / 2)) / 1024 + ImageHeight / 2;
				}
				tempX = rotationTempPoint[m][0] + (AdjustCenterXInImage - ImageWidth / 2);
				tempY = rotationTempPoint[m][1] + (AdjustCenterYInImage - ImageHeight / 2);

				if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
				{
					Image5->Canvas->MoveTo(tempX, tempY);
					Image5->Canvas->LineTo(tempX, tempY + 1);
				}
			}
			Image5->Refresh();
		}
	}

	delete(img1);
	delete(ColorImageData);
	delete(GradientData);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::DiscrimiationMarkExtractF(int a, int b)
{
	unsigned char *ColorImageData;
	unsigned char *BinarizationData;
	unsigned char *TempData;
	unsigned char *ResultData;
	unsigned char *newPrintMasingArea;

	int threshold;

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;
	ColorImageData = new byte[3 * ImageWidth*ImageHeight];
	BinarizationData = new byte[ImageWidth*ImageHeight];
	TempData = new byte[ImageWidth*ImageHeight];
	ResultData = new byte[ImageWidth*ImageHeight];
	newPrintMasingArea = new byte[ImageWidth*ImageHeight];

	Byte *ptr, *ptr_U, *ptr_D;
	int rgb;
	int maxDefectSize;

	int tempSum;
	int tempCount;
	int meanColor[3];
	memset(TempData, 0, ImageWidth * ImageHeight * sizeof(unsigned char));
	memset(ResultData, 0, ImageWidth * ImageHeight * sizeof(unsigned char));
	memset(BinarizationData, 0, ImageWidth * ImageHeight * sizeof(unsigned char));
	memset(PrintBinarizationData, 0, ImageWidth * ImageHeight * sizeof(unsigned char));
	memset(newPrintMasingArea, 0, ImageWidth * ImageHeight * sizeof(unsigned char));
	rgb = 1;
	for (int y = 1; y < ImageHeight - 1; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		ptr_U = (byte*)SelectedImage->ScanLine[y - 1];
		ptr_D = (byte*)SelectedImage->ScanLine[y + 1];
		for (int x = 1; x < ImageWidth - 1; x++)
		{
			for (int c = 0; c < 3; c++)
			{
				tempSum = 0;
				for (int j = x - 1; j <= x + 1; j++)
				{
					tempSum += (ptr[3 * j + c] + ptr_D[3 * j + c] + ptr_U[3 * j + c]);
				}
				ColorImageData[(y*ImageWidth + x) * 3 + c] = tempSum / 9;
			}
		}
	}

	meanColor[0] = 0;
	meanColor[1] = 0;
	meanColor[2] = 0;
	tempCount = 0;
	for (int y = 0; y < ImageHeight; y++)
	{
		for (int x = 0; x < ImageWidth; x++)
		{
			if (ColorImageData[(y*ImageWidth + x) * 3] > 30 || ColorImageData[(y*ImageWidth + x) * 3 + 1] > 30 || ColorImageData[(y*ImageWidth + x) * 3 + 2] > 30)
			{
				meanColor[0] += ColorImageData[(y*ImageWidth + x) * 3];
				meanColor[1] += ColorImageData[(y*ImageWidth + x) * 3 + 1];
				meanColor[2] += ColorImageData[(y*ImageWidth + x) * 3 + 2];
				tempCount++;
				BinarizationData[y*ImageWidth + x] = 1;
			}
		}
	}
	if (tempCount)
	{
		meanColor[0] /= tempCount;
		meanColor[1] /= tempCount;
		meanColor[2] /= tempCount;
	}
	if (SelectedFace == 0)
	{
		TabletSetupData.protoStudyColorB = meanColor[0];
		TabletSetupData.protoStudyColorG = meanColor[1];
		TabletSetupData.protoStudyColorR = meanColor[2];
	}
	else
	{
		TabletSetupData.rear_protoStudyColorB = meanColor[0];
		TabletSetupData.rear_protoStudyColorG = meanColor[1];
		TabletSetupData.rear_protoStudyColorR = meanColor[2];
	}
	if (meanColor[2] > meanColor[1] * 110 / 100)
	{
		if (meanColor[2] > meanColor[0] * 110 / 100)
		{
			rgb = 2;
		}
	}
	if (meanColor[0] > meanColor[1] * 110 / 100)
	{
		if (meanColor[0] > meanColor[2] * 110 / 100)
		{
			rgb = 0;
		}
	}

	if (TabletCharacter.discriminationDisplay_kind == PRINT)
		threshold = 5; // 15;
	else
		threshold = 8;

	int selfPositionValue, searchRange;
	int tempAddress, tempAddress2;
	int thresholdDark;
	int colorDiff;
	int darkDefectCheckSW;

	if (TabletCharacter.discriminationDisplay_kind == PRINT)
	{
		for (int y = 0; y < ImageHeight; y++)
		{
			for (int x = 0; x < ImageWidth; x++)
			{
				if (PrintMaskArea[y*ImageWidth + x])
				{
					tempAddress = ImageWidth * y + x;
					tempCount = 0;
					thresholdDark = threshold;
					darkDefectCheckSW = 0;
					selfPositionValue = ColorImageData[tempAddress * 3 + rgb];
					searchRange = 16;
					for (int r = searchRange; r >= 8; r -= 4)
					{
						tempAddress2 = tempAddress - r * ImageWidth;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						tempAddress2 = tempAddress + r * ImageWidth;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						tempAddress2 = tempAddress - r;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						tempAddress2 = tempAddress + r;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						tempAddress2 = tempAddress + r * ImageWidth + r;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						tempAddress2 = tempAddress - r * ImageWidth - r;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						tempAddress2 = tempAddress + r * ImageWidth - r;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						tempAddress2 = tempAddress - r * ImageWidth + r;
						if (BinarizationData[tempAddress2])
						{
							tempCount++;
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
							}
						}
						if (tempCount >= 3)
						{
							if (darkDefectCheckSW >= 3)
							{
								*(newPrintMasingArea + y * ImageWidth + x) = 1;
								break;
							}
							if (r == 8)
								break;
						}
					}
				}
			}
		}
	}
	else
	{
		unsigned char BrightPixelNeighborPrint[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];
		memset(BrightPixelNeighborPrint, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

		searchRange = 12;
		int brightPxielThreshold = 8;
		int maxcolorDiff;
		int defectCheck;
		int topSW, bottomSW, leftSW, rightSW, topleftSW, toprightSW, bottomleftSW, bottomrightSW;
		int r;

		for (int y = 0; y < ImageHeight; y++)
		{
			for (int x = 0; x < ImageWidth; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (PrintMaskArea[tempAddress])
				{
					selfPositionValue = ColorImageData[tempAddress * 3 + rgb];

					maxcolorDiff = 0;
					defectCheck = 0;

					topSW = bottomSW = leftSW = rightSW = topleftSW = toprightSW = bottomleftSW = bottomrightSW = 0;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								rightSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								leftSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								topSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								bottomSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								topleftSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck < 1) continue;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								toprightSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck < 2) continue;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								bottomleftSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck < 3) continue;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r;

						if (BinarizationData[tempAddress2])
						{
							colorDiff = selfPositionValue - ColorImageData[tempAddress2 * 3 + rgb];

							if (colorDiff > brightPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								bottomrightSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck >= 4)
					{
						if ((topSW && bottomSW) ||
							(leftSW && rightSW) ||
							(topleftSW && bottomrightSW) ||
							(toprightSW && bottomleftSW))
						{
							BrightPixelNeighborPrint[tempAddress] = maxcolorDiff;
						}
					}
				}
			}
		}

		searchRange = 12;
		int darkPxielThreshold = 4;
		for (int y = 0; y < ImageHeight; y++)
		{
			for (int x = 0; x < ImageWidth; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				if (PrintMaskArea[tempAddress])
				{
					selfPositionValue = ColorImageData[tempAddress * 3 + rgb];

					maxcolorDiff = 0;
					defectCheck = 0;

					topSW = bottomSW = leftSW = rightSW = topleftSW = toprightSW = bottomleftSW = bottomrightSW = 0;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								rightSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								leftSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								topSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								bottomSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								topleftSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck < 1) continue;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								toprightSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck < 2) continue;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								bottomleftSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck < 3) continue;

					for (r = searchRange; r >= 4; r -= 4)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r;

						if (BinarizationData[tempAddress2] && !BrightPixelNeighborPrint[tempAddress2])
						{
							colorDiff = ColorImageData[tempAddress2 * 3 + rgb] - selfPositionValue;

							if (colorDiff > darkPxielThreshold)
							{
								if (maxcolorDiff < colorDiff)
									maxcolorDiff = colorDiff;

								bottomrightSW = 1;
								defectCheck++;
								break;
							}
						}
					}

					if (defectCheck >= 4)
					{
						newPrintMasingArea[tempAddress] = 1;
					}
				}
			}
		}
	}

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			ptr[3 * x] = 0;
			ptr[3 * x + 1] = 0;
			ptr[3 * x + 2] = 0;
			if (newPrintMasingArea[y*ImageWidth + x])
			{
				ptr[3 * x + 1] = 255;
				PrintBinarizationData[y*ImageWidth + x] = 1;
			}
		}
	}

	Image5->Picture->Bitmap->Assign(img1);
	delete(img1);
	delete (ColorImageData);
	delete (BinarizationData);
	delete (TempData);
	delete (ResultData);
	delete (PrintBinarizationData);
	delete (newPrintMasingArea);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SaveAndExitButtonClick(TObject *Sender)
{
	if (!checkPrintExtractResult())
	{
		return;
	}

	if (MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_06, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
	{
		AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt";
		TFileStream *fileStream = new TFileStream(setupDataFileName, fmCreate);
		fileStream->Write(&TabletSetupData, sizeof(TTabletSetupData));
		delete fileStream;
		setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt_3D";
		TFileStream *fileStream1 = new TFileStream(setupDataFileName, fmCreate);
		fileStream1->Write(&Tablet3DSetupData, sizeof(TTablet3DSetupData));
		delete fileStream1;

    AnsiString setupDataBackupPath = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\SetupRecord";

    if (!DirectoryExists(setupDataBackupPath))
	  {
		  ForceDirectories(setupDataBackupPath);
	  }

    int nextFileIndex = 0;
    TIniFile *iniFile = new TIniFile(setupDataBackupPath + "\\Record.ini");
    if(iniFile)
    {
      nextFileIndex = iniFile->ReadInteger("Data", "Last Index", 0);
      delete iniFile;
    }
    nextFileIndex++;
    
    AnsiString setupDataBackupFileName = setupDataBackupPath + "\\" + IntToStr(nextFileIndex) + ".sbf";
    TFileStream *recordStream = new TFileStream(setupDataBackupFileName, fmCreate);

    TDateTime SaveTime = Now();
    int size = sizeof(unsigned int) + sizeof(int) + sizeof(TDateTime) + sizeof(TTabletSetupData) + sizeof(TTablet3DSetupData);
    unsigned int checksum = 0;
    checksum += MakeCheckSumID((unsigned int*) &TabletSetupData, sizeof(TTabletSetupData) / 4);
    checksum += MakeCheckSumID((unsigned int*) &Tablet3DSetupData, sizeof(TTablet3DSetupData) / 4);

    recordStream->Write(&checksum, sizeof(unsigned int));
    recordStream->Write(&size, sizeof(int));
    recordStream->Write(&SaveTime, sizeof(TDateTime));
    recordStream->Write(&TabletSetupData, sizeof(TTabletSetupData));
    recordStream->Write(&Tablet3DSetupData, sizeof(TTablet3DSetupData));
    delete recordStream;

    iniFile = new TIniFile(setupDataBackupPath + "\\Record.ini");
    if(iniFile)
    {
      iniFile->WriteInteger("Data", "Last Index", nextFileIndex);
      delete iniFile;
    }

		CPBSetupInfo.StudySetupDataValid = false;
		CPBSetupInfo.InspectionSetupDataValid = false;

    if(SetupMode == TABLET_SETUP_MODE_NORMAL)
    {
		  ProductData.ProcessingStep = TABLET_PROCESSING_STEP_FIRST_STUDY_REQUIRED;
		  AnsiString fileName = GetProductDataFileName(ProductData.ProductCode);
		  WriteProductData(fileName, ProductData);
    }

		AddCSVActionLog(ECSV_ACTION_TABLET_CHARACTER_EXTRACT, UserInfo.Name, ProductData.ProductName, NULL, 0);
		AddCSVActionLog(ECSV_ACTION_TABLET_CHARACTER_EXTRACT_END, UserInfo.Name, ProductData.ProductName, NULL, 0);

    SetupDataChanged = true;

		ModalResult = mrOk;
		this->Close();
	}
	else
	{
		ModalResult = mrCancel;
		this->Close();
	}
}
//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::ImageSelectButtonClick(TObject *Sender)
{
	SelectedImageN[0] = 0;
	SelectedImageN[1] = 0;

	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = false;
	Panel5->Visible = false;
	BitBtn9->Visible = false;
	SpeedButton1->Click();
	GroupBox1->Visible = true;
	SelectedWorkSW[0] = 0;
	SelectedWorkSW[1] = 0;
	ImageSelectActiveSW = 1;
	Graphics::TBitmap *img1;

  SpeedButton1->Visible = true;
  SpeedButton2->Visible = true;

	if (TabletCharacter.discriminationDisplay_num == ONE_FACE && TabletCharacter.tabletColorN == TWOCOLOR)
	{
		ShowMessage(TABLETCHARACTEREXTRACTFORM_MSG_07);
	}

	img1 = new Graphics::TBitmap();
	for (int i = 1; i <= 30; i++)
	{
		AnsiString str;
		if (TabletCharacter.discriminationDisplay_kind != PRINT && TabletCharacter.tabletColorN != TWOCOLOR)
		{
			ExtractImage(img1, i, SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode ,EIK_NORMAL);
		}
		else
		{
			ExtractImage(img1, i, SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);
		}

		if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
		{
			if (!ReductionImageScale(img1)) continue;
		}

		((TTntImage *)FindComponent("CaptureImage" + IntToStr(i)))->Picture->Bitmap->Assign(img1);
		((TTntImage *)FindComponent("CaptureImage" + IntToStr(i)))->Stretch = true;
		((TTntImage *)FindComponent("CaptureImage" + IntToStr(i)))->Refresh();
		Image1->Picture->Bitmap->Assign(img1);
	}
	delete(img1);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::PrintManualExtractButtonClick(TObject *Sender)
{
	PrintMaskingButton->Visible = true;
	PrintManualExtractButton->Visible = true;
	ETC_InformationExtractButton->Visible = false;
	PrintExtractWorkEndButton->Visible = false;

	ManualCorrectSW = 1;
	GroupBox8->Visible = true;
	ManualEraseButton->Down = true;
	ManualEraseButton->Font->Color = clRed;
	ManualDrawButton->Font->Color = 0x555555;
	Panel17->Visible = true;
	Image9->Visible = true;

	Image11->Canvas->Brush->Style = bsSolid;
	Image11->Canvas->Brush->Color = clRed;
	Image11->Canvas->Pen->Color = clBlack;
	Image11->Canvas->Pen->Width = 2;
	Image11->Canvas->Rectangle(0, 0, Image11->Width, Image11->Height);
	Image12->Canvas->Brush->Style = bsSolid;
	Image12->Canvas->Brush->Color = clGreen;
	Image12->Canvas->Pen->Color = clBlack;
	Image12->Canvas->Pen->Width = 2;
	Image12->Canvas->Rectangle(0, 0, Image12->Width, Image12->Height);
	Image13->Canvas->Brush->Style = bsSolid;
	Image13->Canvas->Brush->Color = clBlue;
	Image13->Canvas->Pen->Color = clBlack;
	Image13->Canvas->Pen->Width = 2;
	Image13->Canvas->Rectangle(0, 0, Image13->Width, Image13->Height);

	ManualWorkKind = ERASE;
	SelectedDisplayColor = BLUE;
	noneSelectedDisplayColor1 = RED;
	noneSelectedDisplayColor2 = GREEN;

	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 0);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 0);
	else
		refreshZoomInTabletImage(NULL, 0);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::UpDown2Click(TObject *Sender, TUDBtnType Button)
{
	if (Button == 0)
	{
		ManualWorkAreaWidth++;
		Image10->Canvas->Brush->Style = bsSolid;
		Image10->Canvas->Brush->Color = clWhite;
		Image10->Canvas->Rectangle(0, 0, Image10->Width, Image10->Height);
		Image10->Canvas->Pen->Color = clRed;
		Image10->Canvas->Brush->Color = clRed;
		Image10->Canvas->Ellipse(Image10->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image10->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image10->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image10->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
	}
	else
	{
		ManualWorkAreaWidth--;
		if (ManualWorkAreaWidth < 1)
			ManualWorkAreaWidth = 1;
		Image10->Canvas->Brush->Style = bsSolid;
		Image10->Canvas->Brush->Color = clWhite;
		Image10->Canvas->Rectangle(0, 0, Image10->Width, Image10->Height);
		Image10->Canvas->Pen->Color = clRed;
		Image10->Canvas->Brush->Color = clRed;
		Image10->Canvas->Ellipse(Image10->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image10->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image10->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image10->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ManualWorkEndButtonClick(TObject *Sender)
{
  if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
  {
    PrintInformationCalculation(PRINT_NEW);
	  //ETC_InformationExtractButton->Visible = true;
  }
  else
  {
    SplitLineInformationCalculation();
  }

	PrintMaskingButton->Visible = true;
	PrintManualExtractButton->Visible = true;
  PrintExtractWorkEndButton->Visible = true;
	GroupBox8->Visible = false;
	Image9->Visible = false;
	Panel17->Visible = false;
	ZoomOptionBox->Visible = false;
	ManualCorrectSW = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ManualEraseButtonClick(TObject *Sender)
{
	ManualWorkKind = ERASE;
	ManualEraseButton->Font->Color = clRed;
	ManualDrawButton->Font->Color = 0x555555;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ManualDrawButtonClick(TObject *Sender)
{
	ManualWorkKind = DRAW;
	ManualEraseButton->Font->Color = 0x555555;
	ManualDrawButton->Font->Color = clRed;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image9MouseDown(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	ImageDownSW = 1;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image9MouseMove(TObject *Sender, TShiftState Shift,
	int X, int Y)
{
	Byte *ptr, *tr1, *tr2, *tr;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth * 2;
	img1->Height = ImageHeight * 2;
	img1->PixelFormat = pf24bit;
	Graphics::TBitmap *img2;
	img2 = new Graphics::TBitmap();
	img2->Width = ImageWidth;
	img2->Height = ImageHeight;
	img2->PixelFormat = pf24bit;

	if (ManualCorrectSW)
	{
		if (ImageDownSW)
		{
			if (ManualWorkKind == ERASE)
			{
				for (int y = Y - ManualWorkAreaWidth / 2; y <= Y + ManualWorkAreaWidth / 2; y++)
				{
					for (int x = X - ManualWorkAreaWidth / 2; x <= X + ManualWorkAreaWidth / 2; x++)
					{
						PrintBinarizationData[(y / zoomInOutSize + zoomROIY1)*ImageWidth + (x / zoomInOutSize + zoomROIX1)] = false;
					}
				}
			}
			else if (ManualWorkKind == DRAW)
			{
				for (int y = Y - ManualWorkAreaWidth / 2; y <= Y + ManualWorkAreaWidth / 2; y++)
				{
					for (int x = X - ManualWorkAreaWidth / 2; x <= X + ManualWorkAreaWidth / 2; x++)
					{
						PrintBinarizationData[(y / zoomInOutSize + zoomROIY1)*ImageWidth + (x / zoomInOutSize + zoomROIX1)] = true;
					}
				}
			}
		}
		for (int y = 0; y < ImageHeight * 2; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth * 2; x++)
			{
				if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)])
				{
					ptr[3 * x + SelectedDisplayColor] = 255;
					//ptr[3*x+noneSelectedDisplayColor1] = 40;
					//ptr[3*x+noneSelectedDisplayColor2] = 40;
				}
			}
		}
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img2->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				ptr[3 * x] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
				if (PrintBinarizationData[y*ImageWidth + x])
				{
					ptr[3 * x + 1] = 255;
				}
			}
		}

		refreshZoomInTabletImage(PrintBinarizationData, 0);
	}
	else if (PrintMaskSW)
	{
		if (ImageDownSW)
		{
			for (int y = Y - MaskWidth / 2; y <= Y + MaskWidth / 2; y++)
			{
				for (int x = X - MaskWidth / 2; x <= X + MaskWidth / 2; x++)
				{
					PrintMaskArea[(y / zoomInOutSize + zoomROIY1)*ImageWidth + (x / zoomInOutSize + zoomROIX1)] = true;
				}
			}
		}
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)SelectedImage->ScanLine[y];
			tr = (byte*)img2->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				tr[3 * x] = ptr[3 * x];
				tr[3 * x + 1] = ptr[3 * x + 1];
				tr[3 * x + 2] = ptr[3 * x + 2];
			}
		}
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img2->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				if (PrintMaskArea[y*ImageWidth + x])
				{
					ptr[3 * x] = 255;
				}
			}
		}

		refreshZoomInTabletImage(PrintMaskArea, 0);
	}

	Image9->Canvas->Pen->Color = clBlack;
	Image9->Canvas->Brush->Style = bsClear;
	if (PrintMaskSW)
		Image9->Canvas->Rectangle(X - MaskWidth / 2, Y - MaskWidth / 2, X + MaskWidth / 2, Y + MaskWidth / 2);
	else if (ManualCorrectSW)
		Image9->Canvas->Rectangle(X - ManualWorkAreaWidth / 2, Y - ManualWorkAreaWidth / 2, X + ManualWorkAreaWidth / 2, Y + ManualWorkAreaWidth / 2);
	Image9->Refresh();
	delete(img1);

	Image5->Picture->Bitmap->Assign(img2);
	Image5->Refresh();
	delete(img2);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image9MouseUp(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y)
{
	ImageDownSW = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image11Click(TObject *Sender)
{
	SelectedDisplayColor = RED;
	noneSelectedDisplayColor1 = BLUE;
	noneSelectedDisplayColor2 = GREEN;

	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 1);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 1);
	else
		refreshZoomInTabletImage(NULL, 1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image12Click(TObject *Sender)
{
	SelectedDisplayColor = GREEN;
	noneSelectedDisplayColor1 = RED;
	noneSelectedDisplayColor2 = BLUE;

	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 1);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 1);
	else
		refreshZoomInTabletImage(NULL, 1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image13Click(TObject *Sender)
{
	SelectedDisplayColor = BLUE;
	noneSelectedDisplayColor1 = RED;
	noneSelectedDisplayColor2 = GREEN;

	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 1);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 1);
	else
		refreshZoomInTabletImage(NULL, 1);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::UpDown3Click(TObject *Sender,
	TUDBtnType Button)
{
	if (Button == 0)
	{
		DrawMaskWidth++;
		Image18->Canvas->Brush->Style = bsSolid;
		Image18->Canvas->Brush->Color = clWhite;
		Image18->Canvas->Rectangle(0, 0, Image18->Width, Image18->Height);
		Image18->Canvas->Pen->Color = clRed;
		Image18->Canvas->Brush->Color = clRed;
		Image18->Canvas->Ellipse(Image18->Width / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image18->Height / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image18->Width / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5), Image18->Height / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5));
	}
	else
	{
		DrawMaskWidth--;
		if (DrawMaskWidth < 1)
			DrawMaskWidth = 1;
		Image18->Canvas->Brush->Style = bsSolid;
		Image18->Canvas->Brush->Color = clWhite;
		Image18->Canvas->Rectangle(0, 0, Image18->Width, Image18->Height);
		Image18->Canvas->Pen->Color = clRed;
		Image18->Canvas->Brush->Color = clRed;
		Image18->Canvas->Ellipse(Image18->Width / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image18->Height / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image18->Width / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5), Image18->Height / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5));
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image14MouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 1;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image14MouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image17MouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	CaptureImageMoveSW = 0;

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image17MouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	CaptureImageMoveSW = 1;
	MouseIntiatePosiX = X;
	Groupbox22StopPosition = GroupBox22->Left;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image14MouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	Byte *ptr, *tr1, *tr2, *tr;
	if (SliceMaskSW)
	{
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		img1->Width = ImageWidth;
		img1->Height = ImageHeight;
		img1->PixelFormat = pf24bit;
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				if (Print1BinarizationDataForSlicePrint[y*ImageWidth + x])
				{
					ptr[3 * x] = 0;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 2] = 0;
				}
				else
				{
					ptr[3 * x] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}

		if (ImageDownSW)
		{
			for (int y = Y - DrawMaskWidth / 2; y <= Y + DrawMaskWidth / 2; y++)
			{
				for (int x = X - DrawMaskWidth / 2; x <= X + DrawMaskWidth / 2; x++)
				{
					if (Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)])
						Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] = 2;
				}
			}
		}
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				if (Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] == 2)
				{
					ptr[3 * x + 2] = 255;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 0] = 0;
				}
			}
		}
		Image14->Picture->Bitmap->Assign(img1);
		Image14->Canvas->Pen->Color = clBlue;
		Image14->Canvas->Brush->Style = bsClear;
		Image14->Canvas->Rectangle(X - DrawMaskWidth / 2, Y - DrawMaskWidth / 2, X + DrawMaskWidth / 2, Y + DrawMaskWidth / 2);
		Image14->Repaint();
		delete(img1);
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image17MouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	if (CaptureImageMoveSW)
	{
		if (Groupbox22StopPosition - (MouseIntiatePosiX - X) > -700 && Groupbox22StopPosition - (MouseIntiatePosiX - X) <= 16)
			GroupBox22->Left = Groupbox22StopPosition - (MouseIntiatePosiX - X);
	}

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn4Click(TObject *Sender)
{
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;
	Byte *ptr;
	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			if (Print1BinarizationDataForSlicePrint[y*ImageWidth + x])
			{
				ptr[3 * x] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
			else
			{
				ptr[3 * x] = 255;
				ptr[3 * x + 1] = 255;
				ptr[3 * x + 2] = 255;
			}
		}
	}

	for (int y = 0; y < ImageHeight; y++)
	{
		for (int x = 0; x < ImageWidth; x++)
		{
			if (Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] == 2)
				Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] = 1;
		}
	}

	Image14->Picture->Bitmap->Assign(img1);
	Image14->Repaint();
	delete(img1);
}
//---------------------------------------------------------------------------




void __fastcall TTabletCharacterExtractForm::Image20MouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	CaptureImageMoveSW = 1;
	MouseIntiatePosiX = X;
	Groupbox16StopPosition = GroupBox16->Left;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image20MouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	if (CaptureImageMoveSW)
	{
		if (Groupbox16StopPosition - (MouseIntiatePosiX - X) > -1100 && Groupbox16StopPosition - (MouseIntiatePosiX - X) <= 16)
			GroupBox16->Left = Groupbox16StopPosition - (MouseIntiatePosiX - X);
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image20MouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	CaptureImageMoveSW = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn8Click(TObject *Sender)
{
	GroupBox13->Visible = false;
	GroupBox1->Visible = false;
	//    ShapExtractButton->Visible = true;
	//    DiscrimiationMarkExtract->Visible = true;
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = false;
	Panel5->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn9Click(TObject *Sender)
{
	GroupBox13->Visible = false;
	GroupBox1->Visible = false;
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;

  if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
  {
	  GroupBox20->Visible = true;
    ExtractionSplitLineGroupBox->Visible = false;
  }
  else
  {
    GroupBox20->Visible = false;
    ExtractionSplitLineGroupBox->Visible = true;
  }

	Panel5->Visible = true;

  if(frontFace2DInfoMode == FRONT_GET_DATA_MODE_PRINT)
  {
    if (TabletCharacter.discriminationDisplay_num == ONE_FACE ||
      TabletCharacter.discriminationDisplay_num == TWO_FACE_SAME)
    {
      if (SelectedWorkSW[0] == 1)
      {
        BitBtn13->Enabled = true;
      }
      else
        BitBtn13->Enabled = false;
      BitBtn14->Enabled = false;
    }
    else if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
    {
      if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
      {
        BitBtn13->Enabled = true;
        BitBtn14->Enabled = true;
      }
      else
      {
        BitBtn13->Enabled = false;
        BitBtn14->Enabled = false;
      }
    }

    // 2015-11-12 revision by moon
    // 이중정 & 한쪽각인 세팅인 경우 정제의 양면에 대한 색상의 특징추출이 정상적으로 진행되지 않음 -> 2차 학습 실패의 원인
    // 일성의 경우 이중정 and 양쪽 서로다른 각인으로 세팅되어 별도의 프로그램 수정을 진행하지 않았으나
    // 풍림의 경우 한쪽각인 정제를 생산하고 있어 다음의 수정을 진행함
    if (TabletCharacter.discriminationDisplay_num != TWO_FACE_DIFF && TabletCharacter.tabletColorN == TWOCOLOR)
    {
      unsigned char ColorImageData[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3];
      int meanColor[3] = { 0, }; //B,G,R
      int tempCount = 0;
      int tempSum;

      Byte *ptr, *ptr_U, *ptr_D;

      for (int y = 1; y < ImageHeight - 1; y++)
      {
        ptr = (byte*)SelectedImage2->ScanLine[y];
        ptr_U = (byte*)SelectedImage2->ScanLine[y - 1];
        ptr_D = (byte*)SelectedImage2->ScanLine[y + 1];
        for (int x = 1; x < ImageWidth - 1; x++)
        {
          for (int c = 0; c < 3; c++)
          {
            tempSum = 0;
            for (int j = x - 1; j <= x + 1; j++)
            {
              tempSum += (ptr[3 * j + c] + ptr_D[3 * j + c] + ptr_U[3 * j + c]);
            }
            ColorImageData[(y*ImageWidth + x) * 3 + c] = tempSum / 9;
          }
        }
      }

      for (int y = 0; y < ImageHeight; y++)
      {
        for (int x = 0; x < ImageWidth; x++)
        {
          if (ColorImageData[(y*ImageWidth + x) * 3] > 40 || ColorImageData[(y*ImageWidth + x) * 3 + 1] > 40 || ColorImageData[(y*ImageWidth + x) * 3 + 2] > 40)
          {
            meanColor[0] += ColorImageData[(y*ImageWidth + x) * 3];
            meanColor[1] += ColorImageData[(y*ImageWidth + x) * 3 + 1];
            meanColor[2] += ColorImageData[(y*ImageWidth + x) * 3 + 2];
            tempCount++;
          }
        }
      }
      if (tempCount)
      {
        meanColor[0] /= tempCount;
        meanColor[1] /= tempCount;
        meanColor[2] /= tempCount;
      }

      TabletSetupData.rear_protoStudyColorB = meanColor[0];
      TabletSetupData.rear_protoStudyColorG = meanColor[1];
      TabletSetupData.rear_protoStudyColorR = meanColor[2];
    }
  }
  else
  {
    SplitLineExtractionBtn->Enabled = true;
  }
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton1Click(
	TObject *Sender)
{
	SelectedFace = 0;
	SpeedButton1->Font->Color = clRed;
	SpeedButton2->Font->Color = clGray;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton2Click(
	TObject *Sender)
{
	if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF || TabletCharacter.tabletColorN == TWOCOLOR)
	{
		SelectedFace = 1;
		SpeedButton1->Font->Color = clGray;
		SpeedButton2->Font->Color = clRed;
	}
	else
	{
		ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_03);
	}
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn17Click(TObject *Sender)
{
  ShapExtractButton->Enabled = true;
	DiscrimiationMarkExtract->Enabled = true;
	ThreeDDiscriminationExtractButton->Enabled = bThreeDDataExtraction;
	SetThresholdBtn->Enabled = true;
  GetThreeDInfoButton->Enabled = true;
	SaveAndExitButton->Enabled = true;
  ReadHistoryButton->Enabled = true;
	Panel5->Visible = false;

  frontFace2DInfoMode = FRONT_GET_DATA_MODE_NONE;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn11Click(TObject *Sender)
{
  SelectedImageN[0] = 0;
	SelectedImageN[1] = 0;

  SetBlankImage(Image24);
  SetBlankImage(Image25);

  frontFace2DInfoMode = FRONT_GET_DATA_MODE_PRINT;

	BitBtn11->Enabled = false;
	BitBtn12->Enabled = false;
	BitBtn17->Enabled = false;
  ExtractSplitLineBtn->Enabled = false;
	GroupBox20->Visible = true;
  ExtractionSplitLineGroupBox->Visible = false;
	for (int i = 1000; i > 150; i -= 50)
	{
		GroupBox20->Left = i;
		Sleep(5);
	}
	GroupBox20->BringToFront();

  BitBtn13->Enabled = false;
  BitBtn14->Enabled = false;

  if(TabletSetupData.printData1Count >= PRINT_DATA_SIZE)
  {
    TabletSetupData.printData1Count = 0;
    memset(TabletSetupData.position_printData1, 0, sizeof(short) * PRINT_DATA_SIZE * 2);
  }
  DisplayExistData(Image26, TabletSetupData.printData1Count, TabletSetupData.position_printData1);

  if(TabletSetupData.printData2Count >= PRINT_DATA_SIZE)
  {
    TabletSetupData.printData2Count = 0;
    memset(TabletSetupData.position_printData2, 0, sizeof(short) * PRINT_DATA_SIZE * 2);
  }
  if(TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
  {
    DisplayExistData(Image27, TabletSetupData.printData2Count, TabletSetupData.position_printData2);
  }

  if(TabletCharacter.discriminationDisplay_kind == PRINT && TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF && TabletCharacter.shape == ROUND)
  {
    SimilarPrintSettingBtn->Visible = true;

    if(TabletSetupData.printData1Count && TabletSetupData.printData2Count)
    {
      SimilarPrintSettingBtn->Enabled = true;
    }
    else
    {
      SimilarPrintSettingBtn->Enabled = false;
    }
  }
  else
  {
    SimilarPrintSettingBtn->Visible = false;
  }
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn18Click(TObject *Sender)
{
	BitBtn11->Enabled = true;
	BitBtn12->Enabled = true;
	BitBtn17->Enabled = true;
  ExtractSplitLineBtn->Enabled = true;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = false;

  frontFace2DInfoMode = FRONT_GET_DATA_MODE_NONE;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn12Click(TObject *Sender)
{
	BitBtn11->Enabled = false;
	BitBtn12->Enabled = false;
	BitBtn17->Enabled = false;
  ExtractSplitLineBtn->Enabled = false;
	GroupBox21->Visible = true;
  
	AdjustWorkingKind1 = PRINT_ADJUST;
	AdjustWorkingKind2 = PRINT_ADJUST;

	for (int i = 980; i >= 130; i -= 50)
	{
		GroupBox21->Left = i;
		Sleep(5);
	}

	GroupBox21->BringToFront();

  SetBlankImage(Image30);
  SetBlankImage(Image31);

  BitBtn20->Enabled = false;
  BitBtn21->Enabled = false;

  LoadExtractedPrintLabelData();

  if(TabletCharacter.discriminationDisplay_kind == PRINT && TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF && TabletCharacter.shape == ROUND)
  {
    SimilarPrintSettingBtn2->Visible = true;

    if(TabletSetupData.printData1Count && TabletSetupData.printData2Count)
    {
      SimilarPrintSettingBtn2->Enabled = true;
    }
    else
    {
      SimilarPrintSettingBtn2->Enabled = false;
    }
  }
  else
  {
    SimilarPrintSettingBtn2->Visible = false;
  }
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn19Click(TObject *Sender)
{
	BitBtn11->Enabled = true;
	BitBtn12->Enabled = true;
	BitBtn17->Enabled = true;
  ExtractSplitLineBtn->Enabled = true;
	GroupBox21->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn13Click(TObject *Sender)
{
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = false;
	Panel5->Visible = false;
	GroupBox7->Visible = false;
	GroupBox8->Visible = false;
	GroupBox14->Visible = false;
	GroupBox11->Visible = false;
	Panel17->Visible = false;
	Image9->Visible = false;
	GroupBox6->Visible = true;
	PrintMaskingButton->Visible = true;
	PrintManualExtractButton->Visible = false;
	ETC_InformationExtractButton->Visible = false;
	PrintExtractWorkEndButton->Visible = false;
	GroupBox27->Visible = false;
	ZoomOptionBox->Visible = false;

	Panel18->Color = clBlack;
	Panel19->Color = clBlack;

	zoomInOutShiftX = 0;
	zoomInOutShiftY = 0;
	zoomInOutSize = 2;

  if (ProductData.EngraveType == ENGRAVE_TYPE_PRINT)
	{
		GroupBox8->Width = 623;
		ManualWorkEndButton->Width = 529;
		PrintTHGB->Visible = true;
	}
	else
	{
		GroupBox8->Width = 447;
		PrintTHGB->Visible = false;
		ManualWorkEndButton->Width = 401;
	}

	SelectedFace = 0;
	Byte *ptr;
	AnsiString str;
	if (TabletCharacter.discriminationDisplay_kind != PRINT && TabletCharacter.tabletColorN != TWOCOLOR)
	{
		ExtractImage(SelectedImage, SelectedImageN[0], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode ,EIK_NORMAL);
	}
	else
	{
		ExtractImage(SelectedImage, SelectedImageN[0], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);
	}

	if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
	{
		ReductionImageScale(SelectedImage);
	}

	Image5->Picture->Bitmap->Assign(SelectedImage1);
	PrintMaskSW = 0;
	ImageDownSW = 0;
	ManualCorrectSW = 0;

	DrawMaskWidth = 10;
	MaskWidth = 20;
	ManualWorkAreaWidth = 15;

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			PrintMaskArea[y*ImageWidth + x] = 0;
		}
	}
	ShapeMatching(ImageWidth, ImageHeight);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn14Click(TObject *Sender)
{
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = false;
	Panel5->Visible = false;
	GroupBox7->Visible = false;
	GroupBox8->Visible = false;
	GroupBox14->Visible = false;
	GroupBox11->Visible = false;
	Panel17->Visible = false;
	Image9->Visible = false;
	GroupBox6->Visible = true;
	PrintMaskingButton->Visible = true;
	PrintManualExtractButton->Visible = false;
	ETC_InformationExtractButton->Visible = false;
	PrintExtractWorkEndButton->Visible = false;
	GroupBox27->Visible = false;
	ZoomOptionBox->Visible = false;

	Panel18->Color = clBlack;
	Panel19->Color = clBlack;

	zoomInOutShiftX = 0;
	zoomInOutShiftY = 0;
	zoomInOutSize = 2;

  if (ProductData.EngraveType == ENGRAVE_TYPE_PRINT)
	{
		GroupBox8->Width = 623;
		ManualWorkEndButton->Width = 529;
		PrintTHGB->Visible = true;
	}
	else
	{
		GroupBox8->Width = 447;
		PrintTHGB->Visible = false;
		ManualWorkEndButton->Width = 401;
	}

	SelectedFace = 1;
	Byte *ptr;
	AnsiString str;
	if (TabletCharacter.discriminationDisplay_kind != PRINT && TabletCharacter.tabletColorN != TWOCOLOR)
	{
		ExtractImage(SelectedImage, SelectedImageN[1], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode ,EIK_NORMAL);
	}
	else
	{
		ExtractImage(SelectedImage, SelectedImageN[1], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);
	}

	if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
	{
		ReductionImageScale(SelectedImage);
	}

	Image5->Picture->Bitmap->Assign(SelectedImage2);
	PrintMaskSW = 0;
	ImageDownSW = 0;
	ManualCorrectSW = 0;

	DrawMaskWidth = 10;
	MaskWidth = 20;
	ManualWorkAreaWidth = 15;

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			PrintMaskArea[y*ImageWidth + x] = 0;
		}
	}
	ShapeMatching(ImageWidth, ImageHeight);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ETC_InformationExtractButtonClick(
	TObject *Sender)
{
	GroupBox14->Visible = true;
	GroupBox11->Visible = true;

	SliceMaskSW = 1;
	DrawMaskWidth = 10;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;
	int tx, ty;
	if (SelectedFace == 0)
	{
		memset(Print1BinarizationDataForSlicePrint, 0, 640 * 480);
		for (int m = 0; m < TabletSetupData.printData1Count; m++)
		{
			tx = TabletSetupData.position_printData1[m][0];
			ty = TabletSetupData.position_printData1[m][1];
			ptr = (byte*)img1->ScanLine[ty];
			Print1BinarizationDataForSlicePrint[ty * 640 + tx] = 1;
			ptr[3 * tx] = 0;
			ptr[3 * tx + 1] = 0;
			ptr[3 * tx + 2] = 0;
		}
	}
	else if (SelectedFace == 1)
	{
		memset(Print1BinarizationDataForSlicePrint, 0, 640 * 480);
		for (int m = 0; m < TabletSetupData.printData2Count; m++)
		{
			tx = TabletSetupData.position_printData2[m][0];
			ty = TabletSetupData.position_printData2[m][1];
			ptr = (byte*)img1->ScanLine[ty];
			Print1BinarizationDataForSlicePrint[ty * 640 + tx] = 1;
			ptr[3 * tx] = 0;
			ptr[3 * tx + 1] = 0;
			ptr[3 * tx + 2] = 0;
		}
	}
	Image14->Picture->Bitmap->Assign(img1);
	Image14->Refresh();
	delete(img1);
}
//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::Image3MouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 1;

  if (ManualWorkKind == LABELING)
  {
    PrintEditSW = 1;

    if(PrintLabelEditMode == PRINT_LABEL_EDIT_MODE_SELECT_LABEL)
    {
      if(PrintEditResult[ImageWidth * (Y / 2) + (X / 2)])
      {
        SelectedPrintLabelN = PrintEditResult[ImageWidth * (Y / 2) + (X / 2)];

        if(SelectedPrintLabelN)
        {
          TColor labelColor;

          Byte *ptr;
          ptr = (Byte *)Image3->Picture->Bitmap->ScanLine[Y];

          labelColor = ((ptr[3*X + 0] << 16) & 0x00FF0000) | ((ptr[3*X + 1] << 8) & 0x0000FF00) | ((ptr[3*X + 2] << 0) & 0x000000FF);

          Panel24->Color = labelColor;
          Panel24->Caption = "";
        }
      }
    }
    else if(PrintLabelEditMode == PRINT_LABEL_EDIT_MODE_APPLY_LABEL)
    {
      if(SelectedPrintLabelN)
      {
        if(PrintEditResult[ImageWidth * (Y / 2) + (X / 2)])
        {
          int targetLabelN = PrintEditResult[ImageWidth * (Y / 2) + (X / 2)];

          if(targetLabelN != SelectedPrintLabelN)
          {
            RearrangePrintLabel(targetLabelN);
          }
        }
      }
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image3MouseUp(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	ImageDownSW = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image3MouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	Byte *ptr, *tr1, *tr2, *tr;
	if (ManualWorkKind == ERASE || ManualWorkKind == DRAW)
	{
    PrintEditSW = 1;
    
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		img1->Width = ImageWidth * 2;
		img1->Height = ImageHeight * 2;
		img1->PixelFormat = pf24bit;

		for (int y = 0; y < ImageHeight; y++)
		{
			tr1 = (byte*)img1->ScanLine[y * 2];
			tr2 = (byte*)img1->ScanLine[y * 2 + 1];
			for (int x = 0; x < ImageWidth; x++)
			{
				for (int j = 2 * x; j <= 2 * x + 1; j++)
				{
					tr1[3 * j] = 0;
					tr1[3 * j + 1] = 0;
					tr1[3 * j + 2] = 0;

					tr2[3 * j] = 0;
					tr2[3 * j + 1] = 0;
					tr2[3 * j + 2] = 0;
				}
			}
		}

    if (ImageDownSW)
    {
      if (ManualWorkKind == ERASE)
      {
        for (int y = Y - ManualWorkAreaWidth / 2; y <= Y + ManualWorkAreaWidth / 2; y++)
        {
          for (int x = X - ManualWorkAreaWidth / 2; x <= X + ManualWorkAreaWidth / 2; x++)
          {
            PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)] = 0;
          }
        }
      }
      else if (ManualWorkKind == DRAW)
      {
        for (int y = Y - ManualWorkAreaWidth / 2; y <= Y + ManualWorkAreaWidth / 2; y++)
        {
          for (int x = X - ManualWorkAreaWidth / 2; x <= X + ManualWorkAreaWidth / 2; x++)
          {
            if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)] == 0)
              PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)] = 2;
          }
        }
      }
    }
    for (int y = 0; y < ImageHeight * 2; y++)
    {
      ptr = (byte*)img1->ScanLine[y];
      for (int x = 0; x < ImageWidth * 2; x++)
      {
        if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)] == 1)
        {
          ptr[3 * x] = 0;
          ptr[3 * x + 1] = 255;
          ptr[3 * x + 2] = 255;
        }
        else if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)] == 2)
        {
          ptr[3 * x] = 255;
          ptr[3 * x + 1] = 0;
          ptr[3 * x + 2] = 255;
        }
        else if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)] == 3)
        {
          ptr[3 * x] = 255;
          ptr[3 * x + 1] = 255;
          ptr[3 * x + 2] = 0;
        }
      }
    }

		Image3->Picture->Bitmap->Assign(img1);
		Image3->Canvas->Pen->Color = clWhite;
		Image3->Canvas->Brush->Style = bsClear;
		Image3->Canvas->Rectangle(X - ManualWorkAreaWidth / 2, Y - ManualWorkAreaWidth / 2, X + ManualWorkAreaWidth / 2, Y + ManualWorkAreaWidth / 2);
		Image3->Refresh();
		delete(img1);

    memcpy(PrintEditResult, PrintBinarizationData, ImageWidth * ImageHeight);
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn20Click(TObject *Sender)
{
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox21->Visible = false;
	Panel5->Visible = false;
	GroupBox4->Visible = true;

	SelectedFace = 0;

  //GroupBox39->Left = 536;
  GroupBox4->Height = 1350;
  GroupBox37->Visible = true;
  GroupBox38->Visible = true;
  BitBtn1->Visible = true;

  SpeedButton11->Down = true;
  SpeedButton12->Down = true;
  SpeedButton13->Down = true;

  PrintEditSW = 0;

	if (AdjustWorkingKind1 == PRINT_ADJUST)
	{
		int tx, ty;
		GroupBox5->Visible = true;
		GroupBox12->Visible = false;
		Image3->Visible = true;
		Image8->Visible = false;
		ManualWorkKind = NONE;
		SpeedButton3->Down = false;
		SpeedButton4->Down = false;
		SpeedButton5->Down = false;
    SpeedButton10->Down = false;

		SpeedButton3->Font->Color = clGray;
		SpeedButton4->Font->Color = clGray;
		SpeedButton5->Font->Color = clGray;
    SpeedButton10->Font->Color = clGray;

		SelectedDisplayColor = BLUE;
		noneSelectedDisplayColor1 = RED;
		noneSelectedDisplayColor2 = GREEN;
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		img1->Width = ImageWidth * 2;
		img1->Height = ImageHeight * 2;
		img1->PixelFormat = pf24bit;

		ManualWorkAreaWidth = 15;
		ModifyThickWidth = 0;

		Byte *ptr, *tr1, *tr2;
		memset(PrintBinarizationData, 0, ImageWidth*ImageHeight);
		memset(PrintBinarizationDataForThickModify, 0, ImageWidth*ImageHeight);
    memset(PrintEditResult, 0, ImageWidth*ImageHeight);

		for (int m = 0; m < TabletSetupData.printData1Count; m++)
		{
			tx = TabletSetupData.position_printData1[m][0];
			ty = TabletSetupData.position_printData1[m][1];
			PrintBinarizationData[ty*ImageWidth + tx] = 1;
			PrintBinarizationDataForThickModify[ty*ImageWidth + tx] = 1;
		}
		for (int y = 0; y < ImageHeight * 2; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth * 2; x++)
			{
				ptr[3 * x] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
		}
		for (int y = 0; y < ImageHeight * 2; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth * 2; x++)
			{
				if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)])
				{
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}
		Image3->Picture->Bitmap->Assign(img1);
		Image3->Refresh();
		delete(img1);
	}

  memcpy(PrintEditResult, PrintBinarizationData, ImageWidth*ImageHeight);

  Image4->Canvas->Brush->Style = bsSolid;
  Image4->Canvas->Brush->Color = clWhite;
  Image4->Canvas->Rectangle(0, 0, Image4->Width, Image4->Height);
  Image4->Canvas->Pen->Color = clRed;
  Image4->Canvas->Brush->Color = clRed;
  Image4->Canvas->Ellipse(Image4->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
  Image4->Refresh();

  PrintEditSizeOptionUpdownBtn->Enabled = false;
  PrintEditThickOptionUpdownBtn->Enabled = false;
  Panel23->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn21Click(TObject *Sender)
{
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox21->Visible = false;
	Panel5->Visible = false;
	GroupBox4->Visible = true;

	SelectedFace = 1;

  //GroupBox39->Left = 536;
  GroupBox4->Height = 1350;
  GroupBox37->Visible = true;
  GroupBox38->Visible = true;
  BitBtn1->Visible = true;

  SpeedButton11->Down = true;
  SpeedButton12->Down = true;
  SpeedButton13->Down = true;

  PrintEditSW = 0;

	if (AdjustWorkingKind2 == PRINT_ADJUST)
	{
		GroupBox5->Visible = true;
		GroupBox12->Visible = false;
		Image3->Visible = true;
		Image8->Visible = false;
		ManualWorkKind = NONE;
		SpeedButton3->Down = false;
		SpeedButton4->Down = false;
		SpeedButton5->Down = false;
    SpeedButton10->Down = false;

		SpeedButton3->Font->Color = clGray;
		SpeedButton4->Font->Color = clGray;
		SpeedButton5->Font->Color = clGray;
    SpeedButton10->Font->Color = clGray;

		SelectedDisplayColor = BLUE;
		noneSelectedDisplayColor1 = RED;
		noneSelectedDisplayColor2 = GREEN;
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		img1->Width = ImageWidth * 2;
		img1->Height = ImageHeight * 2;
		img1->PixelFormat = pf24bit;
		ManualWorkAreaWidth = 15;
		ModifyThickWidth = 0;
		int tx, ty;
		Byte *ptr, *tr1, *tr2;
		memset(PrintBinarizationData, 0, ImageWidth*ImageHeight);
		memset(PrintBinarizationDataForThickModify, 0, ImageWidth*ImageHeight);
    memset(PrintEditResult, 0, ImageWidth*ImageHeight);

		for (int m = 0; m < TabletSetupData.printData2Count; m++)
		{
			tx = TabletSetupData.position_printData2[m][0];
			ty = TabletSetupData.position_printData2[m][1];
			PrintBinarizationData[ty*ImageWidth + tx] = 1;
			PrintBinarizationDataForThickModify[ty*ImageWidth + tx] = 1;
		}
		for (int y = 0; y < ImageHeight * 2; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth * 2; x++)
			{
				ptr[3 * x] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
		}
		for (int y = 0; y < ImageHeight * 2; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth * 2; x++)
			{
				if (PrintBinarizationData[(y / 2)*ImageWidth + (x / 2)])
				{
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}
		Image3->Picture->Bitmap->Assign(img1);
		Image3->Refresh();
		delete(img1);
	}

	memcpy(PrintEditResult, PrintBinarizationData, ImageWidth*ImageHeight);

  Image4->Canvas->Brush->Style = bsSolid;
  Image4->Canvas->Brush->Color = clWhite;
  Image4->Canvas->Rectangle(0, 0, Image4->Width, Image4->Height);
  Image4->Canvas->Pen->Color = clRed;
  Image4->Canvas->Brush->Color = clRed;
  Image4->Canvas->Ellipse(Image4->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
  Image4->Refresh();

  PrintEditSizeOptionUpdownBtn->Enabled = false;
  PrintEditThickOptionUpdownBtn->Enabled = false;
  Panel23->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton3Click(
	TObject *Sender)
{
	ManualWorkKind = DRAW;
	SpeedButton3->Font->Color = clRed;
	SpeedButton4->Font->Color = clGray;
	SpeedButton5->Font->Color = clGray;
  SpeedButton10->Font->Color = clGray;

  SpeedButton3->Down = true;
  SpeedButton12->Down = true;
  SpeedButton13->Down = true;

  Image4->Canvas->Brush->Style = bsSolid;
  Image4->Canvas->Brush->Color = clWhite;
  Image4->Canvas->Rectangle(0, 0, Image4->Width, Image4->Height);
  Image4->Canvas->Pen->Color = clRed;
  Image4->Canvas->Brush->Color = clRed;
  Image4->Canvas->Ellipse(Image4->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
  Image4->Refresh();

  PrintEditSizeOptionUpdownBtn->Enabled = true;
  PrintEditThickOptionUpdownBtn->Enabled = false;

  memcpy(PrintBinarizationData, PrintEditResult, ImageWidth*ImageHeight);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton4Click(
	TObject *Sender)
{
	ManualWorkKind = ERASE;
	SpeedButton3->Font->Color = clGray;
	SpeedButton4->Font->Color = clRed;
	SpeedButton5->Font->Color = clGray;
  SpeedButton10->Font->Color = clGray;

  SpeedButton4->Down = true;
  SpeedButton12->Down = true;
  SpeedButton13->Down = true;

  Image4->Canvas->Brush->Style = bsSolid;
  Image4->Canvas->Brush->Color = clWhite;
  Image4->Canvas->Rectangle(0, 0, Image4->Width, Image4->Height);
  Image4->Canvas->Pen->Color = clRed;
  Image4->Canvas->Brush->Color = clRed;
  Image4->Canvas->Ellipse(Image4->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
  Image4->Refresh();

  PrintEditSizeOptionUpdownBtn->Enabled = true;
  PrintEditThickOptionUpdownBtn->Enabled = false;

  memcpy(PrintBinarizationData, PrintEditResult, ImageWidth*ImageHeight);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton5Click(
	TObject *Sender)
{
	ManualWorkKind = THICK;
	ModifyThickWidth = 0;
	SpeedButton3->Font->Color = clGray;
	SpeedButton4->Font->Color = clGray;
	SpeedButton5->Font->Color = clRed;
  SpeedButton10->Font->Color = clGray;

  SpeedButton5->Down = true;
  SpeedButton11->Down = true;
  SpeedButton13->Down = true;

  PrintEditSizeOptionUpdownBtn->Enabled = false;
  PrintEditThickOptionUpdownBtn->Enabled = true;

  memcpy(PrintBinarizationData, PrintEditResult, ImageWidth*ImageHeight);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::PrintEditSizeOptionUpdownBtnClick(TObject *Sender,
	TUDBtnType Button)
{
	if (Button == 0)
	{
		if (ManualWorkKind != THICK)
		{
			ManualWorkAreaWidth++;

			Image4->Canvas->Brush->Style = bsSolid;
			Image4->Canvas->Brush->Color = clWhite;
			Image4->Canvas->Rectangle(0, 0, Image4->Width, Image4->Height);
			Image4->Canvas->Pen->Color = clRed;
			Image4->Canvas->Brush->Color = clRed;
			Image4->Canvas->Ellipse(Image4->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
      Image4->Refresh();
		}
		else if (ManualWorkKind == THICK)
		{
			ModifyThickWidth++;
			PrintThickModify();
		}
	}
	else
	{
		if (ManualWorkKind != THICK)
		{
			ManualWorkAreaWidth--;
			if (ManualWorkAreaWidth < 1)
				ManualWorkAreaWidth = 1;
      
			Image4->Canvas->Brush->Style = bsSolid;
			Image4->Canvas->Brush->Color = clWhite;
			Image4->Canvas->Rectangle(0, 0, Image4->Width, Image4->Height);
			Image4->Canvas->Pen->Color = clRed;
			Image4->Canvas->Brush->Color = clRed;
			Image4->Canvas->Ellipse(Image4->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
      Image4->Refresh();
		}
		else if (ManualWorkKind == THICK)
		{
			ModifyThickWidth--;
			PrintThickModify();
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::PrintThickModify(void)
{
  PrintEditSW = 1;
  
	int checkSW;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth * 2;
	img1->Height = ImageHeight * 2;
	img1->PixelFormat = pf24bit;
	Byte *ptr, *tr1, *tr2;

	for (int y = 0; y < ImageHeight; y++)
	{
		for (int x = 0; x < ImageWidth; x++)
		{
			PrintBinarizationDataForThickModify[y*ImageWidth + x] = PrintBinarizationData[y*ImageWidth + x];
		}
	}
  
	if (ModifyThickWidth > 0)
	{
		for (int y = 30; y < ImageHeight - 30; y++)
		{
			for (int x = 30; x < ImageWidth - 30; x++)
			{
				if (PrintBinarizationData[y*ImageWidth + x])
				{
					for (int i = y - ModifyThickWidth; i <= y + ModifyThickWidth; i++)
					{
						for (int j = x - ModifyThickWidth; j <= x + ModifyThickWidth; j++)
						{
							if (PrintBinarizationData[i*ImageWidth + j] == 0)
							{
								PrintBinarizationDataForThickModify[i*ImageWidth + j] = 3;
							}
						}
					}
				}
			}
		}
	}
	else
	{
		for (int y = 30; y < ImageHeight - 30; y++)
		{
			for (int x = 30; x < ImageWidth - 30; x++)
			{
				if (PrintBinarizationData[y*ImageWidth + x])
				{
					checkSW = 0;
					for (int i = y - 1; i <= y + 1; i++)
					{
						for (int j = x - 1; j <= x + 1; j++)
						{
							if (PrintBinarizationData[i*ImageWidth + j] == 0)
							{
								checkSW = 1;
							}
						}
					}

					if (checkSW)
					{
						for (int i = y - (-ModifyThickWidth - 1); i <= y + (-ModifyThickWidth - 1); i++)
						{
							for (int j = x - (-ModifyThickWidth - 1); j <= x + (-ModifyThickWidth - 1); j++)
							{
								PrintBinarizationDataForThickModify[i*ImageWidth + j] = 0;
							}
						}
					}
				}
			}
		}
	}

	for (int y = 0; y < ImageHeight; y++)
	{
		tr1 = (byte*)img1->ScanLine[y * 2];
		tr2 = (byte*)img1->ScanLine[y * 2 + 1];
		for (int x = 0; x < ImageWidth; x++)
		{
			for (int j = 2 * x; j <= 2 * x + 1; j++)
			{
				tr1[3 * j] = 0;
				tr1[3 * j + 1] = 0;
				tr1[3 * j + 2] = 0;
				tr2[3 * j] = 0;
				tr2[3 * j + 1] = 0;
				tr2[3 * j + 2] = 0;
			}
		}
	}
	for (int y = 0; y < ImageHeight * 2; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth * 2; x++)
		{
			if (PrintBinarizationDataForThickModify[(y / 2)*ImageWidth + (x / 2)] == 1)
			{
				ptr[3 * x] = 0;
				ptr[3 * x + 1] = 255;
				ptr[3 * x + 2] = 255;
			}
			else if (PrintBinarizationDataForThickModify[(y / 2)*ImageWidth + (x / 2)] == 2)
			{
				ptr[3 * x] = 255;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 255;
			}
			else if (PrintBinarizationDataForThickModify[(y / 2)*ImageWidth + (x / 2)] == 3)
			{
				ptr[3 * x] = 255;
				ptr[3 * x + 1] = 255;
				ptr[3 * x + 2] = 0;
			}
		}
	}
	Image3->Picture->Bitmap->Assign(img1);
	Image3->Refresh();
	delete(img1);

  memcpy(PrintEditResult, PrintBinarizationDataForThickModify, ImageWidth*ImageHeight);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image8MouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	Byte *ptr, *tr1, *tr2, *tr;
	if (SliceMaskSW)
	{
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		img1->Width = ImageWidth;
		img1->Height = ImageHeight;
		img1->PixelFormat = pf24bit;
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				if (Print1BinarizationDataForSlicePrint[y*ImageWidth + x])
				{
					ptr[3 * x] = 0;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 2] = 0;
				}
				else
				{
					ptr[3 * x] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}

		if (ImageDownSW)
		{
			for (int y = Y - DrawMaskWidth / 2; y <= Y + DrawMaskWidth / 2; y++)
			{
				for (int x = X - DrawMaskWidth / 2; x <= X + DrawMaskWidth / 2; x++)
				{
					if (Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)])
						Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] = 2;
				}
			}
		}
		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				if (Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] == 2)
				{
					ptr[3 * x + 2] = 255;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 0] = 0;
				}
			}
		}
		Image8->Picture->Bitmap->Assign(img1);
		Image8->Canvas->Pen->Color = clBlue;
		Image8->Canvas->Brush->Style = bsClear;
		Image8->Canvas->Rectangle(X - DrawMaskWidth / 2, Y - DrawMaskWidth / 2, X + DrawMaskWidth / 2, Y + DrawMaskWidth / 2);
		Image8->Repaint();
		delete(img1);
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image8MouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 1;

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image8MouseUp(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	ImageDownSW = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn10Click(TObject *Sender)
{
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;
	Byte *ptr;
	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			if (Print1BinarizationDataForSlicePrint[y*ImageWidth + x])
			{
				ptr[3 * x] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
			else
			{
				ptr[3 * x] = 255;
				ptr[3 * x + 1] = 255;
				ptr[3 * x + 2] = 255;
			}
		}
	}

	for (int y = 0; y < ImageHeight; y++)
	{
		for (int x = 0; x < ImageWidth; x++)
		{
			if (Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] == 2)
				Print1BinarizationDataForSlicePrint[(y)*ImageWidth + (x)] = 1;
		}
	}

	Image8->Picture->Bitmap->Assign(img1);
	Image8->Repaint();

	delete(img1);
}

//////////////////////////////////////////////////////////////////////////

//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ThreeDDiscriminationExtractButtonClick(TObject *Sender)
{
  if(CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D ||
      CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
  {
    if(TabletSetupData.Disk1ThreeDMinThreshold == 0 && TabletSetupData.Disk2ThreeDMinThreshold == 0 &&
        TabletSetupData.Disk1ThreeDNormalizedValue == 0 && TabletSetupData.Disk2ThreeDNormalizedValue == 0)
    {
      // Cameramapinfo에 disk1, disk2 모두 disconnect 처리되었다면 이미지가 존재하지 않는 것으로 간주
      // 이외 케이스는 위 데이터가 하나라도 존재하는 경우 학습이 진행된 것으로 가정
      MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_56, mtConfirmation, TMsgDlgButtons() << mbOK);
      return;
    }
  }
  else
  {
    MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_08, mtConfirmation, TMsgDlgButtons() << mbOK);
    return;
  }

	Panel2->Visible = true;
	ShapExtractButton->Enabled = false;
	DiscrimiationMarkExtract->Enabled = false;
	SaveAndExitButton->Enabled = false;
  ReadHistoryButton->Enabled = false;
	ThreeDDiscriminationExtractButton->Enabled = false;
	SetThresholdBtn->Enabled = false;
  GetThreeDInfoButton->Enabled = false;
	ImageSelectActiveSW = 0;
	for (int i = 1000; i >= 370; i -= 30)
	{
		Panel2->Left = i;
		Sleep(5);
	}
	Panel2->BringToFront();
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn24Click(TObject *Sender)
{
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox23->Visible = false;
	Panel2->Visible = false;
	BitBtn6->Visible = false;
	SpeedButton6->Click();
	Panel16->Visible = false;
	//    TrackBar2->Position = 5;
	//    TrackBar1->Position = 5;
	//    PrintExtractEndButton->Visible = false;
	//    EtcExtract->Visible = false;
	GroupBox19->Visible = true;
	SelectedImageN[0] = 0;
	SelectedImageN[1] = 0;
	SelectedWorkSW[0] = 0;
	SelectedWorkSW[1] = 0;
	ImageSelectActiveSW = 1;

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	Graphics::TBitmap *img2;
	img2 = new Graphics::TBitmap();
	if (SelectDisk == DISK1)
	{
		for (int i = 32; i < 32 + 30; i++)
		{
			ExtractImage(img1, i, SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img1);
			}

			ExtractImage(img2, i, SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img2);
			}

			img2->Width = img1->Width * 2;
			img2->Height = img1->Height;
			Byte *ptr;
			Byte *tr;
			for (int y = 0; y < img1->Height; y++)
			{
				ptr = (byte*)img1->ScanLine[y];
				tr = (byte*)img2->ScanLine[y];
				for (int x = 0; x < img1->Width * 2; x++)
				{
					tr[x] = ptr[x / 2];
				}
			}
			((TTntImage *)FindComponent("Image" + IntToStr(i)))->Picture->Bitmap->Assign(img2);
			((TTntImage *)FindComponent("Image" + IntToStr(i)))->Stretch = true;
			((TTntImage *)FindComponent("Image" + IntToStr(i)))->Refresh();
			Image1->Picture->Bitmap->Assign(img1);
		}
	}
	else
	{
		for (int i = 32; i < 32 + 30; i++)
		{
			ExtractImage(img1, i, SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img1);
			}

			ExtractImage(img2, i, SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img2);
			}

			img2->Width = img1->Width * 2;
			img2->Height = img1->Height;
			Byte *ptr;
			Byte *tr;
			for (int y = 0; y < img1->Height; y++)
			{
				ptr = (byte*)img1->ScanLine[y];
				tr = (byte*)img2->ScanLine[y];
				for (int x = 0; x < img1->Width * 2; x++)
				{
					tr[x] = ptr[x / 2];
				}
			}
			((TTntImage *)FindComponent("Image" + IntToStr(i)))->Picture->Bitmap->Assign(img2);
			((TTntImage *)FindComponent("Image" + IntToStr(i)))->Stretch = true;
			((TTntImage *)FindComponent("Image" + IntToStr(i)))->Refresh();
			Image1->Picture->Bitmap->Assign(img1);
		}
	}
	delete(img1);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn16Click(TObject *Sender)
{
	BitBtn16->Enabled = false;
	BitBtn22->Enabled = false;
	BitBtn23->Enabled = false;

	GroupBox23->Visible = true;
	SelectedWorkSW[0] = 0;
	SelectedWorkSW[1] = 0;

	Image21->Visible = false;
	Image22->Visible = false;
	Image23->Visible = false;
	Image28->Visible = false;

	SelectDisk = DISK1;

	for (int i = 980; i >= 130; i -= 50)
	{
		GroupBox23->Left = i;
		Sleep(5);
	}
	GroupBox23->BringToFront();

	if (TabletCharacter.discriminationDisplay_kind == PRINT)
	{
		if (TabletCharacter.tabletDivisionLineInfo == ONESIDE_DIVISION_LINE)
		{
			if (SelectedWorkSW[0] == 1)
			{
				BitBtn25->Enabled = true;
			}
			else
				BitBtn25->Enabled = false;
			BitBtn26->Enabled = false;
		}
		else if (TabletCharacter.tabletDivisionLineInfo == BOTHSIDE_DIVISION_LINE)
		{
			if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
			{
				BitBtn25->Enabled = true;
				BitBtn26->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
				BitBtn26->Enabled = false;
			}
		}
	}
	else
	{
		if (TabletCharacter.discriminationDisplay_num == ONE_FACE || TabletCharacter.discriminationDisplay_num == TWO_FACE_SAME)
		{
			if (SelectedWorkSW[0] == 1)
			{
				BitBtn25->Enabled = true;
			}
			else
				BitBtn25->Enabled = false;
			BitBtn26->Enabled = false;
		}
		else if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
		{
			if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
			{
				BitBtn25->Enabled = true;
				BitBtn26->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
				BitBtn26->Enabled = false;
			}
		}
	}


	setExtractedThreeDEngraveData();
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton6Click(
	TObject *Sender)
{
	SelectedFace = 0;
	SpeedButton6->Font->Color = clRed;
	SpeedButton7->Font->Color = clGray;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton7Click(
	TObject *Sender)
{
	if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF || TabletCharacter.tabletDivisionLineInfo == BOTHSIDE_DIVISION_LINE)
	{
		SelectedFace = 1;
		SpeedButton6->Font->Color = clGray;
		SpeedButton7->Font->Color = clRed;
	}
	else
	{
		ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_03);
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image32Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(32);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image33Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(33);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image34Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(34);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image35Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(35);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image36Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(36);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image37Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(37);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image38Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(38);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image39Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(39);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image40Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(40);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image41Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(41);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image42Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(42);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image43Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(43);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image44Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(44);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image45Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(45);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image46Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(46);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image47Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(47);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image48Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(48);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image49Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(49);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image50Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(50);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image51Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(51);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image52Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(52);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image53Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(53);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image54Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(54);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image55Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(55);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image56Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(56);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image57Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(57);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image58Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(58);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image59Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(59);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image60Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(60);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image61Click(TObject *Sender)
{
	ThreeDImageSelectDisplay(61);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn6Click(TObject *Sender)
{
	GroupBox19->Visible = false;
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;
	GroupBox23->Visible = true;
	Panel2->Visible = true;

	if (TabletCharacter.discriminationDisplay_kind == PRINT)
	{
		if (TabletCharacter.tabletDivisionLineInfo == ONESIDE_DIVISION_LINE)
		{
			if (SelectedWorkSW[0] == 1)
			{
				BitBtn25->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
			}

			BitBtn26->Enabled = false;
		}
		else if (TabletCharacter.tabletDivisionLineInfo == BOTHSIDE_DIVISION_LINE)
		{
			if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
			{
				BitBtn25->Enabled = true;
				BitBtn26->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
				BitBtn26->Enabled = false;
			}
		}
	}
	else
	{
		if (TabletCharacter.discriminationDisplay_num == ONE_FACE || TabletCharacter.discriminationDisplay_num == TWO_FACE_SAME)
		{
			if (SelectedWorkSW[0] == 1)
			{
				BitBtn25->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
			}

			BitBtn26->Enabled = false;
		}
		else if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
		{
			if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
			{
				BitBtn25->Enabled = true;
				BitBtn26->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
				BitBtn26->Enabled = false;
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn15Click(TObject *Sender)
{
	BitBtn16->Enabled = true;
	BitBtn22->Enabled = true;
	BitBtn23->Enabled = true;
	GroupBox23->Visible = false;
	SelectedWorkSW[0] = 0;
	SelectedWorkSW[1] = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn22Click(TObject *Sender)
{
	BitBtn16->Enabled = false;
	BitBtn22->Enabled = false;
	BitBtn23->Enabled = false;
	GroupBox23->Visible = true;

	Image21->Visible = false;
	Image22->Visible = false;
	Image23->Visible = false;
	Image28->Visible = false;
	SelectDisk = DISK2;
	SelectedWorkSW[0] = 0;
	SelectedWorkSW[1] = 0;
	for (int i = 980; i >= 130; i -= 50)
	{
		GroupBox23->Left = i;
		Sleep(5);
	}
	GroupBox23->BringToFront();

	if (TabletCharacter.discriminationDisplay_kind == PRINT)
	{
		if (TabletCharacter.tabletDivisionLineInfo == ONESIDE_DIVISION_LINE)
		{
			if (SelectedWorkSW[0] == 1)
			{
				BitBtn25->Enabled = true;
			}
			else
				BitBtn25->Enabled = false;
			BitBtn26->Enabled = false;
		}
		else if (TabletCharacter.tabletDivisionLineInfo == BOTHSIDE_DIVISION_LINE)
		{
			if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
			{
				BitBtn25->Enabled = true;
				BitBtn26->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
				BitBtn26->Enabled = false;
			}
		}
	}
	else
	{
		if (TabletCharacter.discriminationDisplay_num == ONE_FACE || TabletCharacter.discriminationDisplay_num == TWO_FACE_SAME)
		{
			if (SelectedWorkSW[0] == 1)
			{
				BitBtn25->Enabled = true;
			}
			else
				BitBtn25->Enabled = false;
			BitBtn26->Enabled = false;
		}
		else if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
		{
			if (SelectedWorkSW[0] == 1 && SelectedWorkSW[1] == 1)
			{
				BitBtn25->Enabled = true;
				BitBtn26->Enabled = true;
			}
			else
			{
				BitBtn25->Enabled = false;
				BitBtn26->Enabled = false;
			}
		}
	}
	setExtractedThreeDEngraveData();
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn23Click(TObject *Sender)
{
	ShapExtractButton->Enabled = true;
	DiscrimiationMarkExtract->Enabled = true;
	SaveAndExitButton->Enabled = true;
  ReadHistoryButton->Enabled = true;
	ThreeDDiscriminationExtractButton->Enabled = bThreeDDataExtraction;
	SetThresholdBtn->Enabled = true;
  GetThreeDInfoButton->Enabled = true;
	Panel2->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn25Click(TObject *Sender)
{
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox23->Visible = false;
	Panel2->Visible = false;
	BitBtn6->Visible = false;
	GroupBox25->Visible = true;
	GroupBox26->Visible = false;
	GroupBox27->Visible = false;
	GroupBox30->Visible = false;
	GroupBox31->Visible = false;

	BitBtn27->Visible = true;
	BitBtn29->Visible = false;
	BitBtn30->Visible = false;
	BitBtn31->Visible = false;
  OtherPrintSettingButton->Visible = false;
	Image23->Visible = true;
	SelectedFace = 0;
	SliceMaskSW = 0;
  OtherPrintSettingSW = 0;
	ManualCorrectSW = 0;
	Image29->Picture->Bitmap->Assign(SelectedImage1);
	Image29->Stretch = true;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn27Click(TObject *Sender)
{
  int cameraIndex;
  if (SelectedFace == 0)
  {
    cameraIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX;
  }
  else
  {
    cameraIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX;
  }

  CPBCommonVariableInitial();

	MakeTabletCharacterData(&ProductData, &TabletCharacter, &MachineParams);

  int SDNum;
  if (cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
    SDNum = SUCTION_DISK_NUM1;
  else
    SDNum = SUCTION_DISK_NUM2;

  SetUpDataTransFormForThreeD(FRONT_FACE_SPECIAL, SDNum);

	threeDPrintExtractMode = THREE_D_NORMAL_MODE;

  ProcessingModeGlobal = FIRST_STUDY_MODE;
  ThickErrorSW = 0;
	DefectSW = 0;
	PrintIsSW = 0;
	PrintMatchingResult.dataNumberWithMaxValue = -1;

  DataInitiate(THREED, cameraIndex);

  memcpy(&tempSourceData, &TabletSetupData, sizeof(TTabletSetupData));

  TabletSetupData.ImageCutStartX[cameraIndex - 1] = 10;
  TabletSetupData.ImageCutEndX[cameraIndex - 1] = MAX_IMAGE_WIDTH - 10;
  TabletSetupData.ImageCutStartY[cameraIndex - 1] = 10;
  TabletSetupData.ImageCutEndY[cameraIndex - 1] = MAX_IMAGE_HEIGHT - 10;

	Byte *ptr;
  if (SelectedFace == 0)
  {
    if (SelectedImage1->PixelFormat == pf8bit)
    {
      for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
      {
        ptr = (byte*)SelectedImage1->ScanLine[y];
        for (int x = 0; x < IMAGE_3D_WIDTH / 2; x++)
        {
          ThreeD_Data[y*HALF_MAX_IMAGE_WIDTH + x] = ptr[x];
        }
      }
    }
    else if (SelectedImage1->PixelFormat == pf24bit)
    {
      for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
      {
        ptr = (byte*)SelectedImage1->ScanLine[y];
        for (int x = 0; x < IMAGE_3D_WIDTH / 2; x++)
        {
          ThreeD_Data[y*HALF_MAX_IMAGE_WIDTH + x] = ptr[x * 3];
        }
      }
    }
  }
  else
  {
    if (SelectedImage2->PixelFormat == pf8bit)
    {
      for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
      {
        ptr = (byte*)SelectedImage2->ScanLine[y];
        for (int x = 0; x < IMAGE_3D_WIDTH / 2; x++)
        {
          ThreeD_Data[y*HALF_MAX_IMAGE_WIDTH + x] = ptr[x];
        }
      }
    }
    else if (SelectedImage2->PixelFormat == pf24bit)
    {
      for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
      {
        ptr = (byte*)SelectedImage2->ScanLine[y];
        for (int x = 0; x < IMAGE_3D_WIDTH / 2; x++)
        {
          ThreeD_Data[y*HALF_MAX_IMAGE_WIDTH + x] = ptr[x * 3];
        }
      }
    }
  }

  memset(ThreeD_Image, 0, MAX_IMAGE_WIDTH*MAX_IMAGE_HEIGHT);

  // half 사이즈 복원
	for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		for (int x = 0; x < HALF_MAX_IMAGE_WIDTH; x++)
		{
			int tempAddress = HALF_MAX_IMAGE_WIDTH * y + x;

      int value = ThreeD_Data[tempAddress];

      if(value)
      {
			  ThreeD_Image[MAX_IMAGE_WIDTH * y + x * 2 + 0] = value;
			  ThreeD_Image[MAX_IMAGE_WIDTH * y + x * 2 + 1] = value;
      }
		}
	}

  PreprocessingFor3D(cameraIndex);

  int shiftX, shiftY;
  shiftX = MAX_IMAGE_WIDTH / 2 - AdjustTabletCenterX;
  shiftY = MAX_IMAGE_HEIGHT / 2 - AdjustTabletCenterY;

  // oval, oblong, 정렬형 정제에 한하여 각인 rotation 매칭 시 범위 제한

  if(AdjustTabletCenterX && AdjustTabletCenterY)
  {
    if(ExecutiveSearchingRotationAngle)
    {
      int rotationAngle = ProtoTabletRotationAngle; // 반대 방향

      int xyCosValue = CosData[(rotationAngle + 720) % 720];
      int xySinValue = SinData[(rotationAngle + 720) % 720];

      int rotateX, rotateY;

      memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
      for(int y = 0; y < MAX_IMAGE_HEIGHT; y++)
      {
        for(int x = 0; x < MAX_IMAGE_WIDTH; x++)
        {
          int tempAddress = MAX_IMAGE_WIDTH * y + x;

          rotateX = ((xyCosValue * (x - AdjustTabletCenterX) - xySinValue * (y - AdjustTabletCenterY)) / 1024) + AdjustTabletCenterX;
          rotateY = ((xySinValue * (x - AdjustTabletCenterX) + xyCosValue * (y - AdjustTabletCenterY)) / 1024) + AdjustTabletCenterY;

          if(rotateX > 2 && rotateX < MAX_IMAGE_WIDTH - 2 && rotateY > 2 && rotateY < MAX_IMAGE_HEIGHT - 2)
          {
            if(RotationThreeDImage[MAX_IMAGE_WIDTH * rotateY + rotateX])
            {
              TempImage[MAX_IMAGE_WIDTH * y + x] = RotationThreeDImage[MAX_IMAGE_WIDTH * rotateY + rotateX];
            }
          }
        }
      }

      memcpy(RotationThreeDImage, TempImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
    }
  }

  // 보정된 영상에 대해 이미지 중앙으로 shift
  memcpy(TempImage, RotationThreeDImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  memset(RotationThreeDImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  for(int y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    for(int x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      int tempAddress = MAX_IMAGE_WIDTH * y + x;

      int height = TempImage[tempAddress];

      if(height)
      {
        int tempX = x + shiftX;
        int tempY = y + shiftY;

        if(tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
        {
          RotationThreeDImage[MAX_IMAGE_WIDTH * tempY + tempX] = height;
        }
      }
    }
  }

  memcpy(ShapeBinaryImage, RotationThreeDImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  memcpy(&TabletSetupData, &tempSourceData, sizeof(TTabletSetupData));

	ZoomOptionBoxFor3D->Visible = false;

	int zoomInOutROIWidth;
	int zoomInOutROIHeight;

	zoomInOutSize3D = 1;

	zoomInOutROIWidth = MAX_ZOOM_W_PIXEL_FOR3D / zoomInOutSize3D;
	zoomInOutROIHeight = MAX_ZOOM_H_PIXEL_FOR3D / zoomInOutSize3D;

	zoomROIX1For3D = 0;
	zoomROIY1For3D = 0;

	zoomROIX2For3D = zoomROIX1For3D + zoomInOutROIWidth;
	zoomROIY2For3D = zoomROIY1For3D + zoomInOutROIHeight;

	zoomInOutShiftX3D = 0;
	zoomInOutShiftY3D = 0;

	refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);

  Image62->Canvas->Font->Color = clRed;
  Image62->Canvas->Font->Size = 14;
  WCHAR TempString[100];
  wsprintfW(TempString, TABLETCHARACTEREXTRACTFORM_IMAGE_TEXT_02, GlobalTabletRotationYZAngle / 2);
  Image62->Canvas->TextOutW(20, 20, TempString);

	GroupBox26->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_06;
	GroupBox26->Visible = true;
	BitBtn27->Visible = true;
	BitBtn29->Visible = true;
	BitBtn30->Visible = false;
	BitBtn31->Visible = false;
  OtherPrintSettingButton->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn29Click(TObject *Sender)
{
	threeDPrintExtractMode = THREE_D_BINARY_EXTRACTION_MODE;

	int zoomInOutROIWidth;
	int zoomInOutROIHeight;

	zoomInOutSize3D = 1;

	zoomInOutROIWidth = MAX_ZOOM_W_PIXEL_FOR3D / zoomInOutSize3D;
	zoomInOutROIHeight = MAX_ZOOM_H_PIXEL_FOR3D / zoomInOutSize3D;

	zoomROIX1For3D = 0;
	zoomROIY1For3D = 0;

	zoomROIX2For3D = zoomROIX1For3D + zoomInOutROIWidth;
	zoomROIY2For3D = zoomROIY1For3D + zoomInOutROIHeight;

	zoomInOutShiftX3D = 0;
	zoomInOutShiftY3D = 0;

	Panel20->Color = clBlack;
	Panel21->Color = clBlack;

	BitBtn27->Visible = false;
	BitBtn29->Visible = false;
	BitBtn30->Visible = false;
	BitBtn31->Visible = false;
  OtherPrintSettingButton->Visible = false;

	GroupBox27->Visible = true;
	GroupBox26->Visible = true;
	//    GroupBox34->Visible = true;
	ManualCorrectSW = 1;
	ManualWorkAreaWidth = 10;
	Image67->Canvas->Brush->Style = bsSolid;
	Image67->Canvas->Brush->Color = clWhite;
	Image67->Canvas->Rectangle(0, 0, Image67->Width, Image67->Height);
	Image67->Canvas->Pen->Color = clRed;
	Image67->Canvas->Brush->Color = clRed;
	Image67->Canvas->Ellipse(Image67->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
	ThreeDPrintBinariztionResultViewSW = 1;
	RadioButton5->Checked = true;
	RadioButton6->Checked = false;
	ManualWorkKind = ERASE;
	SelectedDisplayColor = GREEN;
	noneSelectedDisplayColor1 = BLUE;
	noneSelectedDisplayColor2 = RED;
	SpeedButton8->Down = true;
	SpeedButton8->Font->Color = clRed;
	SpeedButton9->Font->Color = 0x555555;

	Panel15->Visible = false;
	ZoomOptionBoxFor3D->Visible = true;

	ThreeDPrintThreshold = 2;

	ExtractDentedArea(RotationThreeDImage, ExpectedThreeDPrintArea);

	ThreeDPrintDataBinarization();
	PrintBinaryDataDisplay();

	LoadZoomInOutNavigation3DImage();
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::PrintBinaryDataDisplay(void)
{
	GroupBox26->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_13;
	refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ThreeDPrintDataBinarization(void)
{
	int tempCount;
	unsigned char tempPrintBinarizationDataForThreeD[IMAGE_3D_HEIGHT*IMAGE_3D_WIDTH];
	memset(tempPrintBinarizationDataForThreeD, 0, IMAGE_3D_HEIGHT*IMAGE_3D_WIDTH);
	memset(PrintBinarizationDataForThreeD, 0, IMAGE_3D_HEIGHT*IMAGE_3D_WIDTH);
  memset(PrintBinarizationDataForThreeDSlicePrint, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);

	for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		for (int x = 0; x < IMAGE_3D_WIDTH; x++)
		{
			if (ExpectedThreeDPrintArea[IMAGE_3D_WIDTH*y + x] > ThreeDPrintThreshold)
			{
				PrintBinarizationDataForThreeD[IMAGE_3D_WIDTH*y + x] = 1;
				tempPrintBinarizationDataForThreeD[IMAGE_3D_WIDTH*y + x] = 1;
			}
		}
	}
	for (int y = 1; y < IMAGE_3D_HEIGHT - 1; y++)
	{
		for (int x = 1; x < IMAGE_3D_WIDTH - 1; x++)
		{
			if (tempPrintBinarizationDataForThreeD[IMAGE_3D_WIDTH*y + x] == 0)
			{
				tempCount = 0;
				for (int i = y - 1; i <= y + 1; i++)
				{
					for (int j = x - 1; j <= x + 1; j++)
					{
						if (tempPrintBinarizationDataForThreeD[IMAGE_3D_WIDTH*i + j])
						{
							tempCount++;
						}
					}
				}
				if (tempCount > 2)
					PrintBinarizationDataForThreeD[IMAGE_3D_WIDTH*y + x] = 1;
			}
		}
	}

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ExtractDentedArea(unsigned char *src, unsigned char *result)
{
	int startX, startY, endX, endY;
	int x, y, i, j;
	int tempAddress;
	int left;
	int right;
	int up;
	int down;
	int upleft;
	int upright;
	int downleft;
	int downright;
	int length;
	int maxHeight;
	int tempNeighborHeight[4];
	int n, l;
	int startL, endL;
	int tempCount;
	int tempDentedDepth;
	int lengthTable[10];

	startX = 20;
	endX = ImageWidth - 20;
	startY = 20;
	endY = ImageHeight - 20;
	lengthTable[0] = 4;
	lengthTable[1] = 10;
	lengthTable[2] = 15;
	lengthTable[3] = 30;
	lengthTable[4] = 45;
	lengthTable[5] = 45;
	lengthTable[6] = 60;

	if (TabletCharacter.CurvedSurfaceTablet == 0)
	{
		// 보통의 정제.
		startL = 0;
		endL = 4;
	}
	else
	{
		// 표면이 굴곡진 정제. 큰 모양의 변화를 검사하지 않음.
		startL = 0;
		endL = 1;
	}

	memset(result, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	memset(DentedArea, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	for (l = startL; l < endL; l++)
	{

		length = lengthTable[l];
		up = -ImageWidth * length;
		down = ImageWidth * length;
		left = -1 * length;
		right = 1 * length;
		upleft = (-ImageWidth - 1)*length;
		upright = (-ImageWidth + 1)*length;
		downleft = (ImageWidth - 1)*length;
		downright = (ImageWidth + 1)*length;

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				if (RotationThreeDImage[tempAddress])
				{
					maxHeight = 0;
					for (n = 0; n < 4; n++)
					{
						tempNeighborHeight[n] = 0;
					}
					if (src[tempAddress + up] && src[tempAddress + down])
					{
						tempNeighborHeight[0] = src[tempAddress + up] + src[tempAddress + down];
					}
					if (src[tempAddress + left] && src[tempAddress + right])
					{
						tempNeighborHeight[1] = RotationThreeDImage[tempAddress + left] + RotationThreeDImage[tempAddress + right];
					}
					if (src[tempAddress + upleft] && src[tempAddress + downright])
					{
						tempNeighborHeight[2] = src[tempAddress + upleft] + src[tempAddress + downright];
					}
					if (src[tempAddress + upright] && src[tempAddress + downleft])
					{
						tempNeighborHeight[3] = src[tempAddress + upright] + src[tempAddress + downleft];
					}
					for (n = 0; n < 4; n++)
					{
						if (tempNeighborHeight[n] / 2 > maxHeight)
						{
							maxHeight = tempNeighborHeight[n] / 2;
						}
					}
					if (maxHeight)
					{
						if (maxHeight - src[tempAddress] > 0)
						{
							if (maxHeight - src[tempAddress] > result[tempAddress])
							{
								result[tempAddress] = maxHeight - src[tempAddress];
								DentedArea[tempAddress] = maxHeight;
							}
						}
					}
				}
			}
		}
	}
	//채우기
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			if (result[MAX_IMAGE_WIDTH*y + x] == 0)
			{
				tempCount = 0;
				tempDentedDepth = 0;
				for (i = y - 1; i <= y + 1; i++)
				{
					for (j = x - 1; j <= x + 1; j++)
					{
						tempAddress = MAX_IMAGE_WIDTH * i + j;
						if (result[tempAddress])
						{
							tempCount++;
							tempDentedDepth += result[tempAddress];
						}
					}
				}
				if (tempCount >= 5)
				{
					result[MAX_IMAGE_WIDTH*y + x] = (tempDentedDepth * 1024 + 612) / tempCount / 1024;
				}
			}
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::DisplayGradation(int threshold)
{
	for (int i = 0; i < Image63->Width; i++)
	{
		Image63->Canvas->Pen->Color = 0xffffff - (100 * i / 350) * 256 * 256 - (100 * i / Image63->Width) * 256 - (50 * i / Image63->Width);
		Image63->Canvas->Pen->Width = 2;
		Image63->Canvas->MoveTo(i, 0);
		Image63->Canvas->LineTo(i, Image63->Height);
	}
	Image63->Canvas->Pen->Color = clBlack;
	Image63->Canvas->Pen->Width = 2;
	Image63->Canvas->MoveTo(threshold * 7, 0);
	Image63->Canvas->LineTo(threshold * 7, 50);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::Image68Click(TObject *Sender)
{
	threeDPrintExtractMode = THREE_D_BINARY_EXTRACTION_MODE;

	Panel15->Visible = true;
	ThreeDPrintThreshold--;
	DisplayGradation(ThreeDPrintThreshold);
	ExtractDentedArea(RotationThreeDImage, ExpectedThreeDPrintArea);
	ThreeDPrintDataBinarization();
	PrintBinaryDataDisplay();
	Panel15->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image69Click(TObject *Sender)
{
	threeDPrintExtractMode = THREE_D_BINARY_EXTRACTION_MODE;

	Panel15->Visible = true;
	ThreeDPrintThreshold++;
	DisplayGradation(ThreeDPrintThreshold);
	ExtractDentedArea(RotationThreeDImage, ExpectedThreeDPrintArea);
	ThreeDPrintDataBinarization();
	PrintBinaryDataDisplay();
	Panel15->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image63MouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	threeDPrintExtractMode = THREE_D_BINARY_EXTRACTION_MODE;

	ThreeDPrintThreshold = X / 7;
	DisplayGradation(ThreeDPrintThreshold);

	Panel15->Visible = true;
	ExtractDentedArea(RotationThreeDImage, ExpectedThreeDPrintArea);
	ThreeDPrintDataBinarization();
	PrintBinaryDataDisplay();
	Panel15->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn26Click(TObject *Sender)
{
	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox23->Visible = false;
	Panel2->Visible = false;
	BitBtn6->Visible = false;
	GroupBox25->Visible = true;
	GroupBox26->Visible = false;
	GroupBox27->Visible = false;
	GroupBox30->Visible = false;
	GroupBox31->Visible = false;

	BitBtn27->Visible = true;
	BitBtn29->Visible = false;
	BitBtn30->Visible = false;
	BitBtn31->Visible = false;
  OtherPrintSettingButton->Visible = false;

	Image28->Visible = true;
	ManualCorrectSW = 0;
	SliceMaskSW = 0;
  OtherPrintSettingSW = 0;
	SelectedFace = 1;
	Image29->Picture->Bitmap->Assign(SelectedImage2);
	Image29->Stretch = true;
}
//---------------------------------------------------------------------------
bool __fastcall TTabletCharacterExtractForm::PrintInformationCalculationForThreeD(void)
{
	unsigned char expansionData[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	int Pixel_N_Of_Label[MAX_LABEL_COUNT];
	int rX, rY;
	int tx, ty;
	int i, j;
	int n, m, k;
	short label_Image[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	int printCenterX, printCenterY;
	int tempCount;
	int r;
	int tempX, tempY;
	int transX, transY;

	int labelN;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = IMAGE_3D_WIDTH;
	img1->Height = IMAGE_3D_HEIGHT;
	img1->PixelFormat = pf24bit;

	Byte *ptr;
	memset(expansionData, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////평균 shape을 구하기 위해 임시로 에지 데이터와 각인을 제거한 3차원 shape데이터를 셋업데이터에 저장////
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	unsigned char tempSmallBinaryImage[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT / 4];
	int checkSW;

  int tabletCenterX, tabletCenterY;
  tabletCenterX = tabletCenterY = tempCount = 0;

  for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		for (int x = 0; x < IMAGE_3D_WIDTH; x++)
		{
      if(RotationThreeDImage[(IMAGE_3D_WIDTH)*(y)+x])
      {
        tabletCenterX += x;
        tabletCenterY += y;
        tempCount++;
      }
		}
	}

	for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		for (int x = 0; x < IMAGE_3D_WIDTH; x++)
		{
			tempSmallBinaryImage[(IMAGE_3D_WIDTH / 2)*(y / 2) + (x / 2)] = RotationThreeDImage[(IMAGE_3D_WIDTH)*(y)+x];
		}
	}

	if (SelectDisk == DISK1)
	{
		Tablet3DSetupData.Disk1FrontShapeEdgePointCount = 0;
		for (int y = 1; y < IMAGE_3D_HEIGHT / 2 - 1; y++)
		{
			for (int x = 1; x < IMAGE_3D_WIDTH / 2 - 1; x++)
			{
				if (tempSmallBinaryImage[(IMAGE_3D_WIDTH / 2)*y + x])
				{
					checkSW = 0;
					for (int i = y - 1; i <= y + 1; i++)
					{
						for (int j = x - 1; j <= x + 1; j++)
						{
							if (tempSmallBinaryImage[(IMAGE_3D_WIDTH / 2)*i + j] == 0)
							{
								checkSW = 1;
							}
						}
					}
					if (checkSW)
					{
						Tablet3DSetupData.Disk1FrontShapeEdgePoint[Tablet3DSetupData.Disk1FrontShapeEdgePointCount][0] = x * 2;//-IMAGE_3D_WIDTH/2+ProtoTabletCenterX;
						Tablet3DSetupData.Disk1FrontShapeEdgePoint[Tablet3DSetupData.Disk1FrontShapeEdgePointCount][1] = y * 2;//-IMAGE_3D_HEIGHT/2+ProtoTabletCenterY;
						Tablet3DSetupData.Disk1FrontShapeEdgePointCount++;
					}
				}
			}
		}
	}
	else
	{
		Tablet3DSetupData.Disk2FrontShapeEdgePointCount = 0;
		for (int y = 1; y < IMAGE_3D_HEIGHT / 2 - 1; y++)
		{
			for (int x = 1; x < IMAGE_3D_WIDTH / 2 - 1; x++)
			{
				if (tempSmallBinaryImage[(IMAGE_3D_WIDTH / 2)*y + x])
				{
					checkSW = 0;
					for (int i = y - 1; i <= y + 1; i++)
					{
						for (int j = x - 1; j <= x + 1; j++)
						{
							if (tempSmallBinaryImage[(IMAGE_3D_WIDTH / 2)*i + j] == 0)
							{
								checkSW = 1;
							}
						}
					}
					if (checkSW)
					{
						Tablet3DSetupData.Disk2FrontShapeEdgePoint[Tablet3DSetupData.Disk2FrontShapeEdgePointCount][0] = x * 2;
						Tablet3DSetupData.Disk2FrontShapeEdgePoint[Tablet3DSetupData.Disk2FrontShapeEdgePointCount][1] = y * 2;
						Tablet3DSetupData.Disk2FrontShapeEdgePointCount++;
					}
				}
			}
		}
	}

  int AvgPrintDepth, tmpCnt;
  AvgPrintDepth = tmpCnt = 0;
  for (int y = 0; y < MAX_IMAGE_HEIGHT; y++)
	{
		for (int x = 0; x < MAX_IMAGE_WIDTH; x++)
		{
			int tempAddress = MAX_IMAGE_WIDTH * y + x;

      if(PrintBinarizationDataForThreeD[tempAddress])
      {
        AvgPrintDepth += ExpectedThreeDPrintArea[tempAddress];
        tmpCnt++;
      }
		}
	}

  if(tmpCnt)
  {
    AvgPrintDepth /= tmpCnt;
  }

  if(tempCount)
  {
    // tablet center
    printCenterX = tabletCenterX / tempCount;
    printCenterY = tabletCenterY / tempCount;
  }
  else
  {
    printCenterX = MAX_IMAGE_WIDTH / 2;
    printCenterX = MAX_IMAGE_HEIGHT / 2;
  }

  if (TabletCharacter.discriminationDisplay_kind == STAMP || TabletCharacter.tabletDivisionLineInfo)
  {
    labelN = PrintLabelingForThreeDImage(PrintBinarizationDataForThreeD, label_Image, Pixel_N_Of_Label);
  }

  RotationAngleInSelectedImage = 0;

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	if (SelectedFace == 0)
	{
		if (SelectDisk == DISK1)
		{
      Tablet3DSetupData.PrintAverageDepth[0][0] = AvgPrintDepth;
			Tablet3DSetupData.Disk1printData1Count = 0;
			Tablet3DSetupData.Disk1slice_printData1Count = 0;

			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeD[y*IMAGE_3D_WIDTH + x])
					{
						if (Tablet3DSetupData.Disk1printData1Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_printData1[Tablet3DSetupData.Disk1printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_printData1[Tablet3DSetupData.Disk1printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeDSlicePrint[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk1slice_printData1Count < THREED_SLICE_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_slice_printData1[Tablet3DSetupData.Disk1slice_printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_slice_printData1[Tablet3DSetupData.Disk1slice_printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1slice_printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      memset(Tablet3DSetupData.printMaskData[0][0], 0, sizeof(short) * THREED_PRINT_MAX_LABEL_COUNT * PRINT_LABEL_DATA_SIZE);
			for (int n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
			{
				Tablet3DSetupData.printLabelDataCnt[0][0][n] = 0;
			}
			int tempLabelN;
			tempLabelN = 0;
			for (int n = 0; n < labelN; n++)
			{
				if (Pixel_N_Of_Label[n + 1] > 20)
				{
					for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
					{
						for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
						{
							if (label_Image[y*IMAGE_3D_WIDTH + x] == n + 1)
							{
								if (Tablet3DSetupData.printLabelDataCnt[0][0][tempLabelN] < PRINT_LABEL_DATA_SIZE)
								{
									Tablet3DSetupData.printLabelData[0][0][tempLabelN][Tablet3DSetupData.printLabelDataCnt[0][0][tempLabelN]][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
									Tablet3DSetupData.printLabelData[0][0][tempLabelN][Tablet3DSetupData.printLabelDataCnt[0][0][tempLabelN]][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
									Tablet3DSetupData.printLabelDataCnt[0][0][tempLabelN]++;
								}
								else
								{
									if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
									{
										tempLabelN++;
									}
									else
									{
										ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
										Disk1Print1ExtractUnusalSW = 1;
										return(0);
									}
								}
							}
						}
					}
					if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
					{
						tempLabelN++;
					}
					else
					{
						ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
						Disk1Print1ExtractUnusalSW = 1;
						return(0);
					}
				}
			}

			Disk1Print1ExtractUnusalSW = 0;

			Tablet3DSetupData.printLabelCount[0][0] = tempLabelN;
		}
		else
		{
      Tablet3DSetupData.PrintAverageDepth[1][0] = AvgPrintDepth;
			Tablet3DSetupData.Disk2printData1Count = 0;
			Tablet3DSetupData.Disk2slice_printData1Count = 0;
			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeD[y*IMAGE_3D_WIDTH + x])
					{
						if (Tablet3DSetupData.Disk2printData1Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk2position_printData1[Tablet3DSetupData.Disk2printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_printData1[Tablet3DSetupData.Disk2printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeDSlicePrint[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk2slice_printData1Count < THREED_SLICE_PRINT_DATA_SIZE)
						{

							Tablet3DSetupData.Disk2position_slice_printData1[Tablet3DSetupData.Disk2slice_printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_slice_printData1[Tablet3DSetupData.Disk2slice_printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2slice_printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      memset(Tablet3DSetupData.printMaskData[1][0], 0, sizeof(short) * THREED_PRINT_MAX_LABEL_COUNT * PRINT_LABEL_DATA_SIZE);
			for (int n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
			{
				Tablet3DSetupData.printLabelDataCnt[1][0][n] = 0;
			}
			int tempLabelN;
			tempLabelN = 0;
			for (int n = 0; n < labelN; n++)
			{
				if (Pixel_N_Of_Label[n + 1] > 20)
				{
					for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
					{
						for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
						{
							if (label_Image[y*IMAGE_3D_WIDTH + x] == n + 1)
							{
								if (Tablet3DSetupData.printLabelDataCnt[1][0][tempLabelN] < PRINT_LABEL_DATA_SIZE)
								{
									Tablet3DSetupData.printLabelData[1][0][tempLabelN][Tablet3DSetupData.printLabelDataCnt[1][0][tempLabelN]][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
									Tablet3DSetupData.printLabelData[1][0][tempLabelN][Tablet3DSetupData.printLabelDataCnt[1][0][tempLabelN]][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
									Tablet3DSetupData.printLabelDataCnt[1][0][tempLabelN]++;
								}
								else
								{
									if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
									{
										tempLabelN++;
									}
									else
									{
										ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
										Disk2Print1ExtractUnusalSW = 1;
										return(0);
									}
								}
							}
						}
					}
					if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
					{
						tempLabelN++;
					}
					else
					{
						ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
						Disk2Print1ExtractUnusalSW = 1;
						return(0);
					}
				}
			}

			Disk2Print1ExtractUnusalSW = 0;

			Tablet3DSetupData.printLabelCount[1][0] = tempLabelN;
		}

    memset(PrintBinarizationDataForThreeD, 0, IMAGE_3D_HEIGHT*IMAGE_3D_WIDTH);
		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_printData1[m][0];
				ty = Tablet3DSetupData.Disk1position_printData1[m][1];

        PrintBinarizationDataForThreeD[IMAGE_3D_WIDTH * ty + tx] = 1;

				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_printData1[m][0];
				ty = Tablet3DSetupData.Disk2position_printData1[m][1];

        PrintBinarizationDataForThreeD[IMAGE_3D_WIDTH * ty + tx] = 1;

				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}

		Image62->Picture->Bitmap->Assign(img1);
		Image62->Refresh();
		Image23->Picture->Bitmap->Assign(img1);
		Image23->Stretch = true;
		Image23->Refresh();
		delete(img1);
	}
	else
	{
		if (SelectDisk == DISK1)
		{
      Tablet3DSetupData.PrintAverageDepth[0][1] = AvgPrintDepth;
			Tablet3DSetupData.Disk1printData2Count = 0;
			Tablet3DSetupData.Disk1slice_printData2Count = 0;
			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeD[y*IMAGE_3D_WIDTH + x])
					{
						if (Tablet3DSetupData.Disk1printData2Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_printData2[Tablet3DSetupData.Disk1printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_printData2[Tablet3DSetupData.Disk1printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeDSlicePrint[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk1slice_printData2Count < THREED_SLICE_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_slice_printData2[Tablet3DSetupData.Disk1slice_printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_slice_printData2[Tablet3DSetupData.Disk1slice_printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1slice_printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}
		}
		else
		{
      Tablet3DSetupData.PrintAverageDepth[1][1] = AvgPrintDepth;
			Tablet3DSetupData.Disk2printData2Count = 0;
			Tablet3DSetupData.Disk2slice_printData2Count = 0;
			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeD[y*IMAGE_3D_WIDTH + x])
					{
						if (Tablet3DSetupData.Disk2printData2Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk2position_printData2[Tablet3DSetupData.Disk2printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_printData2[Tablet3DSetupData.Disk2printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (PrintBinarizationDataForThreeDSlicePrint[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk2slice_printData2Count < THREED_SLICE_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk2position_slice_printData2[Tablet3DSetupData.Disk2slice_printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_slice_printData2[Tablet3DSetupData.Disk2slice_printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2slice_printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}
		}

    memset(PrintBinarizationDataForThreeD, 0, IMAGE_3D_HEIGHT*IMAGE_3D_WIDTH);

		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_printData2[m][0];
				ty = Tablet3DSetupData.Disk1position_printData2[m][1];

        PrintBinarizationDataForThreeD[IMAGE_3D_WIDTH * ty + tx] = 1;

				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}

      memset(Tablet3DSetupData.printMaskData[0][1], 0, sizeof(short) * THREED_PRINT_MAX_LABEL_COUNT * PRINT_LABEL_DATA_SIZE);
			for (int n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
			{
				Tablet3DSetupData.printLabelDataCnt[0][1][n] = 0;
			}
			int tempLabelN;
			tempLabelN = 0;
			for (int n = 0; n < labelN; n++)
			{
				if (Pixel_N_Of_Label[n + 1] > 20)
				{
					for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
					{
						for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
						{
							if (label_Image[y*IMAGE_3D_WIDTH + x] == n + 1)
							{
								if (Tablet3DSetupData.printLabelDataCnt[0][1][tempLabelN] < PRINT_LABEL_DATA_SIZE)
								{
									Tablet3DSetupData.printLabelData[0][1][tempLabelN][Tablet3DSetupData.printLabelDataCnt[0][1][tempLabelN]][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
									Tablet3DSetupData.printLabelData[0][1][tempLabelN][Tablet3DSetupData.printLabelDataCnt[0][1][tempLabelN]][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
									Tablet3DSetupData.printLabelDataCnt[0][1][tempLabelN]++;
								}
								else
								{
									if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
									{
										tempLabelN++;
									}
									else
									{
										ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
										Disk1Print2ExtractUnusalSW = 1;
										return(0);
									}
								}
							}
						}
					}
					if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
					{
						tempLabelN++;
					}
					else
					{
						ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
						Disk1Print2ExtractUnusalSW = 1;
						return(0);
					}

				}
			}

			Disk1Print2ExtractUnusalSW = 0;

			Tablet3DSetupData.printLabelCount[0][1] = tempLabelN;
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_printData2[m][0];
				ty = Tablet3DSetupData.Disk2position_printData2[m][1];

        PrintBinarizationDataForThreeD[IMAGE_3D_WIDTH * ty + tx] = 1;

				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}

      memset(Tablet3DSetupData.printMaskData[1][1], 0, sizeof(short) * THREED_PRINT_MAX_LABEL_COUNT * PRINT_LABEL_DATA_SIZE);
			for (int n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
			{
				Tablet3DSetupData.printLabelDataCnt[1][1][n] = 0;
			}
			int tempLabelN;
			tempLabelN = 0;
			for (int n = 0; n < labelN; n++)
			{
				if (Pixel_N_Of_Label[n + 1] > 20)
				{
					for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
					{
						for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
						{
							if (label_Image[y*IMAGE_3D_WIDTH + x] == n + 1)
							{
								if (Tablet3DSetupData.printLabelDataCnt[1][1][tempLabelN] < PRINT_LABEL_DATA_SIZE)
								{
									Tablet3DSetupData.printLabelData[1][1][tempLabelN][Tablet3DSetupData.printLabelDataCnt[1][1][tempLabelN]][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
									Tablet3DSetupData.printLabelData[1][1][tempLabelN][Tablet3DSetupData.printLabelDataCnt[1][1][tempLabelN]][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
									Tablet3DSetupData.printLabelDataCnt[1][1][tempLabelN]++;
								}
								else
								{
									if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
									{
										tempLabelN++;
									}
									else
									{
										ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
										Disk2Print2ExtractUnusalSW = 1;
										return(0);
									}
								}
							}
						}
					}
					if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
					{
						tempLabelN++;
					}
					else
					{
						ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_01);
						Disk2Print2ExtractUnusalSW = 1;
						return(0);
					}
				}
			}

			Disk2Print2ExtractUnusalSW = 0;

			Tablet3DSetupData.printLabelCount[1][1] = tempLabelN;
		}

		Image62->Picture->Bitmap->Assign(img1);
		Image62->Refresh();
		Image28->Picture->Bitmap->Assign(img1);
		Image28->Stretch = true;
		Image28->Refresh();
		delete(img1);
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn28Click(TObject *Sender)
{
	PrintInformationCalculationForThreeD();
	GroupBox26->Caption = TABLETCHARACTEREXTRACTFORM_GROUPBOX_CAPTION_29;
	GroupBox27->Visible = false;

	ManualCorrectSW = 0;
	ThreeDPrintBinariztionResultViewSW = 0;
	BitBtn27->Visible = true;
	BitBtn29->Visible = true;
	BitBtn30->Visible = true;
	BitBtn31->Visible = true;

	ZoomOptionBoxFor3D->Visible = false;
	threeDPrintExtractMode = THREE_D_NONE_MODE;

	Panel20->Color = clBlack;
	Panel21->Color = clBlack;

	setExtractedThreeDEngraveData();

  if(TabletCharacter.tabletDivisionLineInfo == DIVISION_LINE_BOTH_SIDE)
  {
    // 분할선이 양면에 존재하는 경우에만 버튼 활성화
    OtherPrintSettingButton->Visible = true;
  }
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton8Click(
	TObject *Sender)
{
	ManualWorkKind = ERASE;
	SpeedButton8->Font->Color = clRed;
	SpeedButton9->Font->Color = 0x555555;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SpeedButton9Click(
	TObject *Sender)
{
	ManualWorkKind = DRAW;
	SpeedButton9->Font->Color = clRed;
	SpeedButton8->Font->Color = 0x555555;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image64Click(TObject *Sender)
{
	SelectedDisplayColor = RED;
	noneSelectedDisplayColor1 = GREEN;
	noneSelectedDisplayColor2 = BLUE;
	int shiftValue = (ScrollBar1->Position - 20) * 3;
	int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;

	DisplayPrintBinarizationManualAdjustResult(shiftValue, multipleValue);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image65Click(TObject *Sender)
{
	SelectedDisplayColor = GREEN;
	noneSelectedDisplayColor1 = BLUE;
	noneSelectedDisplayColor2 = RED;
	int shiftValue = (ScrollBar1->Position - 20) * 3;
	int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;

	DisplayPrintBinarizationManualAdjustResult(shiftValue, multipleValue);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image66Click(TObject *Sender)
{
	SelectedDisplayColor = BLUE;
	noneSelectedDisplayColor1 = GREEN;
	noneSelectedDisplayColor2 = RED;
	int shiftValue = (ScrollBar1->Position - 20) * 3;
	int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;

	DisplayPrintBinarizationManualAdjustResult(shiftValue, multipleValue);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::UpDown6Click(TObject *Sender,
	TUDBtnType Button)
{
	if (Button == 0)
	{
		ManualWorkAreaWidth++;
		Image67->Canvas->Brush->Style = bsSolid;
		Image67->Canvas->Brush->Color = clWhite;
		Image67->Canvas->Rectangle(0, 0, Image67->Width, Image67->Height);
		Image67->Canvas->Pen->Color = clRed;
		Image67->Canvas->Brush->Color = clRed;
		Image67->Canvas->Ellipse(Image67->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
	}
	else
	{
		ManualWorkAreaWidth--;
		if (ManualWorkAreaWidth < 1)
			ManualWorkAreaWidth = 1;
		Image67->Canvas->Brush->Style = bsSolid;
		Image67->Canvas->Brush->Color = clWhite;
		Image67->Canvas->Rectangle(0, 0, Image67->Width, Image67->Height);
		Image67->Canvas->Pen->Color = clRed;
		Image67->Canvas->Brush->Color = clRed;
		Image67->Canvas->Ellipse(Image67->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image67->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image62MouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 1;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image62MouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	Byte *ptr, *tr1, *tr2, *tr;
	if (ThreeDPrintBinariztionResultViewSW)
	{
		threeDPrintExtractMode = THREE_D_BINARY_REVISION_MODE;
		memset(tempRotationThreeDImage, 0, IMAGE_3D_WIDTH * IMAGE_3D_HEIGHT * 3);

		int shiftValue = (ScrollBar1->Position - 20) * 3;
		int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;

		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] > 0)
				{
					if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue > 255)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = 255;
					else if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue < 0)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = 0;
					else
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue;
					if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue > 255)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = 255;
					else if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue < 0)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = 0;
					else
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue;

					if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue > 255)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = 255;
					else if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue < 0)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = 0;
					else
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue;
				}
			}
		}

		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] > 0)
				{
					if (tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] * multipleValue / 10 > 255)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] * multipleValue / 10;
					else
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] * multipleValue / 10;

					if (tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] * multipleValue / 10 > 255)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] * multipleValue / 10;
					else
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] * multipleValue / 10;

					if (tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] * multipleValue / 10 > 255)
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] * multipleValue / 10;
					else
						tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] * multipleValue / 10;
				}
			}
		}

		if (ManualCorrectSW)
		{
			if (ImageDownSW)
			{
				if (ManualWorkKind == ERASE)
				{
					for (int y = Y - ManualWorkAreaWidth / 2; y <= Y + ManualWorkAreaWidth / 2; y++)
					{
						for (int x = X - ManualWorkAreaWidth / 2; x <= X + ManualWorkAreaWidth / 2; x++)
						{
              PrintBinarizationDataForThreeD[(y / zoomInOutSize3D + zoomROIY1For3D)*IMAGE_3D_WIDTH + (x / zoomInOutSize3D + zoomROIX1For3D)] = false;
						}
					}
				}
				else if (ManualWorkKind == DRAW)
				{
					for (int y = Y - ManualWorkAreaWidth / 2; y <= Y + ManualWorkAreaWidth / 2; y++)
					{
						for (int x = X - ManualWorkAreaWidth / 2; x <= X + ManualWorkAreaWidth / 2; x++)
						{
              if (RotationThreeDImage[(y / zoomInOutSize3D + zoomROIY1For3D)*IMAGE_3D_WIDTH + (x / zoomInOutSize3D + zoomROIX1For3D)] > 0)
              {
							  PrintBinarizationDataForThreeD[(y / zoomInOutSize3D + zoomROIY1For3D)*IMAGE_3D_WIDTH + (x / zoomInOutSize3D + zoomROIX1For3D)] = true;
              }
						}
					}
				}
			}
		}

		refreshZoomInTablet3DImage(tempRotationThreeDImage, threeDPrintExtractMode);

		Image62->Canvas->Pen->Color = clBlack;
		Image62->Canvas->Brush->Style = bsClear;
		if (ManualCorrectSW)
			Image62->Canvas->Rectangle(X - ManualWorkAreaWidth / 2, Y - ManualWorkAreaWidth / 2, X + ManualWorkAreaWidth / 2, Y + ManualWorkAreaWidth / 2);
		Image62->Refresh();
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image62MouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 0;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::GroupBox24Click(
	TObject *Sender)
{
	/*
	Byte *ptr,*tr;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	Graphics::TBitmap *img2;
	img2 = new Graphics::TBitmap();
	int shiftValue = (ScrollBar3->Position-5)*10;
	int multipleValue = 10+(ScrollBar4->Position-5)*2;
	for(int i = 32; i < 32+30; i++)
	{
	AnsiString str;
	str =StoredImageFolder+ IntToStr(i)+"_2.bmp" ;
	img1->LoadFromFile(str);
	img2->LoadFromFile(str);
	for(int y = 0 ; y < IMAGE_3D_HEIGHT; y++)
	{
	ptr = (byte*) img1->ScanLine[y];
	tr = (byte*) img2->ScanLine[y];
	for(int x = 0  ;x < IMAGE_3D_WIDTH ;x++)
	{
	if(ptr[3*x] > 10)
	{
	if(ptr[3*x] + shiftValue > 255)
	tr[3*x] = 255;
	else if(ptr[3*x] + shiftValue < 0)
	tr[3*x] = 0;
	else
	tr[3*x] = ptr[3*x] + shiftValue;
	if(ptr[3*x+1] + shiftValue> 255)
	tr[3*x+1] = 255;
	else if(ptr[3*x+1] +shiftValue < 0)
	tr[3*x+1] = 0;
	else
	tr[3*x+1] = ptr[3*x+1] + shiftValue;
	if(ptr[3*x+2] + shiftValue > 255)
	tr[3*x+2] = 255;
	else if(ptr[3*x+2] + shiftValue < 0)
	tr[3*x+2] = 0;
	else
	tr[3*x+2] = ptr[3*x+2] + shiftValue;
	}
	}
	}
	for(int y = 0 ; y < IMAGE_3D_HEIGHT; y++)
	{
	tr = (byte*) img2->ScanLine[y];
	for(int x = 0  ;x < IMAGE_3D_WIDTH ;x++)
	{
	if(tr[3*x] > 10)
	{
	if(tr[3*x]*multipleValue/10 > 255)
	tr[3*x] = tr[3*x]*multipleValue/10;
	else
	tr[3*x] = tr[3*x]*multipleValue/10;
	if(tr[3*x+1]*multipleValue/10 > 255)
	tr[3*x+1] = tr[3*x+1]*multipleValue/10;
	else
	tr[3*x+1] = tr[3*x+1]*multipleValue/10;
	if(tr[3*x+2]*multipleValue/10 > 255)
	tr[3*x+2] = tr[3*x+2]*multipleValue/10;
	else
	tr[3*x+2] = tr[3*x+2]*multipleValue/10;
	}
	}
	}

	((TTntImage *)FindComponent("Image"+IntToStr(i)))->Picture->Bitmap->Assign(img2);
	((TTntImage *)FindComponent("Image"+IntToStr(i)))->Stretch = true;
	((TTntImage *)FindComponent("Image"+IntToStr(i)))->Refresh();
	//    Image1->Picture->Bitmap->Assign(img1);
	}
	delete(img1);
	delete(img2);
	*/
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ScrollBar4Change(
	TObject *Sender)
{
	Panel16->Visible = true;

	Byte *ptr, *tr;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	Graphics::TBitmap *img2;
	img2 = new Graphics::TBitmap();
	int shiftValue = (ScrollBar3->Position - 5) * 10;
	int multipleValue = 10 + (ScrollBar4->Position - 5) * 2;
	for (int i = 32; i < 32 + 30; i++)
	{
		ProgressBar3->Position = 100 * (i - 32) / 30;
		AnsiString str;
		if (SelectDisk == DISK1)
		{
			ExtractImage(img1, i, SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img1);
			}

			ExtractImage(img2, i, SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img2);
			}
		}
		else
		{
			ExtractImage(img1, i, SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img1);
			}

			ExtractImage(img2, i, SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img2);
			}
		}
		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			tr = (byte*)img2->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (ptr[x] > 10)
				{
					if (ptr[x] + shiftValue > 255)
						tr[x] = 255;
					else if (ptr[x] + shiftValue < 0)
						tr[x] = 0;
					else
						tr[x] = ptr[x] + shiftValue;
				}
			}
		}
		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			tr = (byte*)img2->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (tr[x] > 10)
				{
					if (tr[x] * multipleValue / 10 > 255)
						tr[x] = tr[x] * multipleValue / 10;
					else
						tr[x] = tr[x] * multipleValue / 10;
				}
			}
		}

		((TTntImage *)FindComponent("Image" + IntToStr(i)))->Picture->Bitmap->Assign(img2);
		((TTntImage *)FindComponent("Image" + IntToStr(i)))->Stretch = true;
		((TTntImage *)FindComponent("Image" + IntToStr(i)))->Refresh();
		//  Image1->Picture->Bitmap->Assign(img2);
	}
	delete(img1);
	delete(img2);
	Panel16->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ScrollBar3Change(
	TObject *Sender)
{
	Panel16->Visible = true;

	Byte *ptr, *tr;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	Graphics::TBitmap *img2;
	img2 = new Graphics::TBitmap();

	int shiftValue = (ScrollBar3->Position - 5) * 10;
	int multipleValue = 10 + (ScrollBar4->Position - 5) * 2;
	for (int i = 32; i < 32 + 30; i++)
	{
		ProgressBar3->Position = 100 * (i - 32) / 30;
		AnsiString str;

		if (SelectDisk == DISK1)
		{
			ExtractImage(img1, i, SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img1);
			}

			ExtractImage(img2, i, SD1_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img2);
			}
		}
		else
		{
			ExtractImage(img1, i, SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1 ], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img1);
			}

			ExtractImage(img2, i, SD2_3D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

			if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(img2);
			}
		}

		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			tr = (byte*)img2->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (ptr[x] > 10)
				{
					if (ptr[x] + shiftValue > 255)
						tr[x] = 255;
					else if (ptr[x] + shiftValue < 0)
						tr[x] = 0;
					else
						tr[x] = ptr[x] + shiftValue;
				}
			}
		}
		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			tr = (byte*)img2->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (tr[x] > 10)
				{
					if (tr[x] * multipleValue / 10 > 255)
						tr[x] = tr[x] * multipleValue / 10;
					else
						tr[x] = tr[x] * multipleValue / 10;

				}
			}
		}

		((TTntImage *)FindComponent("Image" + IntToStr(i)))->Picture->Bitmap->Assign(img2);
		((TTntImage *)FindComponent("Image" + IntToStr(i)))->Stretch = true;
		((TTntImage *)FindComponent("Image" + IntToStr(i)))->Refresh();
		//  Image1->Picture->Bitmap->Assign(img2);
	}
	delete(img1);
	delete(img2);
	Panel16->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::DisplayPrintBinarizationManualAdjustResult(int shiftValue, int multipleValue)
{
	memset(tempRotationThreeDImage, 0, IMAGE_3D_WIDTH * IMAGE_3D_HEIGHT * 3);

	for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		for (int x = 0; x < IMAGE_3D_WIDTH; x++)
		{
			if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] > 0)
			{
				if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue > 255)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = 255;
				else if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue < 0)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = 0;
				else
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue;
				if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue > 255)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = 255;
				else if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue < 0)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = 0;
				else
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue;

				if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue > 255)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = 255;
				else if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue < 0)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = 0;
				else
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = RotationThreeDImage[IMAGE_3D_WIDTH*y + x] + shiftValue;
			}
		}
	}

	for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		for (int x = 0; x < IMAGE_3D_WIDTH; x++)
		{
			if (RotationThreeDImage[IMAGE_3D_WIDTH*y + x] > 0)
			{
				if (tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] * multipleValue / 10 > 255)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] * multipleValue / 10;
				else
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 0] * multipleValue / 10;

				if (tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] * multipleValue / 10 > 255)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] * multipleValue / 10;
				else
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 1] * multipleValue / 10;

				if (tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] * multipleValue / 10 > 255)
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] * multipleValue / 10;
				else
					tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] = tempRotationThreeDImage[(IMAGE_3D_WIDTH*y + x) * 3 + 2] * multipleValue / 10;
			}
		}
	}

	refreshZoomInTablet3DImage(tempRotationThreeDImage, threeDPrintExtractMode);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ScrollBar1Change(
	TObject *Sender)
{
	int shiftValue = (ScrollBar1->Position - 20) * 3;
	int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;

	DisplayPrintBinarizationManualAdjustResult(shiftValue, multipleValue);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ScrollBar2Change(
	TObject *Sender)
{
	int shiftValue = (ScrollBar1->Position - 20) * 3;
	int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;
	DisplayPrintBinarizationManualAdjustResult(shiftValue, multipleValue);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::RadioButton5Click(
	TObject *Sender)
{
	ThreeDPrintBinariztionResultViewSW = 1;
	RadioButton5->Checked = true;
	RadioButton6->Checked = false;
	int shiftValue = (ScrollBar1->Position - 20) * 3;
	int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;
	DisplayPrintBinarizationManualAdjustResult(shiftValue, multipleValue);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::RadioButton6Click(
	TObject *Sender)
{
	ThreeDPrintBinariztionResultViewSW = 0;
	RadioButton5->Checked = false;
	RadioButton6->Checked = true;
	int shiftValue = (ScrollBar1->Position - 20) * 3;
	int multipleValue = 10 + (ScrollBar2->Position - 10) * 2;
	DisplayPrintBinarizationManualAdjustResult(shiftValue, multipleValue);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn30Click(TObject *Sender)
{
	GroupBox26->Visible = false;
	GroupBox30->Visible = true;
	GroupBox31->Visible = true;
	BitBtn27->Visible = false;
	BitBtn29->Visible = false;
	BitBtn30->Visible = false;
	BitBtn31->Visible = false;
  OtherPrintSettingButton->Visible = false;
	ZoomOptionBoxFor3D->Visible = false;
	Image70->Canvas->Brush->Style = bsSolid;
	Image70->Canvas->Brush->Color = clWhite;
	Image70->Canvas->Rectangle(0, 0, Image70->Width, Image70->Height);
	Image70->Canvas->Pen->Color = clRed;
	Image70->Canvas->Brush->Color = clRed;
	Image70->Canvas->Ellipse(Image70->Width / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Width / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5));

	SliceMaskSW = 1;
	DrawMaskWidth = 10;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;
	int tx, ty;
	if (SelectedFace == 0)
	{
		memset(PrintBinarizationDataForThreeDSlicePrint, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_printData1[m][0];
				ty = Tablet3DSetupData.Disk1position_printData1[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				PrintBinarizationDataForThreeDSlicePrint[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_printData1[m][0];
				ty = Tablet3DSetupData.Disk2position_printData1[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				PrintBinarizationDataForThreeDSlicePrint[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
	}
	else if (SelectedFace == 1)
	{
		memset(Print1BinarizationDataForSlicePrint, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_printData2[m][0];
				ty = Tablet3DSetupData.Disk1position_printData2[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				PrintBinarizationDataForThreeDSlicePrint[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_printData2[m][0];
				ty = Tablet3DSetupData.Disk2position_printData2[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				PrintBinarizationDataForThreeDSlicePrint[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}

	}
	Image71->Picture->Bitmap->Assign(img1);
	Image71->Refresh();
	delete(img1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::UpDown7Click(TObject *Sender,
	TUDBtnType Button)
{
	if (Button == 0)
	{
		DrawMaskWidth++;
		Image70->Canvas->Brush->Style = bsSolid;
		Image70->Canvas->Brush->Color = clWhite;
		Image70->Canvas->Rectangle(0, 0, Image70->Width, Image70->Height);
		Image70->Canvas->Pen->Color = clRed;
		Image70->Canvas->Brush->Color = clRed;
		Image70->Canvas->Ellipse(Image70->Width / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Width / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5));
	}
	else
	{
		DrawMaskWidth--;
		if (DrawMaskWidth < 1)
			DrawMaskWidth = 1;
		Image70->Canvas->Brush->Style = bsSolid;
		Image70->Canvas->Brush->Color = clWhite;
		Image70->Canvas->Rectangle(0, 0, Image70->Width, Image70->Height);
		Image70->Canvas->Pen->Color = clRed;
		Image70->Canvas->Brush->Color = clRed;
		Image70->Canvas->Ellipse(Image70->Width / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Width / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5));
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn33Click(TObject *Sender)
{
	if(SliceMaskSW)
  {
	  SliceMaskSW = 0;
    PrintInformationCalculationForThreeD();
    BitBtn30->Visible = true;
  }

  if(OtherPrintSettingSW)
  {
    OtherPrintSettingSW = 0;
    OtherFacePrintInformationCalculationForThreeD();
    BitBtn30->Visible = false;
  }

	GroupBox30->Visible = false;
	GroupBox31->Visible = false;
	BitBtn27->Visible = true;
	BitBtn29->Visible = true;
	BitBtn31->Visible = true;

  if(TabletCharacter.tabletDivisionLineInfo == DIVISION_LINE_BOTH_SIDE)
  {
    // 분할선이 양면에 존재하는 경우에만 버튼 활성화
    OtherPrintSettingButton->Visible = true;
  }
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::BitBtn32Click(TObject *Sender)
{
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = IMAGE_3D_WIDTH;
	img1->Height = IMAGE_3D_HEIGHT;
	img1->PixelFormat = pf24bit;
	Byte *ptr;

  if(SliceMaskSW)
  {
    for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
    {
      ptr = (byte*)img1->ScanLine[y];
      for (int x = 0; x < IMAGE_3D_WIDTH; x++)
      {
        if (PrintBinarizationDataForThreeDSlicePrint[y*IMAGE_3D_WIDTH + x])
        {
          ptr[3 * x] = 0;
          ptr[3 * x + 1] = 0;
          ptr[3 * x + 2] = 0;
        }
        else
        {
          ptr[3 * x] = 255;
          ptr[3 * x + 1] = 255;
          ptr[3 * x + 2] = 255;
        }
      }
    }

    for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
    {
      for (int x = 0; x < IMAGE_3D_WIDTH; x++)
      {
        if (PrintBinarizationDataForThreeDSlicePrint[(y)*IMAGE_3D_WIDTH + (x)] == 2)
          PrintBinarizationDataForThreeDSlicePrint[(y)*IMAGE_3D_WIDTH + (x)] = 1;
      }
    }
  }
  else if(OtherPrintSettingSW)
  {
    if (SelectedFace == 0)
    {
      memset(OhterFacePrintBinaryData, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
      if (SelectDisk == DISK1)
      {
        for (int m = 0; m < Tablet3DSetupData.Disk1printData1Count; m++)
        {
          int tx = Tablet3DSetupData.Disk1position_printData1[m][0];
          int ty = Tablet3DSetupData.Disk1position_printData1[m][1];
          ptr = (byte*)img1->ScanLine[ty];
          OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
          ptr[3 * tx] = 0;
          ptr[3 * tx + 1] = 0;
          ptr[3 * tx + 2] = 0;
        }
      }
      else
      {
        for (int m = 0; m < Tablet3DSetupData.Disk2printData1Count; m++)
        {
          int tx = Tablet3DSetupData.Disk2position_printData1[m][0];
          int ty = Tablet3DSetupData.Disk2position_printData1[m][1];
          ptr = (byte*)img1->ScanLine[ty];
          OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
          ptr[3 * tx] = 0;
          ptr[3 * tx + 1] = 0;
          ptr[3 * tx + 2] = 0;
        }
      }
    }
    else if (SelectedFace == 1)
    {
      memset(OhterFacePrintBinaryData, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
      if (SelectDisk == DISK1)
      {
        for (int m = 0; m < Tablet3DSetupData.Disk1printData2Count; m++)
        {
          int tx = Tablet3DSetupData.Disk1position_printData2[m][0];
          int ty = Tablet3DSetupData.Disk1position_printData2[m][1];
          ptr = (byte*)img1->ScanLine[ty];
          OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
          ptr[3 * tx] = 0;
          ptr[3 * tx + 1] = 0;
          ptr[3 * tx + 2] = 0;
        }
      }
      else
      {
        for (int m = 0; m < Tablet3DSetupData.Disk2printData2Count; m++)
        {
          int tx = Tablet3DSetupData.Disk2position_printData2[m][0];
          int ty = Tablet3DSetupData.Disk2position_printData2[m][1];
          ptr = (byte*)img1->ScanLine[ty];
          OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
          ptr[3 * tx] = 0;
          ptr[3 * tx + 1] = 0;
          ptr[3 * tx + 2] = 0;
        }
      }
    }
  }

	Image71->Picture->Bitmap->Assign(img1);
	Image71->Repaint();

	delete(img1);

}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image71MouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 1;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image71MouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	ImageDownSW = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::Image71MouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	Byte *ptr, *tr1, *tr2, *tr;
	if (SliceMaskSW)
	{
		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		img1->Width = IMAGE_3D_WIDTH;
		img1->Height = IMAGE_3D_HEIGHT;
		img1->PixelFormat = pf24bit;
		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (PrintBinarizationDataForThreeDSlicePrint[y*IMAGE_3D_WIDTH + x])
				{
					ptr[3 * x] = 0;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 2] = 0;
				}
				else
				{
					ptr[3 * x] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}

		if (ImageDownSW)
		{
			for (int y = Y - DrawMaskWidth / 2; y <= Y + DrawMaskWidth / 2; y++)
			{
				for (int x = X - DrawMaskWidth / 2; x <= X + DrawMaskWidth / 2; x++)
				{
					if (PrintBinarizationDataForThreeDSlicePrint[(y)*IMAGE_3D_WIDTH + (x)])
						PrintBinarizationDataForThreeDSlicePrint[(y)*IMAGE_3D_WIDTH + (x)] = 2;
				}
			}
		}
		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (PrintBinarizationDataForThreeDSlicePrint[(y)*IMAGE_3D_WIDTH + (x)] == 2)
				{
					ptr[3 * x + 2] = 255;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 0] = 0;
				}
			}
		}
		Image71->Picture->Bitmap->Assign(img1);
		Image71->Canvas->Pen->Color = clBlue;
		Image71->Canvas->Brush->Style = bsClear;
		Image71->Canvas->Rectangle(X - DrawMaskWidth / 2, Y - DrawMaskWidth / 2, X + DrawMaskWidth / 2, Y + DrawMaskWidth / 2);
		Image71->Repaint();
		delete(img1);
	}
  else if (OtherPrintSettingSW)
  {
    Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();
		img1->Width = IMAGE_3D_WIDTH;
		img1->Height = IMAGE_3D_HEIGHT;
		img1->PixelFormat = pf24bit;
		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (OhterFacePrintBinaryData[y*IMAGE_3D_WIDTH + x])
				{
					ptr[3 * x] = 0;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 2] = 0;
				}
				else
				{
					ptr[3 * x] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}

		if (ImageDownSW)
		{
			for (int y = Y - DrawMaskWidth / 2; y <= Y + DrawMaskWidth / 2; y++)
			{
				for (int x = X - DrawMaskWidth / 2; x <= X + DrawMaskWidth / 2; x++)
				{
					if (OhterFacePrintBinaryData[(y)*IMAGE_3D_WIDTH + (x)])
						OhterFacePrintBinaryData[(y)*IMAGE_3D_WIDTH + (x)] = 2;
				}
			}
		}
		for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < IMAGE_3D_WIDTH; x++)
			{
				if (OhterFacePrintBinaryData[(y)*IMAGE_3D_WIDTH + (x)] == 2)
				{
					ptr[3 * x + 2] = 255;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 0] = 0;
				}
			}
		}
		Image71->Picture->Bitmap->Assign(img1);
		Image71->Canvas->Pen->Color = clBlue;
		Image71->Canvas->Brush->Style = bsClear;
		Image71->Canvas->Rectangle(X - DrawMaskWidth / 2, Y - DrawMaskWidth / 2, X + DrawMaskWidth / 2, Y + DrawMaskWidth / 2);
		Image71->Repaint();
		delete(img1);
  }
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::BitBtn31Click(TObject *Sender)
{
	GroupBox25->Visible = false;
	GroupBox23->Visible = true;
	Panel2->Visible = true;
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;
	ZoomOptionBoxFor3D->Visible = false;
	threeDPrintExtractMode = THREE_D_NONE_MODE;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ExtractPrintColor()
{
	Byte *ptr;

	int count = 0;
	int PrintRColor = 0;
	int PrintGColor = 0;
	int PrintBColor = 0;

	for (int y = 0; y < MAX_IMAGE_HEIGHT; y++)
	{
		ptr = (Byte*)SelectedImage->ScanLine[y];
		for (int x = 0; x < MAX_IMAGE_WIDTH; x++)
		{
			if (PrintBinarizationData[y*ImageWidth + x])
			{
				PrintBColor += ptr[3 * x + 0];
				PrintGColor += ptr[3 * x + 1];
				PrintRColor += ptr[3 * x + 2];

				count++;
			}
		}
	}

	if (count != 0)
	{
		PrintBColor /= count;
		PrintGColor /= count;
		PrintRColor /= count;
	}

	TabletSetupData.PrintColor[SelectedFace][0] = PrintBColor;
	TabletSetupData.PrintColor[SelectedFace][1] = PrintGColor;
	TabletSetupData.PrintColor[SelectedFace][2] = PrintRColor;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::CalculateCutoffPrintThreshold(int Threshold)
{
	//2015-10-13 revision by moon
	//Threshold 계산 과정은 우선 정제 색상보다 인쇄가 어두운 경우에만 고려하도록 한다.

	Byte *ptr;

	int SelectedPixelR;
	int SelectedPixelG;
	int SelectedPixelB;
  int SelectedValue;

	int GrayLV;
	int tempPrintAreaCnt = 0;

  int selectedRGB = 1;
	if (TabletSetupData.protoStudyColorR != 0
		&& TabletSetupData.protoStudyColorG != 0
		&& TabletSetupData.protoStudyColorB != 0)
	{                                                                                                                                                                                                    
		if (TabletSetupData.protoStudyColorR > TabletSetupData.protoStudyColorG * 110 / 100)
		{
			if (TabletSetupData.protoStudyColorR > TabletSetupData.protoStudyColorB * 110 / 100)
			{
				selectedRGB = 2;
			}
		}
		if (TabletSetupData.protoStudyColorB > TabletSetupData.protoStudyColorG * 110 / 100)
		{
			if (TabletSetupData.protoStudyColorB > TabletSetupData.protoStudyColorR * 110 / 100)
			{
				selectedRGB = 0;
			}
		}
	}

	for (int y = 0; y < MAX_IMAGE_HEIGHT; y++)
	{
		ptr = (Byte*)SelectedImage->ScanLine[y];
		for (int x = 0; x < MAX_IMAGE_WIDTH; x++)
		{
			if (tempPrintBinarizationData[y*ImageWidth + x])
			{
        /*
				SelectedPixelB = ptr[3 * x + 0];
				SelectedPixelG = ptr[3 * x + 1];
				SelectedPixelR = ptr[3 * x + 2];

				GrayLV = (SelectedPixelB + SelectedPixelG + SelectedPixelR) / 3;
        */

        // 2021-04-21
        // gray value 고려방식에서 정제 most factor 고려방식으로 변경

        SelectedValue = ptr[3 * x + selectedRGB];

				if (SelectedValue < Threshold)
				{
					PrintBinarizationData[y*ImageWidth + x] = 1;
					tempPrintAreaCnt++;
				}
				else
					PrintBinarizationData[y*ImageWidth + x] = 0;

			}
		}
	}

	/*
	if(tempPrintAreaCnt != PrintAreaCnt)
	{
	PrintAreaCnt = tempPrintAreaCnt;
	tempUDPOS = Threshold;
	}
	else
	{
	ThresholdUpDown->Position = tempUDPOS;
	PrintTH->Caption = IntToStr(ThresholdUpDown->Position);
	}
	*/
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ThresholdUpDownClick(
	TObject *Sender, TUDBtnType Button)
{
	PrintTH->Caption = IntToStr(ThresholdUpDown->Position);

	TabletSetupData.PrintThreshold = ThresholdUpDown->Position;

	CalculateCutoffPrintThreshold(ThresholdUpDown->Position);
	UpdatePrintArea();
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::UpdatePrintArea()
{
	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 1);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 1);
	else
		refreshZoomInTabletImage(NULL, 1);

	Graphics::TBitmap *img2;
	img2 = new Graphics::TBitmap();
	img2->Width = ImageWidth;
	img2->Height = ImageHeight;
	img2->PixelFormat = pf24bit;

	Byte *ptr;

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img2->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			ptr[3 * x] = 0;
			ptr[3 * x + 1] = 0;
			ptr[3 * x + 2] = 0;
			if (PrintBinarizationData[y*ImageWidth + x])
			{
				ptr[3 * x + 1] = 255;
			}
		}
	}

	Image5->Picture->Bitmap->Assign(img2);
	Image5->Refresh();

	delete img2;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::shapeSelectionCancelBtnClick(
	TObject *Sender)
{
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;

	TabletShapeSelectGB->Visible = false;
}
//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::shapeSelectionOKBtnClick(
	TObject *Sender)
{
  BitBtn8->Visible = false;
	if (SelectedShapeImg == -1)
	{
    BitBtn8->Visible = true;
		ShowMessageW(NEW_ADD_STRING_53);
		return;
	}

	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	TabletShapeSelectGB->Visible = false;

	int startX, endX, startY, endY;

	startX = 1;
	endX = 640 - 1;
	startY = 1;
	endY = 480 - 1;

	ETC_Asymmetry_ShapeExtract(1, 40, startX, endX, startY, endY);

	GroupBox13->Visible = true;

  Sleep(20);

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	Byte *ptr;

	int tabletLength;
	int tabletWidth;
	int space;
	int rotationAngle;
	unsigned char *colorSourceImage;
	unsigned char *accumulateShapeImage1;
	unsigned char *accumulateShapeImage2;
	int tempX, tempY;
	int tempImageCaptureN;
	int meanColor[3]; //B,G,R
	int threshold;
	float uLength;

	// setup data initial
	memset(TabletSetupData.FrontshapeAreaData, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
	memset(TabletSetupData.FrontshapeAreaData2, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
	TabletSetupData.FrontShapeEdgePointCount = 0;
	TabletSetupData.FrontShapeEdgePointCount2 = 0;
	memset(TabletSetupData.FrontShapeEdgePoint, 0, sizeof(short) * 2000 * 3);
	memset(TabletSetupData.FrontShapeEdgePoint2, 0, sizeof(short) * 2000 * 3);
	// end

  Image19->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
  Image19->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
  Image19->Picture->Bitmap->PixelFormat = pf24bit;
	Image19->Canvas->Brush->Style = bsSolid;
	Image19->Canvas->Brush->Color = clBlack;
	Image19->Canvas->Rectangle(0, 0, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
  
  TntImage1->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
  TntImage1->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
  TntImage1->Picture->Bitmap->PixelFormat = pf24bit;
	TntImage1->Canvas->Brush->Style = bsSolid;
	TntImage1->Canvas->Brush->Color = clBlack;
	TntImage1->Canvas->Rectangle(0, 0, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);

	meanColor[0] = meanColor[1] = meanColor[2] = 0;
	tempImageCaptureN = CAPTURE_IMAGE_N;
	colorSourceImage = new unsigned char[3 * ImageWidth * ImageHeight];
	accumulateShapeImage1 = new unsigned char[ImageWidth * ImageHeight];
	accumulateShapeImage2 = new unsigned char[ImageWidth * ImageHeight];

	threshold = 40;

	memset(accumulateShapeImage1, 0, ImageWidth*ImageHeight);
	memset(accumulateShapeImage2, 0, ImageWidth*ImageHeight);
	for (int i = 1; i <= tempImageCaptureN; i++)
	{
    ProgressBar1->BorderWidth = 5;
		ProgressBar1->Brush->Color = 0x212130;
		ProgressBar1->Position = 100 * i / tempImageCaptureN;

    int cameraIndex;

		// SD1
    cameraIndex = SD1_2D_FRONT_FACE_CAMERA_INDEX;
		if (!ExtractImage(img1, i, cameraIndex, TabletSetupData.ImageOffSetSW[cameraIndex - 1], TabletSetupData.referenceImageForOffset[cameraIndex - 1], ProductData.SubSamplingMode)) continue;

		if (CameraMapInfo[cameraIndex - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
		{
			ReductionImageScale(img1);
		}

		Image1->Picture->Bitmap->Assign(img1);
		Image1->Refresh();

		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				*(colorSourceImage + (y*ImageWidth + x) * 3) = ptr[3 * x];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 1) = ptr[3 * x + 1];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 2) = ptr[3 * x + 2];

				*(ColorSrcImg + (y*ImageWidth + x) * 3) = ptr[3 * x];
				*(ColorSrcImg + (y*ImageWidth + x) * 3 + 1) = ptr[3 * x + 1];
				*(ColorSrcImg + (y*ImageWidth + x) * 3 + 2) = ptr[3 * x + 2];
			}
		}

		ShapeExtract(colorSourceImage, accumulateShapeImage1, 1, threshold, startX, endX, startY, endY, meanColor, cameraIndex);
    Application->ProcessMessages();
    
		// SD2
    cameraIndex = SD2_2D_FRONT_FACE_CAMERA_INDEX;
		if (!ExtractImage(img1, i, cameraIndex, TabletSetupData.ImageOffSetSW[cameraIndex - 1], TabletSetupData.referenceImageForOffset[cameraIndex - 1], ProductData.SubSamplingMode)) continue;

		if (CameraMapInfo[cameraIndex - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
		{
			ReductionImageScale(img1);
		}

		Image1->Picture->Bitmap->Assign(img1);
		Image1->Refresh();

		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				*(colorSourceImage + (y*ImageWidth + x) * 3) = ptr[3 * x];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 1) = ptr[3 * x + 1];
				*(colorSourceImage + (y*ImageWidth + x) * 3 + 2) = ptr[3 * x + 2];

				*(ColorSrcImg + (y*ImageWidth + x) * 3) = ptr[3 * x];
				*(ColorSrcImg + (y*ImageWidth + x) * 3 + 1) = ptr[3 * x + 1];
				*(ColorSrcImg + (y*ImageWidth + x) * 3 + 2) = ptr[3 * x + 2];
			}
		}

		ShapeExtract(colorSourceImage, accumulateShapeImage2, 1, threshold, startX, endX, startY, endY, meanColor, cameraIndex);
    Application->ProcessMessages();
	}

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			if (*(accumulateShapeImage1 + y * ImageWidth + x) > tempImageCaptureN * 0.8)  //확률 50%이상이면//
			{
				TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = NORMAL_INPECTION_AREA;

				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = *(accumulateShapeImage1 + y * ImageWidth + x) * 2;
				ptr[3 * x + 2] = *(accumulateShapeImage1 + y * ImageWidth + x) * 2;
			}
			else
			{
				TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = 0;

				*(accumulateShapeImage1 + y * ImageWidth + x) = 0;
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
		}
	}

	for (int y = 1; y < ImageHeight - 1; y++)
	{
		for (int x = 1; x < ImageWidth - 1; x++)
		{
			if (*(accumulateShapeImage1 + y * ImageWidth + x))
			{
				if (*(accumulateShapeImage1 + (y - 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
				else if (*(accumulateShapeImage1 + (y + 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
				else if (*(accumulateShapeImage1 + (y)*ImageWidth + x - 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
				else if (*(accumulateShapeImage1 + (y)*ImageWidth + x + 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][0] = x;
					TabletSetupData.FrontShapeEdgePoint[TabletSetupData.FrontShapeEdgePointCount][1] = y;
					TabletSetupData.FrontShapeEdgePointCount++;
				}
			}
		}
	}

	// uLength는 이미지 중심부와 위에서 구한 FrontShapeEdgePoint와의 거리를 의미한다.
	for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
	{
		tempX = TabletSetupData.FrontShapeEdgePoint[m][0];
		tempY = TabletSetupData.FrontShapeEdgePoint[m][1];
		uLength = sqrt((tempX - 320)*(tempX - 320) + (tempY - 240)*(tempY - 240));
		if (tempY - 240 >= 0) // Edge좌표가 Y축을 기준으로 이미지 중심부 아래에 위치한 좌표라면
		{
			TabletSetupData.FrontShapeEdgePoint[m][2] = acos(float(tempX - 320) / uLength)*180.0 / PI; // FrontShapeEdgePoint에 angle이 할당되는 이유가..
		}
		else
		{
			TabletSetupData.FrontShapeEdgePoint[m][2] = 360.0 - acos(float(tempX - 320) / uLength)*180.0 / PI;
		}
	}

	for (int r = 30; r >= 2; r--)
	{
		for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
		{
			tempX = TabletSetupData.FrontShapeEdgePoint[m][0];
			tempY = TabletSetupData.FrontShapeEdgePoint[m][1];
			for (int y = tempY - r; y <= tempY + r; y++)
			{
				for (int x = tempX - r; x <= tempX + r; x++)
				{
					if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) < (r + 1)*(r + 1))
					{
						if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) > (r - 1)*(r - 1))
						{
							if (TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)])
							{
								TabletSetupData.FrontshapeAreaData[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = r;
							}
						}
					}
				}
			}
		}
	}

	Image19->Picture->Bitmap->Assign(img1);
	Image19->Refresh();

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			if (*(accumulateShapeImage2 + y * ImageWidth + x) > tempImageCaptureN * 0.8)  //확률 50%이상이면//
			{
				TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = NORMAL_INPECTION_AREA;

				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = *(accumulateShapeImage2 + y * ImageWidth + x) * 2;
				ptr[3 * x + 2] = *(accumulateShapeImage2 + y * ImageWidth + x) * 2;
			}
			else
			{
				TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = 0;

				*(accumulateShapeImage2 + y * ImageWidth + x) = 0;
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
		}
	}

	for (int y = 1; y < ImageHeight - 1; y++)
	{
		for (int x = 1; x < ImageWidth - 1; x++)
		{
			if (*(accumulateShapeImage2 + y * ImageWidth + x))
			{
				if (*(accumulateShapeImage2 + (y - 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
				else if (*(accumulateShapeImage2 + (y + 1)*ImageWidth + x) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
				else if (*(accumulateShapeImage2 + (y)*ImageWidth + x - 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
				else if (*(accumulateShapeImage2 + (y)*ImageWidth + x + 1) == 0)
				{
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][0] = x;
					TabletSetupData.FrontShapeEdgePoint2[TabletSetupData.FrontShapeEdgePointCount2][1] = y;
					TabletSetupData.FrontShapeEdgePointCount2++;
				}
			}
		}
	}

	// uLength는 이미지 중심부와 위에서 구한 FrontShapeEdgePoint와의 거리를 의미한다.
	for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount2; m++)
	{
		tempX = TabletSetupData.FrontShapeEdgePoint2[m][0];
		tempY = TabletSetupData.FrontShapeEdgePoint2[m][1];
		uLength = sqrt((tempX - 320)*(tempX - 320) + (tempY - 240)*(tempY - 240));
		if (tempY - 240 >= 0) // Edge좌표가 Y축을 기준으로 이미지 중심부 아래에 위치한 좌표라면
		{
			TabletSetupData.FrontShapeEdgePoint2[m][2] = acos(float(tempX - 320) / uLength)*180.0 / PI; // FrontShapeEdgePoint에 angle이 할당되는 이유가..
		}
		else
		{
			TabletSetupData.FrontShapeEdgePoint2[m][2] = 360.0 - acos(float(tempX - 320) / uLength)*180.0 / PI;
		}
	}

	for (int r = 30; r >= 2; r--)
	{
		for (int m = 0; m < TabletSetupData.FrontShapeEdgePointCount2; m++)
		{
			tempX = TabletSetupData.FrontShapeEdgePoint2[m][0];
			tempY = TabletSetupData.FrontShapeEdgePoint2[m][1];
			for (int y = tempY - r; y <= tempY + r; y++)
			{
				for (int x = tempX - r; x <= tempX + r; x++)
				{
					if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) < (r + 1)*(r + 1))
					{
						if (((y - tempY)*(y - tempY) + (x - tempX)*(x - tempX)) > (r - 1)*(r - 1))
						{
							if (TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)])
							{
								TabletSetupData.FrontshapeAreaData2[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = r;
							}
						}
					}
				}
			}
		}
	}

	TntImage1->Picture->Bitmap->Assign(img1);
	TntImage1->Refresh();

	delete(img1);
	delete(colorSourceImage);
	delete(accumulateShapeImage1);
	delete(accumulateShapeImage2);

  BitBtn8->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::shapeSelectImage1Click(
	TObject *Sender)
{
	TTntImage *tempImage = (TTntImage*)Sender;
	int selectedImageIndex = tempImage->Tag;

	Graphics::TBitmap *shapeImg;
	shapeImg = new Graphics::TBitmap();

	if (SelectedShapeImg != -1)
	{
		if (ExtractImage(shapeImg, SelectedShapeImg, SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode))
		{
			if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
			{
				ReductionImageScale(shapeImg);
			}

			((TTntImage *)FindComponent("shapeSelectImage" + IntToStr(SelectedShapeImg)))->Picture->Bitmap->Assign(shapeImg);
		}
	}

	delete shapeImg;

	SelectedShapeImg = selectedImageIndex;

	((TTntImage *)FindComponent("shapeSelectImage" + IntToStr(SelectedShapeImg)))->Canvas->Pen->Color = clRed;
	((TTntImage *)FindComponent("shapeSelectImage" + IntToStr(SelectedShapeImg)))->Canvas->Pen->Width = 30;
	((TTntImage *)FindComponent("shapeSelectImage" + IntToStr(SelectedShapeImg)))->Canvas->Brush->Style = bsClear;
	((TTntImage *)FindComponent("shapeSelectImage" + IntToStr(SelectedShapeImg)))->Canvas->Rectangle(1, 1, 640 - 1, 480 - 1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ETC_Asymmetry_ShapeExtract(int rgb, int protoThreshold, int startX, int endX, int startY, int endY)
{
	int tempCenterX, tempCenterY;
	int tCnt;
	int edgePoint[2000][2];
	int edgePointCount = 0;
	int edgeCheckSW;
	bool breakSW;
	int range = 30;
	int uLength;
	int tempPosiX;
	int tempPosiY;
	int meanGrayForInnerEdgeLine[2000] = { 0, };
	int meanGrayCountForInnerEdgeLine[2000] = { 0, };
	int neighborRange = 40;
	int resultCenterX, resultCenterY;
	int cnt;
	int tempX, tempY;
	int smallSizeImagWidth;
	int maxLabelN;
	int imgCenterX, imgCenterY;
	int shiftX, shiftY;
	unsigned char smallSizeBinaryImage[(640 / 4)*(480 / 4)];  //19k

	short smallSizeLabelImage[(640 / 4)*(480 / 4)];  //38k  -> 2byte 변수로 선언한 이유는?
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	Byte *ptr;

	unsigned char *binarizationData;
	unsigned char *edgeNeighborData;
	unsigned char *tempData;
	unsigned char *expansionTempData;

	binarizationData = new unsigned char[ImageWidth*ImageHeight];
	edgeNeighborData = new unsigned char[ImageWidth*ImageHeight];
	tempData = new unsigned char[ImageWidth*ImageHeight];
	expansionTempData = new unsigned char[ImageWidth*ImageHeight];
	smallSizeImagWidth = ImageWidth / 4;

	if (ExtractImage(img1, SelectedShapeImg, SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode))
	{
		if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
		{
			ReductionImageScale(img1);
		}

		for (int y = 0; y < ImageHeight; y++)
		{
			ptr = (byte*)img1->ScanLine[y];
			for (int x = 0; x < ImageWidth; x++)
			{
				*(ColorSrcImg + (y*ImageWidth + x) * 3) = ptr[3 * x];
				*(ColorSrcImg + (y*ImageWidth + x) * 3 + 1) = ptr[3 * x + 1];
				*(ColorSrcImg + (y*ImageWidth + x) * 3 + 2) = ptr[3 * x + 2];
			}
		}
	}

	delete img1;

	for (int i = 0; i < ImageHeight; i++)
	{
		for (int j = 0; j < ImageWidth; j++)
		{
			*(binarizationData + ImageWidth * i + j) = 0;
			*(edgeNeighborData + ImageWidth * i + j) = 0;
			*(tempData + ImageWidth * i + j) = 0;
			*(expansionTempData + ImageWidth * i + j) = 0;
		}
	}

	memset(smallSizeBinaryImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeLabelImage, 0, (ImageWidth / 4)*(ImageHeight / 4) * 2);

	for (int y = startY; y < endY; y += 4)
	{
		for (int x = startX; x < endX; x += 4)
		{
      if (*(ColorSrcImg + (ImageWidth*y + x) * 3 + 1) > protoThreshold || *(ColorSrcImg + (ImageWidth*y + x) * 3 + 2) > protoThreshold
        || *(ColorSrcImg + (ImageWidth*y + x) * 3 + 2) - *(ColorSrcImg + (ImageWidth*y + x) * 3) > 30)
        smallSizeBinaryImage[smallSizeImagWidth*(y / 4) + x / 4] = 1;
		}
	}
	maxLabelN = LabellingForTabletImage(smallSizeLabelImage, smallSizeBinaryImage, startX / 4, endX / 4, startY / 4, endY / 4, ImageWidth / 4, ImageHeight / 4);

	for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
	{
		for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
		{
			if (smallSizeLabelImage[(y)*smallSizeImagWidth + (x)] == maxLabelN)
			{
				for (int i = y - 1; i <= y + 1; i++)
				{
					for (int j = x - 1; j <= x + 1; j++)
					{
						smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
					}
				}
			}
		}
	}
	tempCenterX = 0;
	tempCenterY = 0;
	tCnt = 0;
	int tempAddress;

	for (int y = startY; y < endY; y++)
	{
		for (int x = startX; x < endX; x++)
		{
			tempAddress = y * ImageWidth + x;
			if (smallSizeBinaryImage[(y / 4)*smallSizeImagWidth + (x / 4)] == 2)
			{
				if (*(ColorSrcImg + (ImageWidth*y + x) * 3 + 1) > protoThreshold || *(ColorSrcImg + (ImageWidth*y + x) * 3 + 2) > protoThreshold
					|| *(ColorSrcImg + (ImageWidth*y + x) * 3 + 2) - *(ColorSrcImg + (ImageWidth*y + x) * 3) > 30)
				{
					*(tempData + ImageWidth * y + x) = 1;
					tempCenterX += x;
					tempCenterY += y;
					tCnt++;
				}
			}
		}
	}
	if (tCnt)
	{
		tempCenterX = tempCenterX / tCnt;
		tempCenterY = tempCenterY / tCnt;
	}


	if (TabletCharacter.kind != SUGARCOATING)
	{
		breakSW = false;

		for (int i = startY; i < endY; i++)
		{
			for (int j = startX; j < endX; j++)
			{
				if (*(tempData + ImageWidth * i + j))
				{
					edgeCheckSW = 0;
					if (*(tempData + ImageWidth * (i + 1) + j) == 0)  edgeCheckSW = 1; // Up
					if (*(tempData + ImageWidth * (i - 1) + j) == 0)  edgeCheckSW = 1; // Down
					if (*(tempData + ImageWidth * (i)+j - 1) == 0)  edgeCheckSW = 1; // Left
					if (*(tempData + ImageWidth * (i)+j + 1) == 0)  edgeCheckSW = 1; // Right
					if (edgeCheckSW == 1)
					{
						edgePoint[edgePointCount][0] = j; // edgePoint는 x,y 좌표를 구분하기 위해 2차원 배열로 정의한다.
						edgePoint[edgePointCount][1] = i;
						edgePointCount++;
						if (edgePointCount >= 2000) // edge의 총 개수는 2000개로 제한해두었다.
						{
							breakSW = true;
							break;
						}
					}
				}
			}
			if (breakSW == true)
				break;
		}

		for (int n = 0; n < edgePointCount; n++)
		{
			uLength = (edgePoint[n][0] - tempCenterX)*(edgePoint[n][0] - tempCenterX)
				+ (edgePoint[n][1] - tempCenterY)*(edgePoint[n][1] - tempCenterY);
			uLength = sqrt(uLength + 1); // a^2 + b^2 = c^2

			for (int i = 0; i < range; i++) // range = 30, range가 의미하는 바는? -> 정제 테두리의 크기를 의미하는 것이 아닌가?
			{
				tempPosiX = (edgePoint[n][0] * (uLength - i) + tempCenterX * i) / uLength;
				tempPosiY = (edgePoint[n][1] * (uLength - i) + tempCenterY * i) / uLength;
				for (int m = tempPosiY - 1; m <= tempPosiY + 1; m++)
				{
					for (int n = tempPosiX - 1; n <= tempPosiX + 1; n++)
					{
						*(tempData + ImageWidth * (m)+n) = 0;
						if (*(edgeNeighborData + ImageWidth * (m)+n) != 2)
							*(edgeNeighborData + ImageWidth * (m)+n) = 1;
					}
				}
				if (i >= range - 3) // 30 - 3
				{
					*(edgeNeighborData + ImageWidth * (tempPosiY)+tempPosiX) = 2;
				}
			}
		}

		for (int n = 0; n < edgePointCount; n++)
		{
			uLength = (edgePoint[n][0] - tempCenterX)*(edgePoint[n][0] - tempCenterX)
				+ (edgePoint[n][1] - tempCenterY)*(edgePoint[n][1] - tempCenterY);
			if (uLength)
			{
				uLength = sqrt(uLength + 1);
				tempPosiX = (edgePoint[n][0] * (uLength - range) + tempCenterX * range) / uLength;
				tempPosiY = (edgePoint[n][1] * (uLength - range) + tempCenterY * range) / uLength;
				for (int i = tempPosiY - neighborRange; i <= tempPosiY + neighborRange; i++) // neighborRange = 40
				{
					for (int j = tempPosiX - neighborRange; j <= tempPosiX + neighborRange; j++)
					{
						if (i >= 1 && i < ImageHeight - 1 && j >= 1 && j < ImageWidth - 1)
						{
							if (*(edgeNeighborData + ImageWidth * (i)+j) == 2)
							{
								meanGrayForInnerEdgeLine[n] += *(ColorSrcImg + (ImageWidth*(i)+j) * 3 + rgb);
								meanGrayCountForInnerEdgeLine[n]++;
							}
						}
					}
				}
			}
			if (meanGrayCountForInnerEdgeLine[n])
				meanGrayForInnerEdgeLine[n] /= meanGrayCountForInnerEdgeLine[n];
		}

		for (int n = 0; n < edgePointCount; n++)
		{
			uLength = (edgePoint[n][0] - tempCenterX)*(edgePoint[n][0] - tempCenterX)
				+ (edgePoint[n][1] - tempCenterY)*(edgePoint[n][1] - tempCenterY);
			if (uLength)
			{
				uLength = sqrt(uLength);
				for (int i = 0; i < range; i++)
				{
					tempPosiX = (edgePoint[n][0] * (uLength - i) + tempCenterX * i) / uLength;
					tempPosiY = (edgePoint[n][1] * (uLength - i) + tempCenterY * i) / uLength;
					for (int y = tempPosiY - 1; y <= tempPosiY + 1; y++)
					{
						for (int x = tempPosiX - 1; x <= tempPosiX + 1; x++)
						{
							if (*(ColorSrcImg + (ImageWidth*(y)+x) * 3 + rgb) > meanGrayForInnerEdgeLine[n] * 2 / 3)
								*(tempData + ImageWidth * (y)+x) = 1;
						}
					}
				}
			}
		}
	}
	resultCenterX = 0;
	resultCenterY = 0;
	cnt = 0;

	for (int i = startY; i < endY; i++)
	{
		for (int j = startX; j < endX; j++)
		{
			if (*(tempData + ImageWidth * i + j))
			{
				*(expansionTempData + ImageWidth * (i)+j) = 1;
				resultCenterX += j;
				resultCenterY += i;
				cnt++;
			}
		}
	}

	if (cnt)
	{
		resultCenterX /= cnt;
		resultCenterY /= cnt;
	}

	// 이미지 중심점으로 쉬프트
	imgCenterX = ImageWidth / 2;
	imgCenterY = ImageHeight / 2;

	shiftX = imgCenterX - resultCenterX;
	shiftY = imgCenterY - resultCenterY;

	unsigned char tempShiftBinData[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];
	memset(tempShiftBinData, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	for (int i = startY; i < endY; i++)
	{
		for (int j = startX; j < endX; j++)
		{
			if (*(expansionTempData + ImageWidth * i + j))
			{
				tempX = j + shiftX;
				tempY = i + shiftY;

				if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
					tempShiftBinData[ImageWidth * tempY + tempX] = *(expansionTempData + ImageWidth * i + j);
			}
		}
	}

	memcpy(expansionTempData, tempShiftBinData, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	memset(ETC_FrontShapeEdgePoint, 0, sizeof(int) * 4000 * 2);
	ETC_FrontShapeEdgeCount = 0;

	//edge Data 추출
	breakSW = false;
	for (int i = startY; i < endY; i++)
	{
		for (int j = startX; j < endX; j++)
		{
			if (*(expansionTempData + ImageWidth * i + j))
			{
				edgeCheckSW = 0;
				if (*(expansionTempData + ImageWidth * (i + 2) + j) == 0)  edgeCheckSW = 1; // Up
				if (*(expansionTempData + ImageWidth * (i - 2) + j) == 0)  edgeCheckSW = 1; // Down
				if (*(expansionTempData + ImageWidth * (i)+j - 2) == 0)  edgeCheckSW = 1; // Left
				if (*(expansionTempData + ImageWidth * (i)+j + 2) == 0)  edgeCheckSW = 1; // Right
				if (edgeCheckSW == 1)
				{
					ETC_FrontShapeEdgePoint[ETC_FrontShapeEdgeCount][0] = j;
					ETC_FrontShapeEdgePoint[ETC_FrontShapeEdgeCount][1] = i;
					ETC_FrontShapeEdgeCount++;
					if (ETC_FrontShapeEdgeCount >= 4000)
					{
						breakSW = true;
						break;
					}
				}
			}
		}
		if (breakSW == true)
			break;
	}

	delete(binarizationData);
	delete(edgeNeighborData);
	delete(tempData);
	delete(expansionTempData);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ZoomInImageClick(
	TObject *Sender)
{
	zoomInOutSize *= 2;

	if (zoomInOutSize > 8)
		zoomInOutSize = 8;

	Panel18->Color = clRed;
	Panel19->Color = clBlack;

	int zoomInOutROIWidth;
	int zoomInOutROIHeight;

	zoomInOutROIWidth = MAX_ZOOM_W_PIXEL / zoomInOutSize;
	zoomInOutROIHeight = MAX_ZOOM_H_PIXEL / zoomInOutSize;

	if (zoomROIX1 + zoomInOutROIWidth > ImageWidth)
		zoomROIX1 = ImageWidth - zoomInOutROIWidth;
	if (zoomROIY1 + zoomInOutROIHeight > ImageHeight)
		zoomROIY1 = ImageHeight - zoomInOutROIHeight;

	zoomROIX2 = zoomROIX1 + zoomInOutROIWidth;
	zoomROIY2 = zoomROIY1 + zoomInOutROIHeight;

	LoadZoomInOutNavigationImage();

	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 0);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 0);
	else
		refreshZoomInTabletImage(NULL, 0);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ZoomOutImageClick(
	TObject *Sender)
{
	zoomInOutSize /= 2;

	if (zoomInOutSize < 2)
		zoomInOutSize = 2;

	Panel18->Color = clBlack;
	Panel19->Color = clRed;

	int zoomInOutROIWidth;
	int zoomInOutROIHeight;

	zoomInOutROIWidth = MAX_ZOOM_W_PIXEL / zoomInOutSize;
	zoomInOutROIHeight = MAX_ZOOM_H_PIXEL / zoomInOutSize;

	if (zoomROIX1 + zoomInOutROIWidth > ImageWidth)
		zoomROIX1 = ImageWidth - zoomInOutROIWidth;
	if (zoomROIY1 + zoomInOutROIHeight > ImageHeight)
		zoomROIY1 = ImageHeight - zoomInOutROIHeight;

	zoomROIX2 = zoomROIX1 + zoomInOutROIWidth;
	zoomROIY2 = zoomROIY1 + zoomInOutROIHeight;

	LoadZoomInOutNavigationImage();

	if (ManualCorrectSW)
		refreshZoomInTabletImage(PrintBinarizationData, 0);
	else if (PrintMaskSW)
		refreshZoomInTabletImage(PrintMaskArea, 0);
	else
		refreshZoomInTabletImage(NULL, 0);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::LoadZoomInOutNavigationImage()
{
	zoomInOutShiftX = zoomROIX1;
	zoomInOutShiftY = zoomROIY1;

	ZoomSizeLabel->Caption = "x " + IntToStr(zoomInOutSize);

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr, *ptr2;
	int x, y;

	for (y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		ptr2 = (byte*)img1->ScanLine[y];
		for (x = 0; x < ImageWidth; x++)
		{
			if (ptr[3 * x + 0] == 255 && ptr[3 * x + 1] == 255 && ptr[3 * x + 2] == 255)
			{
				ptr2[3 * x + 0] = 0;
				ptr2[3 * x + 1] = 0;
				ptr2[3 * x + 2] = 0;
			}
			else
			{
				ptr2[3 * x + 0] = ptr[3 * x + 0];
				ptr2[3 * x + 1] = ptr[3 * x + 1];
				ptr2[3 * x + 2] = ptr[3 * x + 2];
			}
		}
	}

	zoomInOutImage->Picture->Bitmap->Assign(img1);
	zoomInOutImage->Canvas->Pen->Width = 4;
	zoomInOutImage->Canvas->Pen->Color = clRed;
	zoomInOutImage->Canvas->Brush->Style = bsClear;
	zoomInOutImage->Canvas->Rectangle(zoomROIX1, zoomROIY1, zoomROIX2, zoomROIY2);
	zoomInOutImage->Refresh();
	delete img1;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::zoomInOutImageMouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	zoomImageNavigateFlag = 1;

	navigateStdX = X * (float) 1.6;
	navigateStdY = Y * (float) 1.6;

	tempStdX = zoomROIX1;
	tempStdY = zoomROIY1;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::zoomInOutImageMouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	zoomImageNavigateFlag = 0;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::zoomInOutImageMouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	if (zoomImageNavigateFlag)
	{
		int dX, dY;
		dX = X * (float) 1.6 - navigateStdX;
		dY = Y * (float) 1.6 - navigateStdY;

		int zoomInOutROIWidth;
		int zoomInOutROIHeight;

		zoomInOutROIWidth = MAX_ZOOM_W_PIXEL / zoomInOutSize;
		zoomInOutROIHeight = MAX_ZOOM_H_PIXEL / zoomInOutSize;

		zoomROIX1 = tempStdX + dX;
		zoomROIY1 = tempStdY + dY;

		if (zoomROIX1 < 0)
			zoomROIX1 = 0;
		if (zoomROIY1 < 0)
			zoomROIY1 = 0;
		if (zoomROIX1 + zoomInOutROIWidth > ImageWidth)
			zoomROIX1 = ImageWidth - zoomInOutROIWidth;
		if (zoomROIY1 + zoomInOutROIHeight > ImageHeight)
			zoomROIY1 = ImageHeight - zoomInOutROIHeight;

		zoomROIX2 = zoomROIX1 + zoomInOutROIWidth;
		zoomROIY2 = zoomROIY1 + zoomInOutROIHeight;

		LoadZoomInOutNavigationImage();

		if (ManualCorrectSW)
			refreshZoomInTabletImage(PrintBinarizationData, 0);
		else if (PrintMaskSW)
			refreshZoomInTabletImage(PrintMaskArea, 0);
		else
			refreshZoomInTabletImage(NULL, 0);
	}
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::refreshZoomInTabletImage(unsigned char *tempPrintMaskArea, int initSW)
{
	if (initSW)
	{
		for (int y = 0; y < ImageHeight; y++)
		{
			for (int x = 0; x < ImageWidth; x++)
			{
				PrintMaskArea[y*ImageWidth + x] = 0;
			}
		}
	}

	Byte *ptr;

	int m, k;
	int maxLineCount;
	if (zoomInOutSize == 2)
		maxLineCount = 2;
	else if (zoomInOutSize == 4)
		maxLineCount = 3;
	else if (zoomInOutSize == 8)
		maxLineCount = 4;

	int tempAddress, tempAddress2;
	int tempX, tempY;

	memset(originalColorSourceImage, 0, ImageWidth * ImageHeight * 3);
	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			originalColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
			originalColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
			originalColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];
		}
	}

	memset(extensionColorSourceImage, 0, MAX_ZOOM_W_PIXEL * MAX_ZOOM_H_PIXEL * 3);

	if (tempPrintMaskArea != NULL)
	{
		for (int y = zoomROIY1; y < zoomROIY2; y++)
		{
			for (int x = zoomROIX1; x < zoomROIX2; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				tempX = (x - zoomROIX1) * zoomInOutSize;
				tempY = (y - zoomROIY1) * zoomInOutSize;

				for (int j = tempY; j < tempY + zoomInOutSize; j++)
				{
					for (int i = tempX; i < tempX + zoomInOutSize; i++)
					{
						tempAddress2 = MAX_ZOOM_W_PIXEL * j + i;

						extensionColorSourceImage[tempAddress2 * 3 + 0] = originalColorSourceImage[tempAddress * 3 + 0];
						extensionColorSourceImage[tempAddress2 * 3 + 1] = originalColorSourceImage[tempAddress * 3 + 1];
						extensionColorSourceImage[tempAddress2 * 3 + 2] = originalColorSourceImage[tempAddress * 3 + 2];

						if (tempPrintMaskArea[tempAddress])
							extensionColorSourceImage[tempAddress2 * 3 + SelectedDisplayColor] = 255;
					}
				}
			}
		}
	}
	else
	{
		for (int y = zoomROIY1; y < zoomROIY2; y++)
		{
			for (int x = zoomROIX1; x < zoomROIX2; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				tempX = (x - zoomROIX1) * zoomInOutSize;
				tempY = (y - zoomROIY1) * zoomInOutSize;

				for (int j = tempY; j < tempY + zoomInOutSize; j++)
				{
					for (int i = tempX; i < tempX + zoomInOutSize; i++)
					{
						tempAddress2 = MAX_ZOOM_W_PIXEL * j + i;

						extensionColorSourceImage[tempAddress2 * 3 + 0] = originalColorSourceImage[tempAddress * 3 + 0];
						extensionColorSourceImage[tempAddress2 * 3 + 1] = originalColorSourceImage[tempAddress * 3 + 1];
						extensionColorSourceImage[tempAddress2 * 3 + 2] = originalColorSourceImage[tempAddress * 3 + 2];
					}
				}
			}
		}
	}

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = MAX_ZOOM_W_PIXEL;
	img1->Height = MAX_ZOOM_H_PIXEL;
	img1->PixelFormat = pf24bit;

	for (int y = 0; y < MAX_ZOOM_H_PIXEL; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < MAX_ZOOM_W_PIXEL; x++)
		{
			tempAddress = MAX_ZOOM_W_PIXEL * y + x;
			ptr[3 * x + 0] = extensionColorSourceImage[tempAddress * 3 + 0];
			ptr[3 * x + 1] = extensionColorSourceImage[tempAddress * 3 + 1];
			ptr[3 * x + 2] = extensionColorSourceImage[tempAddress * 3 + 2];
		}
	}

	Image9->Visible = true;
	Image9->Picture->Bitmap->Assign(img1);
	Image9->Refresh();
	delete(img1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::LoadZoomInOutNavigation3DImage()
{
	zoomInOutShiftX3D = zoomROIX1For3D;
	zoomInOutShiftY3D = zoomROIY1For3D;

	ZoomSize3DLabel->Caption = "x " + IntToStr(zoomInOutSize3D);

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = IMAGE_3D_WIDTH;
	img1->Height = IMAGE_3D_HEIGHT;
	img1->PixelFormat = pf24bit;

	Byte *ptr;
	int x, y;
	int tempAddress;

	for (y = 0; y < IMAGE_3D_HEIGHT; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (x = 0; x < IMAGE_3D_WIDTH; x++)
		{
			if (RotationThreeDImage[y*IMAGE_3D_WIDTH + x])
			{
				ptr[3 * x] = RotationThreeDImage[y*IMAGE_3D_WIDTH + x];
				ptr[3 * x + 1] = RotationThreeDImage[y*IMAGE_3D_WIDTH + x];
				ptr[3 * x + 2] = RotationThreeDImage[y*IMAGE_3D_WIDTH + x];
			}
			else
			{
				ptr[3 * x] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}
		}
	}

	zoomInOutNavigate3DImage->Picture->Bitmap->Assign(img1);
	zoomInOutNavigate3DImage->Canvas->Pen->Width = 4;
	zoomInOutNavigate3DImage->Canvas->Pen->Color = clRed;
	zoomInOutNavigate3DImage->Canvas->Brush->Style = bsClear;
	zoomInOutNavigate3DImage->Canvas->Rectangle(zoomROIX1For3D, zoomROIY1For3D, zoomROIX2For3D, zoomROIY2For3D);
	zoomInOutNavigate3DImage->Refresh();
	delete img1;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::zoomIn3DImageClick(
	TObject *Sender)
{
	zoomInOutSize3D *= 2;

	if (zoomInOutSize3D > 4)
		zoomInOutSize3D = 4;

	Panel20->Color = clRed;
	Panel21->Color = clBlack;

	int zoomInOutROIWidth;
	int zoomInOutROIHeight;

	zoomInOutROIWidth = MAX_ZOOM_W_PIXEL_FOR3D / zoomInOutSize3D;
	zoomInOutROIHeight = MAX_ZOOM_H_PIXEL_FOR3D / zoomInOutSize3D;

	if (zoomROIX1For3D + zoomInOutROIWidth > ImageWidth)
		zoomROIX1For3D = ImageWidth - zoomInOutROIWidth;
	if (zoomROIY1For3D + zoomInOutROIHeight > ImageHeight)
		zoomROIY1For3D = ImageHeight - zoomInOutROIHeight;

	zoomROIX2For3D = zoomROIX1For3D + zoomInOutROIWidth;
	zoomROIY2For3D = zoomROIY1For3D + zoomInOutROIHeight;

	LoadZoomInOutNavigation3DImage();

	if (threeDPrintExtractMode == THREE_D_NONE_MODE)
		refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
	else if (threeDPrintExtractMode == THREE_D_NORMAL_MODE)
		refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
	else if (threeDPrintExtractMode == THREE_D_BINARY_EXTRACTION_MODE)
		refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
	else if (threeDPrintExtractMode == THREE_D_BINARY_REVISION_MODE)
		refreshZoomInTablet3DImage(tempRotationThreeDImage, threeDPrintExtractMode);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::zoomOut3DImageClick(
	TObject *Sender)
{
	zoomInOutSize3D /= 2;

	if (zoomInOutSize3D < 1)
		zoomInOutSize3D = 1;

	Panel20->Color = clBlack;
	Panel21->Color = clRed;

	int zoomInOutROIWidth;
	int zoomInOutROIHeight;

	zoomInOutROIWidth = MAX_ZOOM_W_PIXEL_FOR3D / zoomInOutSize3D;
	zoomInOutROIHeight = MAX_ZOOM_H_PIXEL_FOR3D / zoomInOutSize3D;

	if (zoomROIX1For3D + zoomInOutROIWidth > ImageWidth)
		zoomROIX1For3D = ImageWidth - zoomInOutROIWidth;
	if (zoomROIY1For3D + zoomInOutROIHeight > ImageHeight)
		zoomROIY1For3D = ImageHeight - zoomInOutROIHeight;

	zoomROIX2For3D = zoomROIX1For3D + zoomInOutROIWidth;
	zoomROIY2For3D = zoomROIY1For3D + zoomInOutROIHeight;

	LoadZoomInOutNavigation3DImage();

	if (threeDPrintExtractMode == THREE_D_NONE_MODE)
		refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
	else if (threeDPrintExtractMode == THREE_D_NORMAL_MODE)
		refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
	else if (threeDPrintExtractMode == THREE_D_BINARY_EXTRACTION_MODE)
		refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
	else if (threeDPrintExtractMode == THREE_D_BINARY_REVISION_MODE)
		refreshZoomInTablet3DImage(tempRotationThreeDImage, threeDPrintExtractMode);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::zoomInOutNavigate3DImageMouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	zoomImageNavigateFlag3D = 1;

	navigateStdX3D = X * (float) 1.77778;
	navigateStdY3D = Y * (float) 1.77778;

	tempStdXFor3D = zoomROIX1For3D;
	tempStdYFor3D = zoomROIY1For3D;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::zoomInOutNavigate3DImageMouseMove(
	TObject *Sender, TShiftState Shift, int X, int Y)
{
	if (zoomImageNavigateFlag3D)
	{
		int dX, dY;
		dX = X * (float) 1.77778 - navigateStdX3D;
		dY = Y * (float) 1.77778 - navigateStdY3D;

		int zoomInOutROIWidth;
		int zoomInOutROIHeight;

		zoomInOutROIWidth = MAX_ZOOM_W_PIXEL_FOR3D / zoomInOutSize3D;
		zoomInOutROIHeight = MAX_ZOOM_H_PIXEL_FOR3D / zoomInOutSize3D;

		zoomROIX1For3D = tempStdXFor3D + dX;
		zoomROIY1For3D = tempStdYFor3D + dY;

		if (zoomROIX1For3D < 0)
			zoomROIX1For3D = 0;
		if (zoomROIY1For3D < 0)
			zoomROIY1For3D = 0;
		if (zoomROIX1For3D + zoomInOutROIWidth > ImageWidth)
			zoomROIX1For3D = ImageWidth - zoomInOutROIWidth;
		if (zoomROIY1For3D + zoomInOutROIHeight > ImageHeight)
			zoomROIY1For3D = ImageHeight - zoomInOutROIHeight;

		zoomROIX2For3D = zoomROIX1For3D + zoomInOutROIWidth;
		zoomROIY2For3D = zoomROIY1For3D + zoomInOutROIHeight;

		LoadZoomInOutNavigation3DImage();

		if (threeDPrintExtractMode == THREE_D_NONE_MODE)
			refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
		else if (threeDPrintExtractMode == THREE_D_NORMAL_MODE)
			refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
		else if (threeDPrintExtractMode == THREE_D_BINARY_EXTRACTION_MODE)
			refreshZoomInTablet3DImage(RotationThreeDImage, threeDPrintExtractMode);
		else if (threeDPrintExtractMode == THREE_D_BINARY_REVISION_MODE)
			refreshZoomInTablet3DImage(tempRotationThreeDImage, threeDPrintExtractMode);
	}
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::zoomInOutNavigate3DImageMouseUp(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	zoomImageNavigateFlag3D = 0;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::refreshZoomInTablet3DImage(unsigned char *tempImage, int mode)
{
	Byte *ptr;

	int m, k;
	int maxLineCount;
	if (zoomInOutSize3D == 1)
		maxLineCount = 1;
	else if (zoomInOutSize3D == 2)
		maxLineCount = 2;
	else if (zoomInOutSize3D == 4)
		maxLineCount = 3;

	int tempAddress, tempAddress2;
	int tempX, tempY;

	memset(extensionThreeDImage, 0, MAX_ZOOM_W_PIXEL_FOR3D * MAX_ZOOM_H_PIXEL_FOR3D * 3);

	for (int y = zoomROIY1For3D; y < zoomROIY2For3D; y++)
	{
		for (int x = zoomROIX1For3D; x < zoomROIX2For3D; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			tempX = (x - zoomROIX1For3D) * zoomInOutSize3D;
			tempY = (y - zoomROIY1For3D) * zoomInOutSize3D;

			for (int j = tempY; j < tempY + zoomInOutSize3D; j++)
			{
				for (int i = tempX; i < tempX + zoomInOutSize3D; i++)
				{
					tempAddress2 = MAX_ZOOM_W_PIXEL_FOR3D * j + i;

					if (mode == THREE_D_BINARY_EXTRACTION_MODE)
					{
						if (ShapeBinaryImage[tempAddress])
						{
							if (ThreeDPrintBinariztionResultViewSW)
							{
								if (PrintBinarizationDataForThreeD[tempAddress])
								{
									extensionThreeDImage[tempAddress2 * 3 + 0] = 255;
									extensionThreeDImage[tempAddress2 * 3 + 1] = 255;
									extensionThreeDImage[tempAddress2 * 3 + 2] = 0;
								}
							}
						}
					}
					else if (mode == THREE_D_NORMAL_MODE)
					{
						if (ShapeBinaryImage[tempAddress])
						{
							extensionThreeDImage[tempAddress2 * 3 + 0] = tempImage[tempAddress];
							extensionThreeDImage[tempAddress2 * 3 + 1] = tempImage[tempAddress];
							extensionThreeDImage[tempAddress2 * 3 + 2] = tempImage[tempAddress];
						}
					}
					else if (mode == THREE_D_BINARY_REVISION_MODE)
					{
						if (ShapeBinaryImage[tempAddress])
						{
							extensionThreeDImage[tempAddress2 * 3 + 0] = tempImage[tempAddress * 3 + 0];
							extensionThreeDImage[tempAddress2 * 3 + 1] = tempImage[tempAddress * 3 + 1];
							extensionThreeDImage[tempAddress2 * 3 + 2] = tempImage[tempAddress * 3 + 2];

							if (ThreeDPrintBinariztionResultViewSW)
							{
								if (PrintBinarizationDataForThreeD[tempAddress])
								{
									extensionThreeDImage[tempAddress2 * 3 + SelectedDisplayColor] = 192;
									extensionThreeDImage[tempAddress2 * 3 + noneSelectedDisplayColor1] = 40;
									extensionThreeDImage[tempAddress2 * 3 + noneSelectedDisplayColor2] = 40;
								}
							}
						}
					}
				}
			}
		}
	}

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = MAX_ZOOM_W_PIXEL;
	img1->Height = MAX_ZOOM_H_PIXEL;
	img1->PixelFormat = pf24bit;

	for (int y = 0; y < MAX_ZOOM_H_PIXEL_FOR3D; y++)
	{
		ptr = (byte*)img1->ScanLine[y];
		for (int x = 0; x < MAX_ZOOM_W_PIXEL_FOR3D; x++)
		{
			tempAddress = MAX_ZOOM_W_PIXEL_FOR3D * y + x;
			ptr[3 * x + 0] = extensionThreeDImage[tempAddress * 3 + 0];
			ptr[3 * x + 1] = extensionThreeDImage[tempAddress * 3 + 1];
			ptr[3 * x + 2] = extensionThreeDImage[tempAddress * 3 + 2];
		}
	}

	Image62->Visible = true;
	Image62->Picture->Bitmap->Assign(img1);
	Image62->Refresh();
	delete(img1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::setExtractedThreeDEngraveData()
{
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = MAX_IMAGE_WIDTH;
	img1->Height = MAX_IMAGE_HEIGHT;
	img1->PixelFormat = pf24bit;

	int x, y;
	Byte *ptr;

	if (SelectDisk == DISK1)
	{
		if (Tablet3DSetupData.Disk1printData1Count)
		{
			Image23->Visible = true;

			for (int m = 0; m < Tablet3DSetupData.Disk1printData1Count; m++)
			{
				x = Tablet3DSetupData.Disk1position_printData1[m][0];
				y = Tablet3DSetupData.Disk1position_printData1[m][1];
				ptr = (byte*)img1->ScanLine[y];
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}

			Image23->Picture->Bitmap->Assign(img1);
			Image23->Stretch = true;
			Image23->Refresh();

			for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
			{
				ptr = (Byte*)img1->ScanLine[y];
				for (x = 0; x < MAX_IMAGE_WIDTH; x++)
				{
					ptr[3 * x + 0] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}

		if (Tablet3DSetupData.Disk1printData2Count)
		{
			Image28->Visible = true;

			for (int m = 0; m < Tablet3DSetupData.Disk1printData2Count; m++)
			{
				x = Tablet3DSetupData.Disk1position_printData2[m][0];
				y = Tablet3DSetupData.Disk1position_printData2[m][1];
				ptr = (byte*)img1->ScanLine[y];
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}

			Image28->Picture->Bitmap->Assign(img1);
			Image28->Stretch = true;
			Image28->Refresh();

			for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
			{
				ptr = (Byte*)img1->ScanLine[y];
				for (x = 0; x < MAX_IMAGE_WIDTH; x++)
				{
					ptr[3 * x + 0] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}
	}
	else
	{
		if (Tablet3DSetupData.Disk2printData1Count)
		{
			Image23->Visible = true;

			for (int m = 0; m < Tablet3DSetupData.Disk2printData1Count; m++)
			{
				x = Tablet3DSetupData.Disk2position_printData1[m][0];
				y = Tablet3DSetupData.Disk2position_printData1[m][1];
				ptr = (byte*)img1->ScanLine[y];
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}

			Image23->Picture->Bitmap->Assign(img1);
			Image23->Stretch = true;
			Image23->Refresh();

			for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
			{
				ptr = (Byte*)img1->ScanLine[y];
				for (x = 0; x < MAX_IMAGE_WIDTH; x++)
				{
					ptr[3 * x + 0] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}

		if (Tablet3DSetupData.Disk2printData2Count)
		{
			Image28->Visible = true;

			for (int m = 0; m < Tablet3DSetupData.Disk2printData2Count; m++)
			{
				x = Tablet3DSetupData.Disk2position_printData2[m][0];
				y = Tablet3DSetupData.Disk2position_printData2[m][1];
				ptr = (byte*)img1->ScanLine[y];
				ptr[3 * x + 0] = 0;
				ptr[3 * x + 1] = 0;
				ptr[3 * x + 2] = 0;
			}

			Image28->Picture->Bitmap->Assign(img1);
			Image28->Stretch = true;
			Image28->Refresh();

			for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
			{
				ptr = (Byte*)img1->ScanLine[y];
				for (x = 0; x < MAX_IMAGE_WIDTH; x++)
				{
					ptr[3 * x + 0] = 255;
					ptr[3 * x + 1] = 255;
					ptr[3 * x + 2] = 255;
				}
			}
		}
	}

	delete img1;
}
//---------------------------------------------------------------------------
bool __fastcall TTabletCharacterExtractForm::checkPrintExtractResult()
{
	if (print1ExtractUnusalSW)
	{
		if (MessageDlgFA(NEW_ADD_STRING_60, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (print2ExtractUnusalSW)
	{
		if (MessageDlgFA(NEW_ADD_STRING_61, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (Disk1Print1ExtractUnusalSW)
	{
		if (MessageDlgFA(NEW_ADD_STRING_62, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (Disk1Print2ExtractUnusalSW)
	{
		if (MessageDlgFA(NEW_ADD_STRING_63, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (Disk2Print1ExtractUnusalSW)
	{
		if (MessageDlgFA(NEW_ADD_STRING_64, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (Disk2Print2ExtractUnusalSW)
	{
		if (MessageDlgFA(NEW_ADD_STRING_65, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
	}

  if(TabletSetupData.printData1Count > PRINT_DATA_SIZE ||
      TabletSetupData.expansion_printData1Count > PRINT_DATA_SIZE ||
      TabletSetupData.printLabelCount[0] > THREED_PRINT_MAX_LABEL_COUNT)
  {
    if (MessageDlgFA(NEW_ADD_STRING_60, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  bool bTwoDPrint1ErrorSW = false;
  for(int label = 0; label < THREED_PRINT_MAX_LABEL_COUNT; label++)
  {
    if(TabletSetupData.printLabelDataCnt[0][label] > PRINT_LABEL_DATA_SIZE)
    {
      bTwoDPrint1ErrorSW = true;
      break;
    }
  }

  if(bTwoDPrint1ErrorSW)
  {
    if (MessageDlgFA(NEW_ADD_STRING_60, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  if(TabletSetupData.printData2Count > PRINT_DATA_SIZE ||
      TabletSetupData.expansion_printData2Count > PRINT_DATA_SIZE ||
      TabletSetupData.printLabelCount[1] > THREED_PRINT_MAX_LABEL_COUNT)
  {
    if (MessageDlgFA(NEW_ADD_STRING_61, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  bool bTwoDPrint2ErrorSW = false;
  for(int label = 0; label < THREED_PRINT_MAX_LABEL_COUNT; label++)
  {
    if(TabletSetupData.printLabelDataCnt[1][label] > PRINT_LABEL_DATA_SIZE)
    {
      bTwoDPrint2ErrorSW = true;
      break;
    }
  }

  if(bTwoDPrint2ErrorSW)
  {
    if (MessageDlgFA(NEW_ADD_STRING_61, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  // 3d Disk1
  if(Tablet3DSetupData.Disk1printData1Count > THREED_PRINT_DATA_SIZE ||
      Tablet3DSetupData.Disk1slice_printData1Count > THREED_SLICE_PRINT_DATA_SIZE ||
      Tablet3DSetupData.printLabelCount[0][0] > THREED_PRINT_MAX_LABEL_COUNT)
  {
    if (MessageDlgFA(NEW_ADD_STRING_62, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  bool bThreeDDisk1Print1ErrorSW = false;
  for(int label = 0; label < THREED_PRINT_MAX_LABEL_COUNT; label++)
  {
    if(Tablet3DSetupData.printLabelDataCnt[0][0][label] > PRINT_LABEL_DATA_SIZE)
    {
      bThreeDDisk1Print1ErrorSW = true;
      break;
    }
  }

  if(bThreeDDisk1Print1ErrorSW)
  {
    if (MessageDlgFA(NEW_ADD_STRING_62, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  if(Tablet3DSetupData.Disk1printData2Count > THREED_PRINT_DATA_SIZE ||
      Tablet3DSetupData.Disk1slice_printData2Count > THREED_SLICE_PRINT_DATA_SIZE ||
      Tablet3DSetupData.printLabelCount[0][1] > THREED_PRINT_MAX_LABEL_COUNT)
  {
    if (MessageDlgFA(NEW_ADD_STRING_63, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  bool bThreeDDisk1Print2ErrorSW = false;
  for(int label = 0; label < THREED_PRINT_MAX_LABEL_COUNT; label++)
  {
    if(Tablet3DSetupData.printLabelDataCnt[0][1][label] > PRINT_LABEL_DATA_SIZE)
    {
      bThreeDDisk1Print2ErrorSW = true;
      break;
    }
  }

  if(bThreeDDisk1Print2ErrorSW)
  {
    if (MessageDlgFA(NEW_ADD_STRING_63, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  // 3d Disk2
  if(Tablet3DSetupData.Disk2printData1Count > THREED_PRINT_DATA_SIZE ||
      Tablet3DSetupData.Disk2slice_printData1Count > THREED_SLICE_PRINT_DATA_SIZE ||
      Tablet3DSetupData.printLabelCount[1][0] > THREED_PRINT_MAX_LABEL_COUNT)
  {
    if (MessageDlgFA(NEW_ADD_STRING_64, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  bool bThreeDDisk2Print1ErrorSW = false;
  for(int label = 0; label < THREED_PRINT_MAX_LABEL_COUNT; label++)
  {
    if(Tablet3DSetupData.printLabelDataCnt[1][0][label] > PRINT_LABEL_DATA_SIZE)
    {
      bThreeDDisk2Print1ErrorSW = true;
      break;
    }
  }

  if(bThreeDDisk2Print1ErrorSW)
  {
    if (MessageDlgFA(NEW_ADD_STRING_64, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  if(Tablet3DSetupData.Disk2printData2Count > THREED_PRINT_DATA_SIZE ||
      Tablet3DSetupData.Disk2slice_printData2Count > THREED_SLICE_PRINT_DATA_SIZE ||
      Tablet3DSetupData.printLabelCount[1][1] > THREED_PRINT_MAX_LABEL_COUNT)
  {
    if (MessageDlgFA(NEW_ADD_STRING_65, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

  bool bThreeDDisk2Print2ErrorSW = false;
  for(int label = 0; label < THREED_PRINT_MAX_LABEL_COUNT; label++)
  {
    if(Tablet3DSetupData.printLabelDataCnt[1][1][label] > PRINT_LABEL_DATA_SIZE)
    {
      bThreeDDisk2Print2ErrorSW = true;
      break;
    }
  }

  if(bThreeDDisk2Print2ErrorSW)
  {
    if (MessageDlgFA(NEW_ADD_STRING_65, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrCancel)
		{
			MessageDlgFA(NEW_ADD_STRING_66, mtConfirmation, TMsgDlgButtons() << mbOK);
			return false;
		}
		else
		{
			return true;
		}
  }

	return true;

	return true;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SetThresholdBtnClick(
	TObject *Sender)
{
	if (TabletSetupData.protoStudyColorB == 0 || TabletSetupData.protoStudyColorG == 0 || TabletSetupData.protoStudyColorR == 0)
	{
		MessageDlgFA(TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_29, mtConfirmation, TMsgDlgButtons() << mbOK);
		return;
	}

	ShapExtractButton->Enabled = false;
	DiscrimiationMarkExtract->Enabled = false;
	SetThresholdBtn->Enabled = false;
	ThreeDDiscriminationExtractButton->Enabled = false;
	SaveAndExitButton->Enabled = false;
  GetThreeDInfoButton->Enabled = false;
  ReadHistoryButton->Enabled = false;

	if (TabletSetupData.SideFaceShapeExtractThreshold == 0) // 초기값 설정
	{
		TabletSetupData.SideFaceShapeExtractThreshold = 40;
	}

  if (TabletSetupData.TabletColorRange == 0) // 초기값 설정
	{
		TabletSetupData.TabletColorRange = 20;
	}

	if(TabletSetupData.TabletColorRangeEachActive == SIDE_COLORATE_SET_EACH_INABLE)
	{
		for(int i =0; i<= SYSTEM_TOTAL_CAMERA_COUNT; i++)
		{
        	if(TabletSetupData.TabletColorRangeEach[i] == 0)
            {
				TabletSetupData.TabletColorRangeEach[i] = 20;
            }
		}
	}

  if (TabletSetupData.TabletColorRange_Rear == 0) // 초기값 설정
	{
		TabletSetupData.TabletColorRange_Rear = 20;
	}

  LoadSideFaceImage();

  bInit = true;
  for(int globalCameraIndex = 1; globalCameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    if (globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
    {
      TTrackBar *SideTrackBar = (TTrackBar *)FindComponent("SideThresholdForEachCamera" + IntToStr(globalCameraIndex));
      if(SideTrackBar)
      {
        SideTrackBar->Position = TabletSetupData.SideThresholdForEachCamera[globalCameraIndex - 1];
      }
    }
  }

  bInit = false;

  if (TabletCharacter.kind == SUGARCOATING)
  {
    Panel26->Visible = false;
  }

  ColorRateCheckBox->Checked = TabletSetupData.ActiveColorRatioCheck;
  SideThrEachCheckBox->Checked = TabletSetupData.TabletColorRangeEachActive;

  if(ColorRateCheckBox->Checked)
  {
    ColorRateRangeImage->Enabled = true;
    ColorRateRangeImage_Rear->Enabled = true;
    Panel26->Color = 0x00002200;
    SideThrEachCheckBox->Enabled = true;    
  }
  else
  {
    ColorRateRangeImage->Enabled = false;
    ColorRateRangeImage_Rear->Enabled = false;
    Panel26->Color = clDkGray;

    SideThrEachCheckBox->Enabled = false;
    SideThrEachCheckBox->Checked = false;    
    TabletSetupData.TabletColorRangeEachActive = SIDE_COLORATE_SET_EACH_DISABLE;    
  }

  Panel26->Refresh();

	SideFaceThresholdValueDisplay(); 

	SetThresholdPanel->BringToFront();
	SetThresholdPanel->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SetThresholdCloseBtnClick(
	TObject *Sender)
{
	ShapExtractButton->Enabled = true;
	DiscrimiationMarkExtract->Enabled = true;
	SetThresholdBtn->Enabled = true;
	ThreeDDiscriminationExtractButton->Enabled = bThreeDDataExtraction;
	SaveAndExitButton->Enabled = true;
  GetThreeDInfoButton->Enabled = true;
  ReadHistoryButton->Enabled = true;

  SetThresholdPanel->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SideFaceThresholdValueDisplay(void)
{
	SideThresholdImage->Canvas->Brush->Style = bsSolid;
	SideThresholdImage->Canvas->Brush->Color = clBlack;
	SideThresholdImage->Canvas->Pen->Color = clBlack;
	SideThresholdImage->Canvas->Rectangle(0, 0, SideThresholdImage->Width, SideThresholdImage->Height);

	SideThresholdImage->Canvas->Brush->Style = bsSolid;
	SideThresholdImage->Canvas->Brush->Color = (TColor)0x126596;
	SideThresholdImage->Canvas->Rectangle(0, 0, TabletSetupData.SideFaceShapeExtractThreshold*(SideThresholdImage->Width / 200), SideThresholdImage->Height);
	SideThresholdImage->Canvas->Font->Color = clBlack;

	SideFaceThresholdValueLabel->Caption = IntToStr(TabletSetupData.SideFaceShapeExtractThreshold) + " Level";//TABLETCHARACTEREXTRACTFORM_LABEL_CAPTION_06;

  ColorRateRangeImage->Canvas->Brush->Style = bsSolid;
	ColorRateRangeImage->Canvas->Brush->Color = clBlack;
	ColorRateRangeImage->Canvas->Pen->Color = clBlack;
	ColorRateRangeImage->Canvas->Rectangle(0, 0, ColorRateRangeImage->Width, ColorRateRangeImage->Height);

	ColorRateRangeImage->Canvas->Brush->Style = bsSolid;
	ColorRateRangeImage->Canvas->Brush->Color = (TColor)0x126596;
	ColorRateRangeImage->Canvas->Rectangle(0, 0, TabletSetupData.TabletColorRange*(ColorRateRangeImage->Width / 100), ColorRateRangeImage->Height);
	ColorRateRangeImage->Canvas->Font->Color = clBlack;

	ColorRatioRangeLabel->Caption = IntToStr(TabletSetupData.TabletColorRange) + " %";

  ColorRateRangeImage_Rear->Canvas->Brush->Style = bsSolid;
	ColorRateRangeImage_Rear->Canvas->Brush->Color = clBlack;
	ColorRateRangeImage_Rear->Canvas->Pen->Color = clBlack;
	ColorRateRangeImage_Rear->Canvas->Rectangle(0, 0, ColorRateRangeImage_Rear->Width, ColorRateRangeImage_Rear->Height);

	ColorRateRangeImage_Rear->Canvas->Brush->Style = bsSolid;
	ColorRateRangeImage_Rear->Canvas->Brush->Color = (TColor)0x126596;
	ColorRateRangeImage_Rear->Canvas->Rectangle(0, 0, TabletSetupData.TabletColorRange_Rear*(ColorRateRangeImage_Rear->Width / 100), ColorRateRangeImage_Rear->Height);
	ColorRateRangeImage_Rear->Canvas->Font->Color = clBlack;

	ColorRatioRangeLabel_Rear->Caption = IntToStr(TabletSetupData.TabletColorRange_Rear) + " %";
  
	FilteringSideFaceImage();
}

//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SideThresholdImageMouseDown(
	TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
	int Y)
{
	TabletSetupData.SideFaceShapeExtractThreshold = X / (SideThresholdImage->Width / 200) + 1;
	SideFaceThresholdValueDisplay();
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::LoadSideFaceImage(void)
{
	Graphics::TBitmap *shapeImg;
	shapeImg = new Graphics::TBitmap();
	shapeImg->Width = MAX_IMAGE_WIDTH;
	shapeImg->Height = MAX_IMAGE_HEIGHT;
	shapeImg->PixelFormat = pf24bit;

	for (int globalCameraIndex = 1; globalCameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX &&
			globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX &&
			globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
			globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
		{
			if (CameraMapInfo[globalCameraIndex - 1].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[globalCameraIndex - 1] != 0 )

			{
				if (!ExtractImage(shapeImg, 10, globalCameraIndex, TabletSetupData.ImageOffSetSW[globalCameraIndex - 1], TabletSetupData.referenceImageForOffset[globalCameraIndex - 1], ProductData.SubSamplingMode)) continue;

				if (CameraMapInfo[globalCameraIndex - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
				{
					ReductionImageScale(shapeImg);
				}

				TImage *tempImage = ((TImage *)FindComponent("srcSideFaceImageCam" + IntToStr(globalCameraIndex)));

				if (tempImage)
				{
					tempImage->Picture->Bitmap->Assign(shapeImg);
					tempImage->Refresh();
				}
			}
		}
	}

	delete shapeImg;
}

//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::FilteringSideFaceImage()
{
	unsigned char ColorSourceImage[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3];
	memset(ColorSourceImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);

	int x, y;
	int tempAddress;
	Byte *ptr;
	int value[3];
	int colorFactorRate[3];
	int imgHigherFactorTable[3];
	int tempValue;
	int tempFactor;
	int ColorFactorCheckSW;
	int m, k;

	Graphics::TBitmap *shapeImg;
	shapeImg = new Graphics::TBitmap();
	shapeImg->Width = MAX_IMAGE_WIDTH;
	shapeImg->Height = MAX_IMAGE_HEIGHT;
	shapeImg->PixelFormat = pf24bit;

  imgHigherFactorTable[0] = 0;
  imgHigherFactorTable[1] = 1;
  imgHigherFactorTable[2] = 2;
    
  value[0] = TabletSetupData.protoStudyColorB;
  value[1] = TabletSetupData.protoStudyColorG;
  value[2] = TabletSetupData.protoStudyColorR;

  TabletSetupData.TabletColorRatio[0] = colorFactorRate[0] = value[0] * 1000 / (value[0] + value[1] + value[2]);
  TabletSetupData.TabletColorRatio[1] = colorFactorRate[1] = value[1] * 1000 / (value[0] + value[1] + value[2]);
  TabletSetupData.TabletColorRatio[2] = colorFactorRate[2] = value[2] * 1000 / (value[0] + value[1] + value[2]);

  for (k = 0; k < 3; k++)
  {
    for (m = k + 1; m < 3; m++)
    {
      if (colorFactorRate[k] < colorFactorRate[m])
      {
        tempValue = colorFactorRate[k];
        colorFactorRate[k] = colorFactorRate[m];
        colorFactorRate[m] = tempValue;

        tempFactor = imgHigherFactorTable[k];
        imgHigherFactorTable[k] = imgHigherFactorTable[m];
        imgHigherFactorTable[m] = tempFactor;
      }
    }
  }

  TabletSetupData.HigherColorFactor = imgHigherFactorTable[0];

  if(abs(colorFactorRate[0] - colorFactorRate[1]) < SIMILAR_COLOR_STANDARD_VALUE)
  {
    TabletSetupData.TabletColorType = TABLET_COMBINE_COLOR;
  }
  else
  {
    TabletSetupData.TabletColorType = TABLET_SINGLE_COLOR;
  }

  if (ProductData.TabletType == TABLET_TYPE_MULTI_LAYERED)
  {
    imgHigherFactorTable[0] = 0;
    imgHigherFactorTable[1] = 1;
    imgHigherFactorTable[2] = 2;

    value[0] = TabletSetupData.rear_protoStudyColorB;
    value[1] = TabletSetupData.rear_protoStudyColorG;
    value[2] = TabletSetupData.rear_protoStudyColorR;

    TabletSetupData.TabletColorRatio_Rear[0] = colorFactorRate[0] = value[0] * 1000 / (value[0] + value[1] + value[2]);
    TabletSetupData.TabletColorRatio_Rear[1] = colorFactorRate[1] = value[1] * 1000 / (value[0] + value[1] + value[2]);
    TabletSetupData.TabletColorRatio_Rear[2] = colorFactorRate[2] = value[2] * 1000 / (value[0] + value[1] + value[2]);

    for (k = 0; k < 3; k++)
    {
      for (m = k + 1; m < 3; m++)
      {
        if (colorFactorRate[k] < colorFactorRate[m])
        {
          tempValue = colorFactorRate[k];
          colorFactorRate[k] = colorFactorRate[m];
          colorFactorRate[m] = tempValue;

          tempFactor = imgHigherFactorTable[k];
          imgHigherFactorTable[k] = imgHigherFactorTable[m];
          imgHigherFactorTable[m] = tempFactor;
        }
      }
    }

    TabletSetupData.HigherColorFactor_Rear = imgHigherFactorTable[0];

    if(abs(colorFactorRate[0] - colorFactorRate[1]) < SIMILAR_COLOR_STANDARD_VALUE)
    {
      TabletSetupData.TabletColorType_Rear = TABLET_COMBINE_COLOR;
    }
    else
    {
      TabletSetupData.TabletColorType_Rear = TABLET_SINGLE_COLOR;
    }
  }

  TabletColorRatioImage->Picture->Bitmap->Width = TabletColorRatioImage->Width;
  TabletColorRatioImage->Picture->Bitmap->Height = TabletColorRatioImage->Height;
  TabletColorRatioImage->Picture->Bitmap->PixelFormat = pf24bit;

  TabletColorRatioImage_Rear->Picture->Bitmap->Width = TabletColorRatioImage_Rear->Width;
  TabletColorRatioImage_Rear->Picture->Bitmap->Height = TabletColorRatioImage_Rear->Height;
  TabletColorRatioImage_Rear->Picture->Bitmap->PixelFormat = pf24bit;
  
  for(y = 0; y < TabletColorRatioImage->Height; y++)
  {
    Byte *ptr = (Byte*)TabletColorRatioImage->Picture->Bitmap->ScanLine[y];
    for(x = 0; x < TabletColorRatioImage->Width; x++)
    {
      ptr[3 * x + 0] = 255 * TabletSetupData.TabletColorRatio[0] / 1000;
      ptr[3 * x + 1] = 255 * TabletSetupData.TabletColorRatio[1] / 1000;
      ptr[3 * x + 2] = 255 * TabletSetupData.TabletColorRatio[2] / 1000;
    }
  }

  TabletColorRatioImage->Refresh();

  if (ProductData.TabletType == TABLET_TYPE_MULTI_LAYERED)
  {
    for(y = 0; y < TabletColorRatioImage_Rear->Height; y++)
    {
      Byte *ptr = (Byte*)TabletColorRatioImage_Rear->Picture->Bitmap->ScanLine[y];
      for(x = 0; x < TabletColorRatioImage_Rear->Width; x++)
      {
        ptr[3 * x + 0] = 255 * TabletSetupData.TabletColorRatio_Rear[0] / 1000;
        ptr[3 * x + 1] = 255 * TabletSetupData.TabletColorRatio_Rear[1] / 1000;
        ptr[3 * x + 2] = 255 * TabletSetupData.TabletColorRatio_Rear[2] / 1000;
      }
    }

    TabletColorRatioImage_Rear->Refresh();
  }
  else
  {
    ColorRateRangeImage_Rear->Visible = false;
    TabletColorRatioImage_Rear->Visible = false;
    ColorRatioRangeLabel_Rear->Visible = false;
  }

	int selectedRGB = 1;
	if (TabletSetupData.protoStudyColorR != 0
		&& TabletSetupData.protoStudyColorG != 0
		&& TabletSetupData.protoStudyColorB != 0)
	{
		if (TabletSetupData.protoStudyColorR > TabletSetupData.protoStudyColorG * 110 / 100)
		{
			if (TabletSetupData.protoStudyColorR > TabletSetupData.protoStudyColorB * 110 / 100)
			{
				selectedRGB = 2;
			}
		}
		if (TabletSetupData.protoStudyColorB > TabletSetupData.protoStudyColorG * 110 / 100)
		{
			if (TabletSetupData.protoStudyColorB > TabletSetupData.protoStudyColorR * 110 / 100)
			{
				selectedRGB = 0;
			}
		}
	}

  int selectedRGB_Rear = 1;

  if (ProductData.TabletType == TABLET_TYPE_MULTI_LAYERED)
  {
    if (TabletSetupData.rear_protoStudyColorR != 0
      && TabletSetupData.rear_protoStudyColorG != 0
      && TabletSetupData.rear_protoStudyColorB != 0)
    {
      if (TabletSetupData.rear_protoStudyColorR > TabletSetupData.rear_protoStudyColorG * 110 / 100)
      {
        if (TabletSetupData.rear_protoStudyColorR > TabletSetupData.rear_protoStudyColorB * 110 / 100)
        {
          selectedRGB_Rear = 2;
        }
      }
      if (TabletSetupData.rear_protoStudyColorB > TabletSetupData.rear_protoStudyColorG * 110 / 100)
      {
        if (TabletSetupData.rear_protoStudyColorB > TabletSetupData.rear_protoStudyColorR * 110 / 100)
        {
          selectedRGB_Rear = 0;
        }
      }
    }
  }
  else
  {
    selectedRGB_Rear = selectedRGB;
  }

  unsigned char SmallSizeBinaryImage[(MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2)];
  short SmallLabelImage[(MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2)];

  int tempAddress2;
  int startX, endX, startY, endY;
  startX = 10;
  endX = MAX_IMAGE_WIDTH - 10;
  startY = 10;
  endY = MAX_IMAGE_HEIGHT - 10;
  
	for (int globalCameraIndex = 1; globalCameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{

		if (globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
		{
			if (CameraMapInfo[globalCameraIndex - 1].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[globalCameraIndex -1] != 0)
			{
				TTntImage *tempImage = ((TTntImage *)FindComponent("srcSideFaceImageCam" + IntToStr(globalCameraIndex)));

				if (tempImage)
				{
					for (y = startY; y < endY; y++)
					{
						ptr = (Byte*)tempImage->Picture->Bitmap->ScanLine[y];
						for (x = startX; x < endX; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							ColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
							ColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
							ColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];
						}
					}

          memset(ShapeBinaryImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
          int threshold = TabletSetupData.SideFaceShapeExtractThreshold + TabletSetupData.SideThresholdForEachCamera[globalCameraIndex - 1];

          if (!ColorRateCheckBox->Checked)
          {
            for (y = startY; y < endY; y++)
            {
              for (x = startX; x < endX; x++)
              {
                tempAddress = MAX_IMAGE_WIDTH * y + x;

                if (ColorSourceImage[tempAddress * 3 + selectedRGB] > threshold ||
                    ColorSourceImage[tempAddress * 3 + selectedRGB_Rear] > threshold)
                {
                  ShapeBinaryImage[tempAddress] = 1;
                }
              }
            }
          }
          else
          {
            for (y = startY; y < endY; y++)
            {
              for (x = startX; x < endX; x++)
              {
                tempAddress = MAX_IMAGE_WIDTH * y + x;

                if (ColorSourceImage[tempAddress * 3 + selectedRGB] > threshold ||
                    ColorSourceImage[tempAddress * 3 + selectedRGB_Rear] > threshold)
                {
                  imgHigherFactorTable[0] = 0;
                  imgHigherFactorTable[1] = 1;
                  imgHigherFactorTable[2] = 2;
    
                  value[0] = ColorSourceImage[tempAddress * 3 + 0];
                  value[1] = ColorSourceImage[tempAddress * 3 + 1];
                  value[2] = ColorSourceImage[tempAddress * 3 + 2];

                  if(value[0] + value[1] + value[2])
                  {
                    colorFactorRate[0] = value[0] * 1000 / (value[0] + value[1] + value[2]);
                    colorFactorRate[1] = value[1] * 1000 / (value[0] + value[1] + value[2]);
                    colorFactorRate[2] = value[2] * 1000 / (value[0] + value[1] + value[2]);
                  }

                  for (k = 0; k < 3; k++)
                  {
                    for (m = k + 1; m < 3; m++)
                    {
                      if (value[k] < value[m])
                      {
                        tempValue = value[k];
                        value[k] = value[m];
                        value[m] = tempValue;

                        tempFactor = imgHigherFactorTable[k];
                        imgHigherFactorTable[k] = imgHigherFactorTable[m];
                        imgHigherFactorTable[m] = tempFactor;
                      }
                    }
                  }

                  if((TabletSetupData.TabletColorType == TABLET_SINGLE_COLOR && imgHigherFactorTable[0] == TabletSetupData.HigherColorFactor) ||
                      (TabletSetupData.TabletColorType == TABLET_COMBINE_COLOR && (imgHigherFactorTable[0] == TabletSetupData.HigherColorFactor || imgHigherFactorTable[1] == TabletSetupData.HigherColorFactor)))
                  {
                  	if(TabletSetupData.TabletColorRangeEachActive == SIDE_COLORATE_SET_EACH_INABLE)
                  	{
	                    if(colorFactorRate[0] > (TabletSetupData.TabletColorRatio[0] * (100 - TabletSetupData.TabletColorRangeEach[globalCameraIndex - 1])) / 100 &&
	                        colorFactorRate[0] < (TabletSetupData.TabletColorRatio[0] * (100 + TabletSetupData.TabletColorRangeEach[globalCameraIndex - 1])) / 100 &&
	                        colorFactorRate[1] > (TabletSetupData.TabletColorRatio[1] * (100 - TabletSetupData.TabletColorRangeEach[globalCameraIndex - 1])) / 100 &&
	                        colorFactorRate[1] < (TabletSetupData.TabletColorRatio[1] * (100 + TabletSetupData.TabletColorRangeEach[globalCameraIndex - 1])) / 100 &&
	                        colorFactorRate[2] > (TabletSetupData.TabletColorRatio[2] * (100 - TabletSetupData.TabletColorRangeEach[globalCameraIndex - 1])) / 100 &&
	                        colorFactorRate[2] < (TabletSetupData.TabletColorRatio[2] * (100 + TabletSetupData.TabletColorRangeEach[globalCameraIndex - 1])) / 100)
	                    {
	                      ShapeBinaryImage[tempAddress] = 1;
	                    }	                    
                    }
                    else
                    {
	                    if(colorFactorRate[0] > (TabletSetupData.TabletColorRatio[0] * (100 - TabletSetupData.TabletColorRange)) / 100 &&
	                        colorFactorRate[0] < (TabletSetupData.TabletColorRatio[0] * (100 + TabletSetupData.TabletColorRange)) / 100 &&
	                        colorFactorRate[1] > (TabletSetupData.TabletColorRatio[1] * (100 - TabletSetupData.TabletColorRange)) / 100 &&
	                        colorFactorRate[1] < (TabletSetupData.TabletColorRatio[1] * (100 + TabletSetupData.TabletColorRange)) / 100 &&
	                        colorFactorRate[2] > (TabletSetupData.TabletColorRatio[2] * (100 - TabletSetupData.TabletColorRange)) / 100 &&
	                        colorFactorRate[2] < (TabletSetupData.TabletColorRatio[2] * (100 + TabletSetupData.TabletColorRange)) / 100)
	                    {
	                      ShapeBinaryImage[tempAddress] = 1;
	                    }
                    }
                  }

                  if (ProductData.TabletType == TABLET_TYPE_MULTI_LAYERED)
                  {
                    if((TabletSetupData.TabletColorType_Rear == TABLET_SINGLE_COLOR && imgHigherFactorTable[0] == TabletSetupData.HigherColorFactor_Rear) ||
                        (TabletSetupData.TabletColorType_Rear == TABLET_COMBINE_COLOR && (imgHigherFactorTable[0] == TabletSetupData.HigherColorFactor_Rear || imgHigherFactorTable[1] == TabletSetupData.HigherColorFactor_Rear)))
                    {
                      if(colorFactorRate[0] > (TabletSetupData.TabletColorRatio_Rear[0] * (100 - TabletSetupData.TabletColorRange_Rear)) / 100 &&
                          colorFactorRate[0] < (TabletSetupData.TabletColorRatio_Rear[0] * (100 + TabletSetupData.TabletColorRange_Rear)) / 100 &&
                          colorFactorRate[1] > (TabletSetupData.TabletColorRatio_Rear[1] * (100 - TabletSetupData.TabletColorRange_Rear)) / 100 &&
                          colorFactorRate[1] < (TabletSetupData.TabletColorRatio_Rear[1] * (100 + TabletSetupData.TabletColorRange_Rear)) / 100 &&
                          colorFactorRate[2] > (TabletSetupData.TabletColorRatio_Rear[2] * (100 - TabletSetupData.TabletColorRange_Rear)) / 100 &&
                          colorFactorRate[2] < (TabletSetupData.TabletColorRatio_Rear[2] * (100 + TabletSetupData.TabletColorRange_Rear)) / 100)
                      {
                        ShapeBinaryImage[tempAddress] = 1;
                      }
                    }
                  }
                }
              }
            }
          }

					for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
					{
						ptr = (Byte*)shapeImg->ScanLine[y];
						for (x = 0; x < MAX_IMAGE_WIDTH; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

              if(ShapeBinaryImage[tempAddress])
              {
                ptr[3 * x + 0] = ColorSourceImage[tempAddress * 3 + 0];
                ptr[3 * x + 1] = ColorSourceImage[tempAddress * 3 + 1];
                ptr[3 * x + 2] = ColorSourceImage[tempAddress * 3 + 2];
              }
              else
              {
                ptr[3 * x + 0] = 0;
                ptr[3 * x + 1] = 0;
                ptr[3 * x + 2] = 0;
              }
						}
					}

          /*
          for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
					{
						ptr = (Byte*)shapeImg->ScanLine[y];
						for (x = 0; x < MAX_IMAGE_WIDTH; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

              ptr[3 * x + 0] = BackgroundColorImage[tempAddress * 3 + 0];
              ptr[3 * x + 1] = BackgroundColorImage[tempAddress * 3 + 1];
              ptr[3 * x + 2] = BackgroundColorImage[tempAddress * 3 + 2];
						}
					}
          */

					TImage *tempImage2 = ((TImage *)FindComponent("dstSideFaceImageCam" + IntToStr(globalCameraIndex)));

					if (tempImage2)
					{
						tempImage2->Picture->Bitmap->Assign(shapeImg);
						tempImage2->Refresh();
					}
				}
			}
		}
	}

	delete shapeImg;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ExtractSplitLineBtnClick(
      TObject *Sender)
{
  SelectedImageN[0] = 0;
	SelectedImageN[1] = 0;

  SetBlankImage(SplitLineSelectedImage);

  frontFace2DInfoMode = FRONT_GET_DATA_MODE_SPLITLINE;

  BitBtn11->Enabled = false;
	BitBtn12->Enabled = false;
	BitBtn17->Enabled = false;
  ExtractSplitLineBtn->Enabled = false;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = true;
	for (int i = 1000; i > 150; i -= 50)
	{
		ExtractionSplitLineGroupBox->Left = i;
		Sleep(5);
	}

	ExtractionSplitLineGroupBox->BringToFront();

  SplitLineExtractionBtn->Enabled = false;

  if(TabletSetupData.tabletSplitLineDataCount >= PRINT_DATA_SIZE)
  {
    TabletSetupData.tabletSplitLineDataCount = 0;
    memset(TabletSetupData.tabletSplitLineData, 0, sizeof(short) * PRINT_DATA_SIZE * 2);
  }
  DisplayExistData(ExtractedSplitLineImage, TabletSetupData.tabletSplitLineDataCount, TabletSetupData.tabletSplitLineData);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SplitLineImageSelectionBtnClick(
      TObject *Sender)
{
  SelectedImageN[0] = 0;
	SelectedImageN[1] = 0;

	GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = false;
	Panel5->Visible = false;
	BitBtn9->Visible = false;
	SpeedButton1->Click();
	GroupBox1->Visible = true;
	SelectedWorkSW[0] = 0;
	SelectedWorkSW[1] = 0;
	ImageSelectActiveSW = 1;
	Graphics::TBitmap *img1;

  SpeedButton1->Visible = false;
  SpeedButton2->Visible = false;

	img1 = new Graphics::TBitmap();
	for (int i = 1; i <= 30; i++)
	{
    ExtractImage(img1, i, SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

		if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
		{
			if (!ReductionImageScale(img1)) continue;
		}

		((TTntImage *)FindComponent("CaptureImage" + IntToStr(i)))->Picture->Bitmap->Assign(img1);
		((TTntImage *)FindComponent("CaptureImage" + IntToStr(i)))->Stretch = true;
		((TTntImage *)FindComponent("CaptureImage" + IntToStr(i)))->Refresh();
		Image1->Picture->Bitmap->Assign(img1);
	}
	delete(img1);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SetBlankImage(TTntImage *dstImage)
{
  Graphics::TBitmap *blankImage = new Graphics::TBitmap;
  blankImage->Width = MAX_IMAGE_WIDTH;
  blankImage->Height = MAX_IMAGE_HEIGHT;
  blankImage->PixelFormat = pf24bit;

  int x, y;
  Byte *ptr;

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (Byte*)blankImage->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;
    }
  }

  dstImage->Picture->Bitmap->Assign(blankImage);
  dstImage->Refresh();

  delete blankImage;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SplitLineExtractionBtnClick(
      TObject *Sender)
{
  GroupBox17->Visible = false;
	GroupBox18->Visible = false;
	SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;
	GroupBox20->Visible = false;
  ExtractionSplitLineGroupBox->Visible = false;
	Panel5->Visible = false;
	GroupBox7->Visible = false;
	GroupBox8->Visible = false;
	GroupBox14->Visible = false;
	GroupBox11->Visible = false;
	Panel17->Visible = false;
	Image9->Visible = false;
	GroupBox6->Visible = true;
	PrintMaskingButton->Visible = true;
	PrintManualExtractButton->Visible = false;
	ETC_InformationExtractButton->Visible = false;
	PrintExtractWorkEndButton->Visible = false;
	GroupBox27->Visible = false;
	ZoomOptionBox->Visible = false;

	Panel18->Color = clBlack;
	Panel19->Color = clBlack;

	zoomInOutShiftX = 0;
	zoomInOutShiftY = 0;
	zoomInOutSize = 2;

  GroupBox8->Width = 447;
	PrintTHGB->Visible = false;
	ManualWorkEndButton->Width = 401;

	SelectedFace = 0;
	Byte *ptr;
	AnsiString str;
  ExtractImage(SelectedImage, SelectedImageN[0], SD1_2D_FRONT_FACE_CAMERA_INDEX, TabletSetupData.ImageOffSetSW[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], TabletSetupData.referenceImageForOffset[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1], ProductData.SubSamplingMode);

	if (CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D && ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
	{
		ReductionImageScale(SelectedImage);
	}

	Image5->Picture->Bitmap->Assign(SelectedImage1);
	PrintMaskSW = 0;
	ImageDownSW = 0;
	ManualCorrectSW = 0;

	DrawMaskWidth = 10;
	MaskWidth = 20;
	ManualWorkAreaWidth = 15;

	for (int y = 0; y < ImageHeight; y++)
	{
		ptr = (byte*)SelectedImage->ScanLine[y];
		for (int x = 0; x < ImageWidth; x++)
		{
			PrintMaskArea[y*ImageWidth + x] = 0;
		}
	}
	ShapeMatching(ImageWidth, ImageHeight);  
}
//---------------------------------------------------------------------------
bool __fastcall TTabletCharacterExtractForm::SplitLineInformationCalculation(void)
{
	int Pixel_N_Of_Label[MAX_LABEL_COUNT];
	int rX, rY;
	int tx, ty;
	int i, j;
	int n, m, k;
	short label_Image[640 * 480];
	int printCenterX, printCenterY;
	int tempCount;
	int labelN;
  int maxLabelN;
  int maxLabelSize;
  int tempAddress;

	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;

  labelN = PrintLabeling(PrintBinarizationData, label_Image, Pixel_N_Of_Label);

  maxLabelN = 0;
  maxLabelSize = -1;
  for(m = 0; m <= labelN; m++)
  {
    if(maxLabelSize < Pixel_N_Of_Label[m])
    {
      maxLabelSize = Pixel_N_Of_Label[m];
      maxLabelN = m;
    }
  }

  printCenterX = AdjustCenterXInImage;
  printCenterY = AdjustCenterYInImage;

  TabletSetupData.tabletSplitLineDataCount = 0;
  memset(TabletSetupData.tabletSplitLineData, 0, sizeof(short) * PRINT_DATA_SIZE * 2);

  print1ExtractUnusalSW = 0;

  for (int y = 10; y < ImageHeight - 10; y++)
  {
    for (int x = 10; x < ImageWidth - 10; x++)
    {
      tempAddress = y*ImageWidth + x;

      labelN = label_Image[tempAddress];
      if (PrintBinarizationData[y*ImageWidth + x])
      {
        if(labelN == maxLabelN)
        {
          rX = cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) - sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterX;
          rY = sin(RotationAngleInSelectedImage*PI / 180.0)*(float)(x - printCenterX) + cos(RotationAngleInSelectedImage*PI / 180.0)*(float)(y - printCenterY) + printCenterY;

          TabletSetupData.tabletSplitLineData[TabletSetupData.tabletSplitLineDataCount][0] = rX - (printCenterX - ImageWidth / 2);
          TabletSetupData.tabletSplitLineData[TabletSetupData.tabletSplitLineDataCount][1] = rY - (printCenterY - ImageHeight / 2);
          TabletSetupData.tabletSplitLineDataCount++;
        }
      }
    }
  }

  /////////////////////Display///////////////////////////

  for (int y = 0; y < ImageHeight; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for (int x = 0; x < ImageWidth; x++)
    {
      ptr[3 * x + 0] = 255;
      ptr[3 * x + 1] = 255;
      ptr[3 * x + 2] = 255;
    }
  }

  for (int m = 0; m < TabletSetupData.tabletSplitLineDataCount; m++)
  {
    tx = TabletSetupData.tabletSplitLineData[m][0];
    ty = TabletSetupData.tabletSplitLineData[m][1];
    ptr = (byte*)img1->ScanLine[ty];
    ptr[3 * tx] = 0;
    ptr[3 * tx + 1] = 0;
    ptr[3 * tx + 2] = 0;
  }

  Image5->Picture->Bitmap->Assign(img1);
  Image5->Refresh();

  ExtractedSplitLineImage->Picture->Bitmap->Assign(img1);
  ExtractedSplitLineImage->Stretch = true;
  ExtractedSplitLineImage->Refresh();

  delete(img1);
}

//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::DisplayExistData(TTntImage *Destination, int dataCount, short arr[][2])
{
  int m;
  int x, y;
  int tx, ty;

  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;

  for (int y = 0; y < ImageHeight; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for (int x = 0; x < ImageWidth; x++)
    {
      ptr[3 * x + 0] = 255;
      ptr[3 * x + 1] = 255;
      ptr[3 * x + 2] = 255;
    }
  }

  for (int m = 0; m < dataCount; m++)
  {
    tx = arr[m][0];
    ty = arr[m][1];
    ptr = (byte*)img1->ScanLine[ty];

    ptr[3 * tx] = 0;
    ptr[3 * tx + 1] = 0;
    ptr[3 * tx + 2] = 0;
  }

  Destination->Stretch = true;
  Destination->Picture->Bitmap->Assign(img1);
  Destination->Refresh();

  delete(img1);
}

//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SimilarPrintSettingBtnClick(
      TObject *Sender)
{
  SimilarPrintSettingPanel->Visible = true;
  SimilarPrintSettingPanel->BringToFront();

  Label8->Visible = false;
  PrintSimilarCheckResultGroupBox->Visible = false;
  SimilarPrintOptionGroupBox->Visible = false;

  CheckPrintSimliarResultBtn->Enabled = true;
  PrintSimliarCheckCloseBtn->Visible = false;

  SimilarPrintSettingPanel->DoubleBuffered = true;

  LoadExtractedPrintData();

  // 해당 메뉴에 들어오면 무조건 초기화 되는 걸로
  memset(TabletSetupData.SimilarPrint1MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  memset(TabletSetupData.SimilarPrint2MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  TabletSetupData.ApplySimilarPrintMatchingAlgorithm = 0;
}

//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::LoadExtractedPrintData()
{
  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
  img1->Width = MAX_IMAGE_WIDTH;
  img1->Height = MAX_IMAGE_HEIGHT;
  img1->PixelFormat = pf24bit;

	Byte *ptr;

  int x, y;
  int tempAddress;

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;
    }
  }

  for (int m = 0; m < TabletSetupData.printData1Count; m++)
  {
    x = TabletSetupData.position_printData1[m][0];
    y = TabletSetupData.position_printData1[m][1];

    ptr = (byte*)img1->ScanLine[y];

    ptr[3*x + 0] = 255;
    ptr[3*x + 1] = 255;
    ptr[3*x + 2] = 255;
  }

  PrintResultImage1->Picture->Bitmap->Assign(img1);
  PrintResultImage1->Refresh();

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;
    }
  }

  for (int m = 0; m < TabletSetupData.printData2Count; m++)
  {
    x = TabletSetupData.position_printData2[m][0];
    y = TabletSetupData.position_printData2[m][1];

    ptr = (byte*)img1->ScanLine[y];

    ptr[3*x + 0] = 255;
    ptr[3*x + 1] = 255;
    ptr[3*x + 2] = 255;
  }

  PrintResultImage2->Picture->Bitmap->Assign(img1);
  PrintResultImage2->Refresh();

  delete img1;
}

//---------------------------------------------------------------------------
                                                                          
void __fastcall TTabletCharacterExtractForm::LoadPrintSimilarCheckResult()
{
  CheckPrintSimliarResultBtn->Enabled = false;

  unsigned char *DestPrint;
  DestPrint = TempImage;
  unsigned char *SrcPrint;
  SrcPrint = TempImage2;

  int x, y;
  int tempAddress;

  memset(DestPrint, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
  img1->Width = MAX_IMAGE_WIDTH;
  img1->Height = MAX_IMAGE_HEIGHT;
  img1->PixelFormat = pf24bit;

	Byte *ptr;

  for (int m = 0; m < TabletSetupData.printData1Count; m++)
  {
    x = TabletSetupData.position_printData1[m][0];
    y = TabletSetupData.position_printData1[m][1];

    DestPrint[MAX_IMAGE_WIDTH * y + x] = 255;
  }

  PrintABSimilarCheckResultImage->Picture->Bitmap->Assign(img1);
  PrintABSimilarCheckResultImage->Refresh();

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;
    }
  }

  int cosData[720];
	int sinData[720];
	for (int i = 0; i < 720; i++)
	{
		cosData[i] = cos((float)i / 2.0*PI / 180.0) * 1024;
		sinData[i] = sin((float)i / 2.0*PI / 180.0) * 1024;
	}

  int tabletCenterX, tabletCenterY;
  tabletCenterX = MAX_IMAGE_WIDTH / 2;
  tabletCenterY = MAX_IMAGE_HEIGHT / 2;

  int rX, rY;

  int matchingValue;

  const int MAX_RotationAngle = 720;
  const int MAX_ShiftX = 12;
  const int MAX_ShiftY = 12;

  PrintMatchingProgressBar->Max = (MAX_RotationAngle / 2) * (MAX_ShiftX * 2 + 1) * (MAX_ShiftX * 2 + 1);
  PrintMatchingProgressBar->Position = 0;
  PrintMatchingProgressBar->Visible = true;

  maxMatchingValue = 0;
  for (int r = 0; r < MAX_RotationAngle; r+=2)
  {
    for(int shiftY = -MAX_ShiftY; shiftY <= MAX_ShiftY; shiftY++)
    {
      for(int shiftX = -MAX_ShiftX; shiftX <= MAX_ShiftX; shiftX++)
      {
        matchingValue = 0;
        memset(SrcPrint, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
        for (int m = 0; m < TabletSetupData.printData2Count; m++)
        {
          x = TabletSetupData.position_printData2[m][0];
          y = TabletSetupData.position_printData2[m][1];

          if (r >= 0)
          {
            rX = ((x - tabletCenterX) * cosData[r] - (y - tabletCenterY)* sinData[r]) / 1024 + tabletCenterX + shiftX;
            rY = ((x - tabletCenterX) * sinData[r] + (y - tabletCenterY)* cosData[r]) / 1024 + tabletCenterY + shiftY;
          }
          else
          {
            rX = ((x - tabletCenterX) * cosData[-r] + (y - tabletCenterY) * sinData[-r]) / 1024 + tabletCenterX + shiftX;
            rY = (-(x - tabletCenterX) * sinData[-r] + (y - tabletCenterY) * cosData[-r]) / 1024 + tabletCenterY + shiftY;
          }

          if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
          {
            SrcPrint[MAX_IMAGE_WIDTH * rY + rX] = 255;

            if (DestPrint[MAX_IMAGE_WIDTH * rY + rX])
            {
              matchingValue++;
            }
          }
        }

        if(maxMatchingValue < matchingValue)
        {
          matchingAngle = r;
          maxMatchingValue = matchingValue;
          matchingShiftX = shiftX;
          matchingShiftY = shiftY;

          for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
          {
            ptr = (byte*)img1->ScanLine[y];
            for(x = 0; x < MAX_IMAGE_WIDTH; x++)
            {
              tempAddress = MAX_IMAGE_WIDTH * y + x;

              ptr[3*x + 0] = 0;
              ptr[3*x + 1] = 0;
              ptr[3*x + 2] = 0;

              if(DestPrint[tempAddress] && SrcPrint[tempAddress])
              {
                ptr[3*x + 0] = 0;
                ptr[3*x + 1] = 255;
                ptr[3*x + 2] = 0;
              }
              else if(!DestPrint[tempAddress] && SrcPrint[tempAddress])
              {
                ptr[3*x + 0] = 160;
                ptr[3*x + 1] = 160;
                ptr[3*x + 2] = 160;
              }
              else if(DestPrint[tempAddress] && !SrcPrint[tempAddress])
              {
                ptr[3*x + 0] = 96;
                ptr[3*x + 1] = 96;
                ptr[3*x + 2] = 96;
              }
            }
          }

          PrintABSimilarCheckResultImage->Picture->Bitmap->Assign(img1);
          PrintABSimilarCheckResultImage->Refresh();
          Sleep(10);
        }

        PrintMatchingProgressBar->Position++;



        Application->ProcessMessages();
      }
    }
  }

  memset(SrcPrint, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  for (int m = 0; m < TabletSetupData.printData2Count; m++)
  {
    x = TabletSetupData.position_printData2[m][0];
    y = TabletSetupData.position_printData2[m][1];

    if (matchingAngle >= 0)
    {
      rX = ((x - tabletCenterX) * cosData[matchingAngle] - (y - tabletCenterY)* sinData[matchingAngle]) / 1024 + tabletCenterX + matchingShiftX;
      rY = ((x - tabletCenterX) * sinData[matchingAngle] + (y - tabletCenterY)* cosData[matchingAngle]) / 1024 + tabletCenterY + matchingShiftY;
    }
    else
    {
      rX = ((x - tabletCenterX) * cosData[-matchingAngle] + (y - tabletCenterY) * sinData[-matchingAngle]) / 1024 + tabletCenterX + matchingShiftX;
      rY = (-(x - tabletCenterX) * sinData[-matchingAngle] + (y - tabletCenterY) * cosData[-matchingAngle]) / 1024 + tabletCenterY + matchingShiftY;
    }

    if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
    {
      SrcPrint[MAX_IMAGE_WIDTH * rY + rX] = 255;
    }
  }

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;

      if(DestPrint[tempAddress] && SrcPrint[tempAddress])
      {
        ptr[3*x + 0] = 0;
        ptr[3*x + 1] = 255;
        ptr[3*x + 2] = 0;
      }
      else if(!DestPrint[tempAddress] && SrcPrint[tempAddress])
      {
        ptr[3*x + 0] = 255;
        ptr[3*x + 1] = 0;
        ptr[3*x + 2] = 255;
      }
      else if(DestPrint[tempAddress] && !SrcPrint[tempAddress])
      {
        ptr[3*x + 0] = 0;
        ptr[3*x + 1] = 255;
        ptr[3*x + 2] = 255;
      }
    }
  }

  PrintABSimilarCheckResultImage->Picture->Bitmap->Assign(img1);
  PrintABSimilarCheckResultImage->Refresh();

  PrintMatchingProgressBar->Visible = false;

  delete img1;

  CheckPrintSimliarResultBtn->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::PrintSimliarCheckCloseBtnClick(
      TObject *Sender)
{
  if(TabletSetupData.ApplySimilarPrintMatchingAlgorithm)
  {
    if (MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_27, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
    {
      SimilarPrintSettingPanel->Visible = false;
    }
    else
    {
      return;
    }
  }
  else
  {
    if (MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_25, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
    {
      SimilarPrintSettingPanel->Visible = false;
    }
    else
    {
      return;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::CheckPrintSimliarResultBtnClick(
      TObject *Sender)
{
  Label8->Visible = true;
  PrintSimilarCheckResultGroupBox->Visible = true;
  PrintSimliarCheckCloseBtn->Visible = false;
  SimilarPrintOptionGroupBox->Visible = false;

  memset(TabletSetupData.SimilarPrint1MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  memset(TabletSetupData.SimilarPrint2MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  TabletSetupData.ApplySimilarPrintMatchingAlgorithm = 0;
  memset(SimilarPrintMaskImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  LoadPrintSimilarCheckResult();

  SimilarPrintOptionGroupBox->Visible = true;
  PrintSimliarCheckCloseBtn->Visible = true;

  SimilarPrintSettingSizeEdit->Text = "3";
  SimilarPrintDrawRadioBox->Checked = true;
}
//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::SimilarPrintSettingSizeEditKeyPress(
      TObject *Sender, char &Key)
{
  Key = NULL;
  return;
}
//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::PrintABSimilarCheckResultImageMouseDown(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
  if(SimilarPrintOptionGroupBox->Visible)
  {
    ImageDownSW = true;
    int tempX = X * MAX_IMAGE_WIDTH / PrintABSimilarCheckResultImage->Width;
    int tempY = Y * MAX_IMAGE_HEIGHT / PrintABSimilarCheckResultImage->Height;
    EditSimilarPrint(tempX, tempY);
  }
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::PrintABSimilarCheckResultImageMouseUp(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
  ImageDownSW = false;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::PrintABSimilarCheckResultImageMouseMove(
      TObject *Sender, TShiftState Shift, int X, int Y)
{
  if(ImageDownSW)
  {
    int tempX = X * MAX_IMAGE_WIDTH / PrintABSimilarCheckResultImage->Width;
    int tempY = Y * MAX_IMAGE_HEIGHT / PrintABSimilarCheckResultImage->Height;
    EditSimilarPrint(tempX, tempY);
  }
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::EditSimilarPrint(int tempX, int tempY)
{
  unsigned char *DestPrint;
  DestPrint = TempImage;
  unsigned char *SrcPrint;
  SrcPrint = TempImage2;

  int size = StrToInt(SimilarPrintSettingSizeEdit->Text);

  int x, y;
  int tempAddress;

  for(y = tempY - size; y <= tempY + size; y++)
  {
    for(x = tempX - size; x <= tempX + size; x++)
    {
      if(x > 0 && x < MAX_IMAGE_WIDTH && y > 0 && y < MAX_IMAGE_HEIGHT)
      {
        tempAddress = MAX_IMAGE_WIDTH * y + x;

        if(DestPrint[tempAddress] || SrcPrint[tempAddress])
        {
          if(SimilarPrintDrawRadioBox->Checked)
          {
            SimilarPrintMaskImage[tempAddress] = 1;
          }
          else
          {
            SimilarPrintMaskImage[tempAddress] = 0;
          }
        }
      }
    }
  }

  RefreshPrintABMatchingResultImage(tempX, tempY);
}

//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::InitSimilarPrintMaskBtnClick(
      TObject *Sender)
{
  memset(TabletSetupData.SimilarPrint1MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  memset(TabletSetupData.SimilarPrint2MaskInfo, 0, sizeof(short) * PRINT_DATA_SIZE);
  TabletSetupData.ApplySimilarPrintMatchingAlgorithm = 0;

  LoadExtractedPrintData();
  
  memset(SimilarPrintMaskImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  RefreshPrintABMatchingResultImage(0, 0);
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::RefreshPrintABMatchingResultImage(int tempX, int tempY)
{
  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
  img1->Width = MAX_IMAGE_WIDTH;
  img1->Height = MAX_IMAGE_HEIGHT;
  img1->PixelFormat = pf24bit;

	Byte *ptr;

  unsigned char *DestPrint;
  DestPrint = TempImage;
  unsigned char *SrcPrint;
  SrcPrint = TempImage2;

  int x, y, tempAddress;

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;

      if(DestPrint[tempAddress] || SrcPrint[tempAddress])
      {
        ptr[3*x + 0] = 255;
        ptr[3*x + 1] = 255;
        ptr[3*x + 2] = 255;
      }

      if(SimilarPrintMaskImage[tempAddress])
      {
        ptr[3*x + 0] = 0;
        ptr[3*x + 1] = 0;
        ptr[3*x + 2] = 255;
      }
    }
  }

  int size = StrToInt(SimilarPrintSettingSizeEdit->Text);

  PrintABSimilarCheckResultImage->Picture->Bitmap->Assign(img1);

  if(tempX && tempY)
  {
    PrintABSimilarCheckResultImage->Canvas->Brush->Style = bsClear;
    PrintABSimilarCheckResultImage->Canvas->Pen->Color = clLime;
    PrintABSimilarCheckResultImage->Canvas->Pen->Width = 1;
    PrintABSimilarCheckResultImage->Canvas->Rectangle(tempX - size, tempY - size, tempX + size, tempY + size);
  }

  PrintABSimilarCheckResultImage->Refresh();

  delete img1;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::SimilarPrintSettingSizeEditClick(
      TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *)Sender;
	KeyboardForm->Text = theEdit->Text;
	if (KeyboardForm->ShowKeypad() == mrOk)
  {
    TEdit *EditText = (TEdit*)Sender;
    EditText->Text = KeyboardForm->Text;
  }  
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SimilarPrintSettingSizeEditKeyDown(
      TObject *Sender, WORD &Key, TShiftState Shift)
{
  Key = NULL;
  return;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ApplyDiffPrintAreaBtnClick(
      TObject *Sender)
{
  unsigned char dummy[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];
  memset(dummy, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  if(!memcmp(SimilarPrintMaskImage, dummy, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT))
  {
    MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_29, mtConfirmation, TMsgDlgButtons() << mbOK);
    return;
  }

  ApplySimilarPrintMaskInfo();
  
  short dummy2[PRINT_DATA_SIZE];
  memset(dummy2, 0, sizeof(short) * PRINT_DATA_SIZE);

  if(!memcmp(TabletSetupData.SimilarPrint1MaskInfo, dummy2, sizeof(short) * PRINT_DATA_SIZE) ||
      !memcmp(TabletSetupData.SimilarPrint2MaskInfo, dummy2, sizeof(short) * PRINT_DATA_SIZE))
  {
    MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_30, mtConfirmation, TMsgDlgButtons() << mbOK);
    return;
  }

  TabletSetupData.ApplySimilarPrintMatchingAlgorithm = 1;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ApplySimilarPrintMaskInfo()
{
  int x, y;
  int tempAddress;

  for (int m = 0; m < TabletSetupData.printData1Count; m++)
  {
    x = TabletSetupData.position_printData1[m][0];
    y = TabletSetupData.position_printData1[m][1];

    tempAddress = MAX_IMAGE_WIDTH * y + x;
    if(SimilarPrintMaskImage[tempAddress])
    {
      TabletSetupData.SimilarPrint1MaskInfo[m] = 1;
    }
  }

  int rX, rY;
  int tabletCenterX, tabletCenterY;
  tabletCenterX = MAX_IMAGE_WIDTH / 2;
  tabletCenterY = MAX_IMAGE_HEIGHT / 2;

  int cosData[720];
	int sinData[720];
	for (int i = 0; i < 720; i++)
	{
		cosData[i] = cos((float)i / 2.0*PI / 180.0) * 1024;
		sinData[i] = sin((float)i / 2.0*PI / 180.0) * 1024;
	}
  
  for (int m = 0; m < TabletSetupData.printData2Count; m++)
  {
    x = TabletSetupData.position_printData2[m][0];
    y = TabletSetupData.position_printData2[m][1];

    if (matchingAngle >= 0)
    {
      rX = ((x - tabletCenterX) * cosData[matchingAngle] - (y - tabletCenterY)* sinData[matchingAngle]) / 1024 + tabletCenterX + matchingShiftX;
      rY = ((x - tabletCenterX) * sinData[matchingAngle] + (y - tabletCenterY)* cosData[matchingAngle]) / 1024 + tabletCenterY + matchingShiftY;
    }
    else
    {
      rX = ((x - tabletCenterX) * cosData[-matchingAngle] + (y - tabletCenterY) * sinData[-matchingAngle]) / 1024 + tabletCenterX + matchingShiftX;
      rY = (-(x - tabletCenterX) * sinData[-matchingAngle] + (y - tabletCenterY) * cosData[-matchingAngle]) / 1024 + tabletCenterY + matchingShiftY;
    }

    if (rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
    {
      tempAddress = MAX_IMAGE_WIDTH * rY + rX;
      if(SimilarPrintMaskImage[tempAddress])
      {
        TabletSetupData.SimilarPrint2MaskInfo[m] = 1;
      }
    }
  }

  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
  img1->Width = MAX_IMAGE_WIDTH;
  img1->Height = MAX_IMAGE_HEIGHT;
  img1->PixelFormat = pf24bit;

	Byte *ptr;

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;
    }
  }

  for (int m = 0; m < TabletSetupData.printData1Count; m++)
  {
    x = TabletSetupData.position_printData1[m][0];
    y = TabletSetupData.position_printData1[m][1];

    ptr = (byte*)img1->ScanLine[y];

    if(!TabletSetupData.SimilarPrint1MaskInfo[m])
    {
      ptr[3*x + 0] = 255;
      ptr[3*x + 1] = 255;
      ptr[3*x + 2] = 255;
    }
    else
    {
      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 255;
    }
  }

  PrintResultImage1->Picture->Bitmap->Assign(img1);
  PrintResultImage1->Refresh();

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (byte*)img1->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 0;
    }
  }

  for (int m = 0; m < TabletSetupData.printData2Count; m++)
  {
    x = TabletSetupData.position_printData2[m][0];
    y = TabletSetupData.position_printData2[m][1];

    ptr = (byte*)img1->ScanLine[y];

    if(!TabletSetupData.SimilarPrint2MaskInfo[m])
    {
      ptr[3*x + 0] = 255;
      ptr[3*x + 1] = 255;
      ptr[3*x + 2] = 255;
    }
    else
    {
      ptr[3*x + 0] = 0;
      ptr[3*x + 1] = 0;
      ptr[3*x + 2] = 255;
    }
  }

  PrintResultImage2->Picture->Bitmap->Assign(img1);
  PrintResultImage2->Refresh();

  delete img1;
}

//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::SetupdataStatusTimerTimer(
      TObject *Sender)
{
  WideString tempStr = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_15;
  if(TabletSetupData.ApplySimilarPrintMatchingAlgorithm)
  {
    SimilarPrintSettingBtn->Caption = tempStr + " (On)";
    SimilarPrintSettingBtn2->Caption = tempStr + " (On)";
  }
  else
  {
    SimilarPrintSettingBtn->Caption = tempStr + " (Off)";
    SimilarPrintSettingBtn2->Caption = tempStr + " (Off)";
  }

  if(SetupMode == TABLET_SETUP_MODE_REVISION)
  {
    ShapExtractButton->Visible = false;
    DiscrimiationMarkExtract->Visible = false;
    GetThreeDInfoButton->Visible = false;
    ThreeDDiscriminationExtractButton->Visible = false;
    ReadHistoryButton->Visible = false;
  }
}
//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::GetThreeDInfoButtonClick(
      TObject *Sender)
{
  TabletShapeSize = 0;
  for(int y = 0; y < HALF_IMAGE_HEIGHT; y++)
  {
    for(int x = 0; x < HALF_IMAGE_WIDTH; x++)
    {
      int tempAddress = HALF_IMAGE_WIDTH * y + x;

      if(TabletSetupData.FrontshapeAreaData[tempAddress])
      {
        TabletShapeSize++;
      }
    }
  }

  TabletShapeSize = TabletShapeSize * 4;
  
  if (TabletShapeSize == 0)
	{
		MessageDlgFA(TABLETCHARACTEREXTRACTFORM_BITBTN_CAPTION_29, mtConfirmation, TMsgDlgButtons() << mbOK);
		return;
	}
  
  if(CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D ||
      CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
  {
    ReadHistoryButton->Visible = false;
    
    Extraction3DInfoGroupBox->Visible = true;
    Extraction3DInfoGroupBox->BringToFront();

    ExtractThreeInformation();
  }
  else
  {
    MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_08, mtConfirmation, TMsgDlgButtons() << mbOK);
    ReadHistoryButton->Visible = true;
    return;
  }
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ExtractThreeInformation()
{
  ExtractThreeInfoCloseBtn->Enabled = false;
  
  GetThreeDThresholdGroupBox->Visible = false;
  NormalizedThreeDImageGroupBox->Visible = false;

  ThreeDImageProgressBar->Position = 0;
  RotationProgressbar->Position = 0;
  NormalizedProgressbar->Position = 0;

  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();

  Disk1MinHeightDiff = Disk2MinHeightDiff = 0x0FFFFFFF;
  Disk1BestNotiltImageIndex = Disk2BestNotiltImageIndex = 0;
  Disk1OutlineAverageHeight = Disk2OutlineAverageHeight = 0;
  Disk1OutlineMinThreshold = Disk2OutlineMinThreshold = 0xFFFF;

  TabletSetupData.Disk1ThreeDMinThreshold = 0;
  TabletSetupData.Disk2ThreeDMinThreshold = 0;

  TabletSetupData.Disk1ThreeDNormalizedValue = 0;
  TabletSetupData.Disk2ThreeDNormalizedValue = 0;

  TabletSetupData.Disk1AverageMaxHeight = 0;
  TabletSetupData.Disk2AverageMaxHeight = 0;

  Disk1BestImageIndexLabel->Visible = false;
  Disk2BestImageIndexLabel->Visible = false;
  Disk1ThresholdLabel->Visible = false;
  Disk2ThresholdLabel->Visible = false;
  Disk1NormalizedValueLabel->Visible = false;
  Disk2NormalizedValueLabel->Visible = false;

  for(int m = 0; m < 100; m++)
  {
    Disk1HeightInfo[m] = -1;
    Disk2HeightInfo[m] = -1;
  }

  for(int ImageIndex = 1; ImageIndex <= 100; ImageIndex++)
  {
    if(CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      if(ExtractImage(img1, ImageIndex, SD1_3D_FRONT_FACE_CAMERA_INDEX, false, NULL, 0))
      {
        CapturedThreeDImageDisk1->Picture->Bitmap->Assign(img1);
        CapturedThreeDImageDisk1->Refresh();

        AnalysisThreeDTiltLevel(img1, SD1_3D_FRONT_FACE_CAMERA_INDEX, ImageIndex, 1);
      }
    }

    if(CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      if(ExtractImage(img1, ImageIndex, SD2_3D_FRONT_FACE_CAMERA_INDEX, false, NULL, 0))
      {
        CapturedThreeDImageDisk2->Picture->Bitmap->Assign(img1);
        CapturedThreeDImageDisk2->Refresh();

        AnalysisThreeDTiltLevel(img1, SD2_3D_FRONT_FACE_CAMERA_INDEX, ImageIndex, 1);
      }
    }

    ThreeDImageProgressBar->Position++;
    Application->ProcessMessages();
  }

  int heightSum, heightCount;

  heightSum = heightCount = 0;
  for(int m = 0; m < 100; m++)
  {
    if(Disk1HeightInfo[m] > 0)
    {
      heightSum += Disk1HeightInfo[m];
      heightCount++;
    }
  }

  if(heightCount)
  {
    TabletSetupData.Disk1AverageMaxHeight = heightSum / heightCount;
  }

  heightSum = heightCount = 0;
  for(int m = 0; m < 100; m++)
  {
    if(Disk2HeightInfo[m] > 0)
    {
      heightSum += Disk2HeightInfo[m];
      heightCount++;
    }
  }

  if(heightCount)
  {
    TabletSetupData.Disk2AverageMaxHeight = heightSum / heightCount;
  }

  Disk1BestImageIndexLabel->Visible = true;
  Disk2BestImageIndexLabel->Visible = true;

  Disk1BestImageIndexLabel->Caption = "#" + IntToStr(Disk1BestNotiltImageIndex);
  Disk2BestImageIndexLabel->Caption = "#" + IntToStr(Disk2BestNotiltImageIndex);

  memset(Disk1StdThreeDImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  if(CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
  {
    if(ExtractImage(img1, Disk1BestNotiltImageIndex, SD1_3D_FRONT_FACE_CAMERA_INDEX, false, NULL, 0))
    {
      CapturedThreeDImageDisk1->Picture->Bitmap->Assign(img1);
      CapturedThreeDImageDisk1->Refresh();

      AnalysisThreeDTiltLevel(img1, SD1_3D_FRONT_FACE_CAMERA_INDEX, NULL, 0);
      memcpy(Disk1StdThreeDImage, ThreeD_Image, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
    }
  }

  memset(Disk2StdThreeDImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  if(CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
  {
    if(ExtractImage(img1, Disk2BestNotiltImageIndex, SD2_3D_FRONT_FACE_CAMERA_INDEX, false, NULL, 0))
    {
      CapturedThreeDImageDisk2->Picture->Bitmap->Assign(img1);
      CapturedThreeDImageDisk2->Refresh();

      AnalysisThreeDTiltLevel(img1, SD2_3D_FRONT_FACE_CAMERA_INDEX, NULL, 0);
      memcpy(Disk2StdThreeDImage, ThreeD_Image, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
    }
  }

  delete img1;

  GetThreeDThresholdGroupBox->Visible = true;
  int AngleRange = 56;
  RotationProgressbar->Max = AngleRange * 2 + 1;

  for(int r = -AngleRange; r <= AngleRange; r++)
  {
    if(CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      GetThreeDThreshold(Disk1StdThreeDImage, r, SD1_3D_FRONT_FACE_CAMERA_INDEX);
    }

    if(CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      GetThreeDThreshold(Disk2StdThreeDImage, r, SD2_3D_FRONT_FACE_CAMERA_INDEX);
    }

    RotationProgressbar->Position++;
    Application->ProcessMessages();

    Sleep(100);
  }

  Disk1ThresholdLabel->Visible = true;
  Disk2ThresholdLabel->Visible = true;

  Disk1ThresholdLabel->Caption = "TH : " + IntToStr(Disk1OutlineMinThreshold);
  Disk2ThresholdLabel->Caption = "TH : " + IntToStr(Disk2OutlineMinThreshold);

  NormalizedThreeDImageGroupBox->Visible = true;

  int minNormalizedRange = 40;
  int AngleXZRange = 12;
  int AngleYZRange = 40;
  NormalizedProgressbar->Max = 255 - minNormalizedRange;

  int centerX, centerY, centerZ;
  int Disk1MinOverlapImageCount, Disk2MinOverlapImageCount;
  int Disk1NormalizedLevel, Disk2NormalizedLevel;
  Disk1MinOverlapImageCount = Disk2MinOverlapImageCount = 0xFFFFFF;
  Disk1NormalizedLevel = Disk1NormalizedLevel = 255;
  
  for(int normalizedValue = 255; normalizedValue >= minNormalizedRange; normalizedValue-=4)
  {
    if(CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      NormalizedThreeDImage(Disk1StdThreeDImage, normalizedValue, &centerX, &centerY, &centerZ, SD1_3D_FRONT_FACE_CAMERA_INDEX);
    }

    if(CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      NormalizedThreeDImage(Disk2StdThreeDImage, normalizedValue, &centerX, &centerY, &centerZ, SD2_3D_FRONT_FACE_CAMERA_INDEX);
    }

    if(CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      if(Disk1MinOverlapImageCount != 0)
      {
        memset(ThreeDEraseArea, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
        for(int xz = -AngleXZRange; xz <= AngleXZRange; xz+=4)
        {
          for(int yz = -AngleYZRange; yz <= AngleYZRange; yz+=8)
          {
            threeDRotation(Disk1NrmThreeDImage, centerX / 2, centerY / 2, centerZ, xz, yz, SD1_3D_FRONT_FACE_CAMERA_INDEX);

            Application->ProcessMessages();
          }
        }

        CheckOverlapArea(&Disk1MinOverlapImageCount, &Disk1NormalizedLevel, normalizedValue);
      }
    }

    if(CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      if(Disk2MinOverlapImageCount != 0)
      {
        memset(ThreeDEraseArea, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
        for(int xz = -AngleXZRange; xz <= AngleXZRange; xz+=4)
        {
          for(int yz = -AngleYZRange; yz <= AngleYZRange; yz+=8)
          {
            threeDRotation(Disk2NrmThreeDImage, centerX / 2, centerY / 2, centerZ, xz, yz, SD2_3D_FRONT_FACE_CAMERA_INDEX);

            Application->ProcessMessages();
          }
        }

        CheckOverlapArea(&Disk2MinOverlapImageCount, &Disk2NormalizedLevel, normalizedValue);
      }
    }
    
    NormalizedProgressbar->Position++;
    Application->ProcessMessages();

    if(Disk1MinOverlapImageCount == 0 && Disk2MinOverlapImageCount == 0)
    {
      break;
    }
  }

  MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_09, mtConfirmation, TMsgDlgButtons() << mbOK);

  NormalizedProgressbar->Position = NormalizedProgressbar->Max;

  Disk1NormalizedValueLabel->Visible = true;
  Disk2NormalizedValueLabel->Visible = true;

  Disk1NormalizedValueLabel->Caption = "NV : " + IntToStr(Disk1NormalizedLevel);
  Disk2NormalizedValueLabel->Caption = "NV : " + IntToStr(Disk2NormalizedLevel);

  ExtractThreeInfoCloseBtn->Enabled = true;

  TabletSetupData.Disk1ThreeDMinThreshold = Disk1OutlineMinThreshold;
  TabletSetupData.Disk2ThreeDMinThreshold = Disk2OutlineMinThreshold;

  TabletSetupData.Disk1ThreeDNormalizedValue = Disk1NormalizedLevel;
  TabletSetupData.Disk2ThreeDNormalizedValue = Disk2NormalizedLevel;
}

//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::AnalysisThreeDTiltLevel(Graphics::TBitmap *img, int cameraIndex, int imageIndex, int searchingSW)
{
  int x, y;
  int tempAddress;
  int startX, endX, startY, endY;
  int halfStartX, halfEndX;
  int value;
  Byte *ptr;

  startX = 10;
  endX = MAX_IMAGE_WIDTH - 10;
  startY = 10;
  endY = MAX_IMAGE_HEIGHT - 10;

  halfStartX = startX / 2;
  halfEndX = endX / 2;

  // half 사이즈 복원
  memset(ThreeD_Image, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	for (y = startY; y < endY; y++)
	{
    ptr = (Byte*)img->ScanLine[y];
		for (x = halfStartX; x < halfEndX; x++)
		{
			tempAddress = HALF_MAX_IMAGE_WIDTH * y + x;

      value = ptr[x];

      if(value)
      {
			  ThreeD_Image[MAX_IMAGE_WIDTH * y + x * 2 + 0] = value;
			  ThreeD_Image[MAX_IMAGE_WIDTH * y + x * 2 + 1] = value;
      }
		}
	}

  int halfImageWidth;
  int halfImageHeight;
  int halfstartX, halfendX, halfstartY, halfendY;
  int maxImgSize;
  int maxLabelN;
  int protoCenterX, protoCenterY, protoCenterZ;
  int tempCount;

	halfImageWidth = MAX_IMAGE_WIDTH / 2;
	halfImageHeight = MAX_IMAGE_HEIGHT / 2;

	halfstartX = startX / 2;
	halfendX = endX / 2;
	halfstartY = startY / 2;
	halfendY = endY / 2;

	maxImgSize = halfImageWidth * halfImageHeight;

	memset(HalfTempImage, 0, maxImgSize);
  memset(HalfLabelImage, 0, 2 * maxImgSize);

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = (y / 2) * halfImageWidth + (x / 2);

			HalfTempImage[tempAddress] = max(HalfTempImage[tempAddress], ThreeD_Image[MAX_IMAGE_WIDTH * y + x]);
		}
	}

	maxLabelN = LabellingForTabletImage(HalfLabelImage, HalfTempImage, halfstartX, halfendX, halfstartY, halfendY, halfImageWidth, halfImageHeight);
  
  protoCenterX = protoCenterY = protoCenterZ = tempCount = 0;
	if (maxLabelN != 0)
	{
    for (y = startY; y < endY; y++)
    {
      for (x = startX; x < endX; x++)
      {
        tempAddress = (y / 2) * halfImageWidth + (x / 2);

        if (HalfLabelImage[tempAddress] != maxLabelN)
        {
          ThreeD_Image[MAX_IMAGE_WIDTH * y + x] = 0;
        }
        else
        {
          protoCenterX += x;
          protoCenterY += y;
          protoCenterZ += HalfTempImage[tempAddress];
          tempCount++;
        }
      }
    }

    if(tempCount < TabletShapeSize * 70 / 100)
    {
      return;
    }
	}
  else
  {
    return;
  }

  if(tempCount)
  {
    protoCenterX /= tempCount;
    protoCenterY /= tempCount;
    protoCenterZ /= tempCount;
  }

  bool bImageError = false;
  for(y = startY; y < endY; y++)
  {
    if(ThreeD_Image[MAX_IMAGE_WIDTH * y + (startX + 4)])
    {
      bImageError = true;
      break;
    }

    if(ThreeD_Image[MAX_IMAGE_WIDTH * y + (endX - 4)])
    {
      bImageError = true;
      break;
    }
  }

  for(x = startX; x < endX; x++)
  {
    if(ThreeD_Image[MAX_IMAGE_WIDTH * (startY + 4) + x])
    {
      bImageError = true;
      break;
    }

    if(ThreeD_Image[MAX_IMAGE_WIDTH * (endY - 4) + x])
    {
      bImageError = true;
      break;
    }
  }

  if(bImageError) return;

  for (y = startY + 4; y < endY - 4; y++)
	{
		for (x = startX + 4; x < endX - 4; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
    }
  }

  unsigned char *outlineData = GradientImage;
  memset(outlineData, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

      if(ThreeD_Image[tempAddress])
      {
        if(ThreeD_Image[tempAddress - 2] == 0 ||
            ThreeD_Image[tempAddress + 2] == 0 ||
            ThreeD_Image[tempAddress - 2 * MAX_IMAGE_WIDTH] == 0 ||
            ThreeD_Image[tempAddress + 2 * MAX_IMAGE_WIDTH] == 0)
        {
          outlineData[tempAddress] = 1;
        }
      }
		}
	}

  int outlineInfoTable[361][4]; // length, height
  int pX, pY;
  int angle;
  int uLength;
  int sinV;

  memset(outlineInfoTable, 0, sizeof(int) * 361 * 4);
  for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;
			if (outlineData[tempAddress] == 1)
			{
        pX = x - protoCenterX;
        pY = y - protoCenterY;
        uLength = pX * pX + pY * pY;
        if (uLength < 90000)
        {
          uLength = SqrtData[uLength]; //sqrtdata는 128이 곱해 진 상태.
          sinV = 1280000 * pX / uLength;
          if (sinV > 10000) sinV = 10000;

          if (pX >= 0 && pY <= 0)
            angle = ArcSinData[sinV];
          else if (pX >= 0 && pY > 0)
            angle = 180 - ArcSinData[sinV];
          else if (pX < 0 && pY > 0)
            angle = 180 + ArcSinData[-sinV];
          else
            angle = 360 - ArcSinData[-sinV];

          if(angle >= 0 && angle < 360)
          {
            if(outlineInfoTable[angle][0] < uLength)
            {
              outlineInfoTable[angle][0] = uLength;
              outlineInfoTable[angle][1] = ThreeD_Image[tempAddress];
              outlineInfoTable[angle][2] = x;
              outlineInfoTable[angle][3] = y;
            }
          }
        }
			}
		}
	}

  int SymmetryAngle1;
  int SymmetryAngle2;
  int SymmetryAngle3;

  int heightDiffSum = 0;
  for(angle = 0; angle < 360; angle++)
  {
    SymmetryAngle1 = angle;
    SymmetryAngle2 = (angle + 120) % 360;
    SymmetryAngle3 = (angle + 240) % 360;

    if(outlineInfoTable[SymmetryAngle1][1] && outlineInfoTable[SymmetryAngle2][1] && outlineInfoTable[SymmetryAngle3][1])
    {
      heightDiffSum += abs(outlineInfoTable[SymmetryAngle1][1] - outlineInfoTable[SymmetryAngle2][1]) + abs(outlineInfoTable[SymmetryAngle1][1] - outlineInfoTable[SymmetryAngle3][1]) + abs(outlineInfoTable[SymmetryAngle2][1] - outlineInfoTable[SymmetryAngle3][1]);
    }
  }

  int tempX, tempY;
  int tempHeight;
  tempHeight = tempCount = 0;
  for(angle = 0; angle < 360; angle++)
  {
    if(outlineInfoTable[angle][1])
    {
      tempX = outlineInfoTable[angle][2];
      tempY = outlineInfoTable[angle][3];

      for(y = tempY - 2; y <= tempY + 2; y++)
      {
        for(x = tempX - 2; x <= tempX + 2; x++)
        {
          tempAddress = MAX_IMAGE_WIDTH * y + x;

          if(ThreeD_Image[tempAddress])
          {
            tempHeight += ThreeD_Image[tempAddress];
            tempCount++;
          }
        }
      }
    }
  }

  if(tempCount)
  {
    tempHeight /= tempCount;
  }

  if(searchingSW)
  {
    if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
    {
      if(Disk1MinHeightDiff > heightDiffSum)
      {
        Disk1MinHeightDiff = heightDiffSum;
        Disk1BestNotiltImageIndex = imageIndex;
        Disk1OutlineAverageHeight = tempHeight;
      }
    }
    else
    {
      if(Disk2MinHeightDiff > heightDiffSum)
      {
        Disk2MinHeightDiff = heightDiffSum;
        Disk2BestNotiltImageIndex = imageIndex;
        Disk2OutlineAverageHeight = tempHeight;
      }
    }

    int maxHeight = 0;
    for (y = startY; y < endY; y+=2)
    {
      for (x = startX; x < endX; x+=2)
      {
        tempAddress = MAX_IMAGE_WIDTH * y + x;

        if(ThreeD_Image[tempAddress])
        {
          if(maxHeight < ThreeD_Image[tempAddress])
          {
            maxHeight = ThreeD_Image[tempAddress];
          }
        }
      }
    }

    if(maxHeight)
    {
      if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
      {
        Disk1HeightInfo[imageIndex - 1] = maxHeight;
      }
      else
      {
        Disk2HeightInfo[imageIndex - 1] = maxHeight;
      }
    }
  }

  Graphics::TBitmap *tempImage;
	tempImage = new Graphics::TBitmap();
  tempImage->Width = MAX_IMAGE_WIDTH;
  tempImage->Height = MAX_IMAGE_HEIGHT;
  tempImage->PixelFormat = pf24bit;

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (Byte*)tempImage->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      ptr[3*x + 0] = ThreeD_Image[tempAddress];
      ptr[3*x + 1] = ThreeD_Image[tempAddress];
      ptr[3*x + 2] = ThreeD_Image[tempAddress];

      if(outlineData[tempAddress])
      {
        ptr[3*x + 0] = 0;
        ptr[3*x + 1] = 0;
        ptr[3*x + 2] = 255;
      }
    }
  }

  if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
  {
    CapturedThreeDImageDisk1->Picture->Bitmap->Assign(tempImage);
    CapturedThreeDImageDisk1->Refresh();
  }
  else
  {
    CapturedThreeDImageDisk2->Picture->Bitmap->Assign(tempImage);
    CapturedThreeDImageDisk2->Refresh();
  } 

  delete tempImage;
}

//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::threeDRotation(unsigned char *srcImage, int centerX, int centerY, int centerZ, int xzR, int yzR, int cameraIndex)
{
  int x, y, z;
  int tempAddress, tempAddress2;
  int xzCosValue, xzSinValue;
  int yzCosValue, yzSinValue;
  int rX, rY, rZ;
  int rX2, rY2, rZ2;
  int CosX, CosY, CosZ;
  int SinX, SinY, SinZ;
  int heightDiff;
  int tempHeight;
  int tempCount;
  unsigned char RotationThreeDImage[HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT];
  unsigned char tranformedThreeDImage[HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT];
  unsigned char halfSrcImage[HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT];
  int r;
  int upBinarySW, downBinarySW, leftBinarySW, rightBinarySW;
  int upThreeDHeight, downThreeDHeight, leftThreeDHeight, rightThreeDHeight;
  int srcHeight;
  int transformHeight;
  int shiftX, shiftY, shiftZ;
  int rotateHeight;
  int dX, dY, dZ;
  int minValue;
  int i, j;
  int startX, endX, startY, endY;

  startX = 10 / 2;
  endX = (MAX_IMAGE_WIDTH - 10) / 2;
  startY = 10 / 2;
  endY = (MAX_IMAGE_HEIGHT - 10) / 2;

  memset(halfSrcImage, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
  for(y = 10; y < MAX_IMAGE_HEIGHT - 10; y++)
  {
    for(x = 10; x < MAX_IMAGE_WIDTH - 10; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;
      if(srcImage[tempAddress])
      {
        halfSrcImage[HALF_IMAGE_WIDTH * (y / 2) + (x / 2)] = max(halfSrcImage[HALF_IMAGE_WIDTH * (y / 2) + (x / 2)], srcImage[tempAddress]);
      }
    }
  }

  memset(shiftInfoArray, 0, sizeof(short) * 3 * HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);

  xzCosValue = CosData[(xzR + 720) % 720];
  xzSinValue = SinData[(xzR + 720) % 720];
  
  yzCosValue = CosData[(yzR + 720) % 720];
  yzSinValue = SinData[(yzR + 720) % 720];

  memset(RotationThreeDImage, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);
  
  for(y = startY; y < endY; y++)
  {
    for(x = startX; x < endX; x++)
    {
      tempAddress = HALF_IMAGE_WIDTH * y + x;

      z = halfSrcImage[tempAddress];

      if(z > 0)
      {
        rX = (((x - centerX) * xzCosValue + (z - centerZ) * xzSinValue) / 1024) + centerX;
        rY = y;
        rZ = (( - (x - centerX) * xzSinValue + (z - centerZ) * xzCosValue) / 1024) + centerZ;

        if(rZ < 0) rZ = 0;
        if(rZ > 255) rZ = 255;

        rX2 = rX;
        rY2 = (((rY - centerY) * yzCosValue - (rZ - centerZ) * yzSinValue) / 1024) + centerY;
        rZ2 = (((rY - centerY) * yzSinValue + (rZ - centerZ) * yzCosValue) / 1024) + centerZ;

        if(rZ2 < 0) rZ2 = 0;
        if(rZ2 > 255) rZ2 = 255;
        
        tempAddress = HALF_IMAGE_WIDTH * rY2 + rX2;

        if(rX2 > 0 && rX2 < HALF_IMAGE_WIDTH && rY2 > 0 && rY2 < HALF_IMAGE_HEIGHT)
        {
          RotationThreeDImage[tempAddress] = max(RotationThreeDImage[tempAddress], rZ2);

          shiftInfoArray[HALF_IMAGE_WIDTH * y + x][0] = rX2;
          shiftInfoArray[HALF_IMAGE_WIDTH * y + x][1] = rY2;
          shiftInfoArray[HALF_IMAGE_WIDTH * y + x][2] = rZ2;
        }
      }
    }
  }

  memcpy(tranformedThreeDImage, RotationThreeDImage, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);

  for(y = startY; y < endY; y++)
  {
    for(x = startX; x < endX; x++)
    {
      tempAddress = HALF_IMAGE_WIDTH * y + x;

      transformHeight = tranformedThreeDImage[tempAddress];

      if(transformHeight == 0)
      {
        upBinarySW = downBinarySW = leftBinarySW = rightBinarySW = 0;
        upThreeDHeight = downThreeDHeight = leftThreeDHeight = rightThreeDHeight = 0;

        tempCount = 0;
        for(r = 2; r >= 0; r--)
        {
          if(tranformedThreeDImage[tempAddress - r])
          {
            leftBinarySW = 1;
            leftThreeDHeight += tranformedThreeDImage[tempAddress - r];
            tempCount++;
          }
        }

        if(tempCount)
        {
          leftThreeDHeight /= tempCount;
        }

        tempCount = 0;
        for(r = 2; r >= 0; r--)
        {
          if(tranformedThreeDImage[tempAddress + r])
          {
            rightBinarySW = 1;
            rightThreeDHeight += tranformedThreeDImage[tempAddress + r];
            tempCount++;
          }
        }

        if(tempCount)
        {
          rightThreeDHeight /= tempCount;
        }

        tempCount = 0;
        for(r = 2; r >= 0; r--)
        {
          if(tranformedThreeDImage[tempAddress - r * HALF_IMAGE_WIDTH])
          {
            upBinarySW = 1;
            upThreeDHeight += tranformedThreeDImage[tempAddress - r * HALF_IMAGE_WIDTH];
            tempCount++;
          }
        }

        if(tempCount)
        {
          upThreeDHeight /= tempCount;
        }

        tempCount = 0;
        for(r = 2; r >= 0; r--)
        {
          if(tranformedThreeDImage[tempAddress + r * HALF_IMAGE_WIDTH])
          {
            downBinarySW = 1;
            downThreeDHeight += tranformedThreeDImage[tempAddress + r * HALF_IMAGE_WIDTH];
            tempCount++;
          }
        }

        if(tempCount)
        {
          downThreeDHeight /= tempCount;
        }

        if(upBinarySW && downBinarySW)
        {
          RotationThreeDImage[tempAddress] = (upThreeDHeight + downThreeDHeight) / 2;

        }
        else if(leftBinarySW && rightBinarySW)
        {
          RotationThreeDImage[tempAddress] = (leftThreeDHeight + rightThreeDHeight) / 2;
        }
      } 
    }
  }

  for(y = startY; y < endY; y++)
  {
    for(x = startX; x < endX; x++)
    {
      tempAddress = HALF_IMAGE_WIDTH * y + x;

      z = halfSrcImage[tempAddress];

      if(z)
      {
        shiftX = shiftInfoArray[tempAddress][0];
        shiftY = shiftInfoArray[tempAddress][1];
        shiftZ = shiftInfoArray[tempAddress][2];

        minValue = 0xFF;

        tempAddress2 = HALF_IMAGE_WIDTH * shiftY + shiftX;
        for(i = -1; i <= 1; i++)
        {
          for(j = -1; j < 1; j++)
          {
            minValue = min(minValue, RotationThreeDImage[tempAddress2 + i * MAX_IMAGE_WIDTH + j] - shiftZ);
          }
        }

        minValue = min(minValue, RotationThreeDImage[tempAddress2] - shiftZ);

        if(RotationThreeDImage[tempAddress2 - 2])
        {
          minValue = min(minValue, RotationThreeDImage[tempAddress2 - 2] - shiftZ);
        }

        if(RotationThreeDImage[tempAddress2 + 2])
        {
          minValue = min(minValue, RotationThreeDImage[tempAddress2 + 2] - shiftZ);
        }

        if(minValue > 10)
        {
          ThreeDEraseArea[tempAddress] = 1;
        }
      }
    }
  }

  Byte *ptr;
  Graphics::TBitmap *tempImage;
	tempImage = new Graphics::TBitmap();

  if(RotationDataLoadCheckBox->Checked == false)
  {
    tempImage->Width = MAX_IMAGE_WIDTH;
    tempImage->Height = MAX_IMAGE_HEIGHT;
    tempImage->PixelFormat = pf24bit;
    for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
    {
      ptr = (Byte*)tempImage->ScanLine[y];
      for(x = 0; x < MAX_IMAGE_WIDTH; x++)
      {
        tempAddress = MAX_IMAGE_WIDTH * y + x;

        if(NormalizedImageLoadCheckBox->Checked)
        {
          if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
          {
            ptr[3*x + 0] = Disk1NrmThreeDImage[tempAddress];
            ptr[3*x + 1] = Disk1NrmThreeDImage[tempAddress];
            ptr[3*x + 2] = Disk1NrmThreeDImage[tempAddress];
          }
          else
          {
            ptr[3*x + 0] = Disk2NrmThreeDImage[tempAddress];
            ptr[3*x + 1] = Disk2NrmThreeDImage[tempAddress];
            ptr[3*x + 2] = Disk2NrmThreeDImage[tempAddress];
          }
        }
        else
        {
          if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
          {
            ptr[3*x + 0] = Disk1StdThreeDImage[tempAddress];
            ptr[3*x + 1] = Disk1StdThreeDImage[tempAddress];
            ptr[3*x + 2] = Disk1StdThreeDImage[tempAddress];
          }
          else
          {
            ptr[3*x + 0] = Disk2StdThreeDImage[tempAddress];
            ptr[3*x + 1] = Disk2StdThreeDImage[tempAddress];
            ptr[3*x + 2] = Disk2StdThreeDImage[tempAddress];
          }
        }

        if(ThreeDEraseArea[HALF_IMAGE_WIDTH * (y / 2) + (x / 2)])
        {
          ptr[3*x + 2] = 255;
        }
      }
    }
  }
  else
  {
    tempImage->Width = MAX_IMAGE_WIDTH / 2;
    tempImage->Height = MAX_IMAGE_HEIGHT / 2;
    tempImage->PixelFormat = pf24bit;

    for(y = 0; y < MAX_IMAGE_HEIGHT / 2; y++)
    {
      ptr = (Byte*)tempImage->ScanLine[y];
      for(x = 0; x < MAX_IMAGE_WIDTH / 2; x++)
      {
        tempAddress = (MAX_IMAGE_WIDTH / 2) * y + x;

        ptr[3*x + 0] = RotationThreeDImage[tempAddress];
        ptr[3*x + 1] = RotationThreeDImage[tempAddress];
        ptr[3*x + 2] = RotationThreeDImage[tempAddress];
      }
    }
  }

  if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
  {
    Disk1NormalizedThreeDImage->Picture->Bitmap->Assign(tempImage);
    Disk1NormalizedThreeDImage->Refresh();
  }
  else
  {
    Disk2NormalizedThreeDImage->Picture->Bitmap->Assign(tempImage);
    Disk2NormalizedThreeDImage->Refresh();
  } 

  delete tempImage;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::GetThreeDThreshold(unsigned char *srcImage, int yzR, int cameraIndex)
{
  int x, y, z;
  int tempAddress, tempAddress2;
  int yzCosValue, yzSinValue;
  int rX, rY, rZ;
  int heightDiff;
  int tempHeight;
  int tempCount;
  unsigned char RotationThreeDImage[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];
  int r;
  int srcHeight;
  int transformHeight;
  int shiftX, shiftY, shiftZ;
  int rotateHeight;
  int dX, dY, dZ;
  int minValue;
  int i, j;
  int startX, endX, startY, endY;
  int centerX, centerY, centerZ;

  startX = 10;
  endX = MAX_IMAGE_WIDTH - 10;
  startY = 10;
  endY = MAX_IMAGE_HEIGHT - 10;

  centerX = centerY = centerZ = tempCount = 0;
  for(y = startY; y < endY; y++)
  {
    for(x = startX; x < endX; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;
      if(srcImage[tempAddress])
      {
        centerX += x;
        centerY += y;
        centerZ += srcImage[tempAddress];
        tempCount++;
      }
    }
  }

  if(tempCount)
  {
    centerX /= tempCount;
    centerY /= tempCount;
    centerZ /= tempCount;
  }

  unsigned char *outlineData = GradientImage;
  memset(outlineData, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

      if(srcImage[tempAddress])
      {
        if(srcImage[tempAddress - 2] == 0 ||
            srcImage[tempAddress + 2] == 0 ||
            srcImage[tempAddress - 2 * MAX_IMAGE_WIDTH] == 0 ||
            srcImage[tempAddress + 2 * MAX_IMAGE_WIDTH] == 0)
        {
          outlineData[tempAddress] = 1;
          
          if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
          {
            srcImage[tempAddress] = Disk1OutlineAverageHeight;
          }
          else
          {
            srcImage[tempAddress] = Disk2OutlineAverageHeight;
          }
        }
      }
		}
	}

  yzCosValue = CosData[(yzR + 720) % 720];
  yzSinValue = SinData[(yzR + 720) % 720];

  memset(RotationThreeDImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  
  for(y = startY; y < endY; y++)
  {
    for(x = startX; x < endX; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      z = srcImage[tempAddress];

      if(outlineData[tempAddress] && z)
      {
        rX = x;
        rY = (((y - centerY) * yzCosValue - (z - centerZ) * yzSinValue) / 1024) + centerY;
        rZ = (((y - centerY) * yzSinValue + (z - centerZ) * yzCosValue) / 1024) + centerZ;

        if(rZ < 0) rZ = 0;
        if(rZ > 255) rZ = 255;

        tempAddress = MAX_IMAGE_WIDTH * rY + rX;

        if(rX > 0 && rX < MAX_IMAGE_WIDTH && rY > 0 && rY < MAX_IMAGE_HEIGHT)
        {
          RotationThreeDImage[tempAddress] = max(RotationThreeDImage[tempAddress], rZ);
        }
      }
    }
  }

  minValue = 0xFFFF;
  for(y = startY; y < endY; y++)
  {
    for(x = startX; x < endX; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      if(RotationThreeDImage[tempAddress])
      {
        if(minValue > RotationThreeDImage[tempAddress])
        {
          minValue = RotationThreeDImage[tempAddress];
        }
      }
    }
  }

  if(minValue && minValue != 0xFFFF)
  {
    if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
    {
      if(Disk1OutlineMinThreshold > minValue)
      {
        Disk1OutlineMinThreshold = minValue;
      }
    }
    else
    {
      if(Disk2OutlineMinThreshold > minValue)
      {
        Disk2OutlineMinThreshold = minValue;
      }
    }
  }

  Graphics::TBitmap *tempImage;
	tempImage = new Graphics::TBitmap();
  tempImage->Width = MAX_IMAGE_WIDTH;
  tempImage->Height = MAX_IMAGE_HEIGHT;
  tempImage->PixelFormat = pf24bit;

  Byte *ptr;

  for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
  {
    ptr = (Byte*)tempImage->ScanLine[y];
    for(x = 0; x < MAX_IMAGE_WIDTH; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      ptr[3*x + 0] = RotationThreeDImage[tempAddress];
      ptr[3*x + 1] = RotationThreeDImage[tempAddress];
      ptr[3*x + 2] = RotationThreeDImage[tempAddress];
    }
  }

  if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
  {
    Disk1RotationThreeDImage->Picture->Bitmap->Assign(tempImage);
    Disk1RotationThreeDImage->Refresh();
  }
  else
  {
    Disk2RotationThreeDImage->Picture->Bitmap->Assign(tempImage);
    Disk2RotationThreeDImage->Refresh();
  } 

  delete tempImage;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::NormalizedThreeDImage(unsigned char *srcImage, int normalizedValue, int *centerX, int *centerY, int *centerZ, int cameraIndex)
{
  if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
  {
    memset(Disk1NrmThreeDImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  }
  else
  {
    memset(Disk2NrmThreeDImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  }

  int startX, endX, startY, endY;
  int tempAddress;
  int x, y;
  int tempValue;
  
  startX = 10;
  endX = MAX_IMAGE_WIDTH - 10;
  startY = 10;
  endY = MAX_IMAGE_HEIGHT - 10;

  int tempCenterX, tempCenterY, tempCenterZ;
  int tempCount;

  tempCenterX = tempCenterY = tempCenterZ = tempCount = 0;
  for (y = startY; y < endY; y++)
  {
    for (x = startX; x < endX; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      if(srcImage[tempAddress])
      {
        tempCenterX += x;
        tempCenterY += y;
        tempCenterZ += srcImage[tempAddress];
        tempCount++;
      }
    }
  }

  if(tempCount)
  {
    *centerX = tempCenterX / tempCount;
    *centerY = tempCenterY / tempCount;
    *centerZ = tempCenterZ / tempCount;
  }
  else
  {
    *centerX = MAX_IMAGE_WIDTH / 2;
    *centerY = MAX_IMAGE_HEIGHT / 2;
    *centerZ = 128;
  }
  
  unsigned char *outlineData = GradientImage;
  memset(outlineData, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

      if(srcImage[tempAddress])
      {
        if(srcImage[tempAddress - 2] == 0 ||
            srcImage[tempAddress + 2] == 0 ||
            srcImage[tempAddress - 2 * MAX_IMAGE_WIDTH] == 0 ||
            srcImage[tempAddress + 2 * MAX_IMAGE_WIDTH] == 0)
        {
          outlineData[tempAddress] = 1;
        }
      }
		}
	}

  int outlineInfoTable[361][4]; // length, height
  int pX, pY;
  int angle;
  int uLength;
  int sinV;

  memset(outlineInfoTable, 0, sizeof(int) * 361 * 4);
  for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;
			if (outlineData[tempAddress] == 1)
			{
        pX = x - *centerX;
        pY = y - *centerY;
        uLength = pX * pX + pY * pY;
        if (uLength < 90000)
        {
          uLength = SqrtData[uLength]; //sqrtdata는 128이 곱해 진 상태.
          sinV = 1280000 * pX / uLength;
          if (sinV > 10000) sinV = 10000;

          if (pX >= 0 && pY <= 0)
            angle = ArcSinData[sinV];
          else if (pX >= 0 && pY > 0)
            angle = 180 - ArcSinData[sinV];
          else if (pX < 0 && pY > 0)
            angle = 180 + ArcSinData[-sinV];
          else
            angle = 360 - ArcSinData[-sinV];

          if(angle >= 0 && angle < 360)
          {
            if(outlineInfoTable[angle][0] < uLength)
            {
              outlineInfoTable[angle][0] = uLength;
              outlineInfoTable[angle][1] = srcImage[tempAddress];
              outlineInfoTable[angle][2] = x;
              outlineInfoTable[angle][3] = y;
            }
          }
        }
			}
		}
	}

  memset(outlineData, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  for(angle = 0; angle < 360; angle++)
  {
    if(outlineInfoTable[angle][0])
    {
      x = outlineInfoTable[angle][2];
      y = outlineInfoTable[angle][3];

      for(int tempY = y - 2; tempY <= y + 2; tempY++)
      {
        for(int tempX = x - 2; tempX <= x + 2; tempX++)
        {
          tempAddress = MAX_IMAGE_WIDTH * tempY + tempX;

          if(tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
          {
            outlineData[tempAddress] = 1;
          }
        }
      }
    }
  }
   
  for (y = startY; y < endY; y++)
  {
    for (x = startX; x < endX; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      if(srcImage[tempAddress] && outlineData[tempAddress] == 0)
      {
        tempValue = (srcImage[tempAddress] - *centerZ) * normalizedValue / 255 + *centerZ;

        if(tempValue > 10)
        {
          if(cameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX)
          {
            Disk1NrmThreeDImage[tempAddress] = tempValue;
          }
          else
          {
            Disk2NrmThreeDImage[tempAddress] = tempValue;
          }
        }
      }
    }
  }
}

//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::CheckOverlapArea(int *prevOverlapResultCount, int *studyNormalizedValue, int currentNormalizedValue)
{
  int x, y;
  int tempAddress;
  int tempCount;

  tempCount = 0;
  for(y = 0; y < HALF_IMAGE_HEIGHT; y++)
  {
    for(x = 0; x < HALF_IMAGE_WIDTH; x++)
    {
      tempAddress = HALF_IMAGE_WIDTH * y + x;

      if(ThreeDEraseArea[tempAddress])
      {
        tempCount++;
      }
    }
  }

  if(*prevOverlapResultCount > tempCount)
  {
    *prevOverlapResultCount = tempCount;
    *studyNormalizedValue = currentNormalizedValue;
  }
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::Extraction3DInfoGroupBoxDblClick(
      TObject *Sender)
{
  RotationDataLoadCheckBox->Visible = !RotationDataLoadCheckBox->Visible;
  NormalizedImageLoadCheckBox->Visible = !NormalizedImageLoadCheckBox->Visible;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ExtractThreeInfoCloseBtnClick(
      TObject *Sender)
{
  Extraction3DInfoGroupBox->Visible = false;
  ReadHistoryButton->Visible = true;
}
//---------------------------------------------------------------------------
bool __fastcall TTabletCharacterExtractForm::makeOffsetData()
{
  int x, y;
  int tempAddress, tempAddress2;
  int halfImageWidth;
  bool bExistAllImage = true;

  AnsiString imageDir, fileName;
  AnsiString RootPath;
  RootPath = ProgramPath.Env;

  for(int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
  {
    if(cameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX && cameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
    {
      if(CameraMapInfo[cameraIndex - 1].CameraInspectPosition < CAMERA_POSITION_DISCONNECT)
      {
        imageDir = RootPath + "\\OFFSETIMAGE\\GAIN" + IntToStr(ProductData.DigitalGainV[cameraIndex-1]);
        fileName = imageDir + "\\Camera" + IntToStr(cameraIndex) + "_OffSet.bmp";

        if(!FileExists(fileName))
        {
          bExistAllImage = false;
          break;
        }
      }
    }
  }

  if(bExistAllImage)
  {
    halfImageWidth = MAX_IMAGE_WIDTH / 2;

    Graphics::TBitmap *img;
		img = new Graphics::TBitmap();

    img->Width = MAX_IMAGE_WIDTH;
    img->Height = MAX_IMAGE_HEIGHT;
    img->PixelFormat = pf24bit;

    Byte *ptr;

    unsigned char tempOffsetImage[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];

    for(int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
    {
      if(cameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX && cameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
      {
        if(CameraMapInfo[cameraIndex - 1].CameraInspectPosition < CAMERA_POSITION_DISCONNECT)
        {
          memset(tempOffsetImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

          imageDir = RootPath + "\\OFFSETIMAGE\\GAIN" + IntToStr(ProductData.DigitalGainV[cameraIndex-1]);
          fileName = imageDir + "\\Camera" + IntToStr(cameraIndex) + "_OffSet.bmp";

          img->LoadFromFile(fileName);

          for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
          {
            ptr = (Byte*) img->ScanLine[y];
            for(x = 0; x < MAX_IMAGE_WIDTH; x++)
            {
              tempAddress = MAX_IMAGE_WIDTH * y + x;
              tempOffsetImage[tempAddress] = ptr[3*x + 1];
            }
          }

          int value;
          for(y = 2; y < MAX_IMAGE_HEIGHT - 2; y+=2)
          {
            for(x = 2; x < MAX_IMAGE_WIDTH - 2; x+=2)
            {
              tempAddress = halfImageWidth * (y / 2) + (x / 2);
              tempAddress2 = MAX_IMAGE_WIDTH * y + x;

              value = tempOffsetImage[tempAddress2] +
                      tempOffsetImage[tempAddress2 - 1] +
                      tempOffsetImage[tempAddress2 + 1] +
                      tempOffsetImage[tempAddress2 - MAX_IMAGE_WIDTH] +
                      tempOffsetImage[tempAddress2 + MAX_IMAGE_WIDTH];

              TabletSetupData.referenceImageForOffset[cameraIndex - 1][tempAddress] = value / 5;


            }
          }
          TabletSetupData.ImageOffSetSW[cameraIndex - 1] = 1;

        }
      }
    }

    delete img;
  }
  else
  {
    memset(TabletSetupData.ImageOffSetSW, 0, sizeof(int) * SYSTEM_TOTAL_CAMERA_COUNT);
  }

  return bExistAllImage;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SpeedButton10Click(
      TObject *Sender)
{
  if(ManualWorkKind == LABELING) return;

  if(MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_10, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) != mrOk)
  {
    SpeedButton13->Down = true;
    return;
  }

  //GroupBox39->Left = 16;
  GroupBox4->Height = 1210;
  GroupBox37->Visible = false;
  GroupBox38->Visible = false;
  BitBtn1->Visible = false;
 
  ManualWorkKind = LABELING;
	SpeedButton3->Font->Color = clGray;
	SpeedButton4->Font->Color = clGray;
	SpeedButton5->Font->Color = clGray;
  SpeedButton10->Font->Color = clRed;

  SpeedButton10->Down = true;
  SpeedButton11->Down = true;
  SpeedButton12->Down = true;

  Image4->Canvas->Brush->Style = bsSolid;
  Image4->Canvas->Brush->Color = clWhite;
  Image4->Canvas->Rectangle(0, 0, Image4->Width, Image4->Height);
  Image4->Canvas->Pen->Color = clRed;
  Image4->Canvas->Brush->Color = clRed;
  Image4->Canvas->Ellipse(Image4->Width / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 - (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Width / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5), Image4->Height / 2 + (((float)ManualWorkAreaWidth) / 2.0 + 0.5));
  Image4->Refresh();

  PrintEditSizeOptionUpdownBtn->Enabled = false;
  PrintEditThickOptionUpdownBtn->Enabled = false;

  memcpy(PrintBinarizationData, PrintEditResult, ImageWidth*ImageHeight);
  memcpy(PrintBinarizationDataForThickModify, PrintBinarizationData, ImageWidth*ImageHeight);

  PrintEditSW = 1;

  PrintInformationCalculation(PRINT_MODIFY);
  LoadPrintGroupInformation();
}
//---------------------------------------------------------------------------

bool __fastcall TTabletCharacterExtractForm::LoadPrintGroupInformation(void)
{
	Byte *ptr, *tr1, *tr2, *tr;
  int tempX, tempY;

  Graphics::TBitmap *img1;
  img1 = new Graphics::TBitmap();
  img1->Width = ImageWidth * 2;
  img1->Height = ImageHeight * 2;
  img1->PixelFormat = pf24bit;

  for (int y = 0; y < ImageHeight; y++)
  {
    tr1 = (byte*)img1->ScanLine[y * 2];
    tr2 = (byte*)img1->ScanLine[y * 2 + 1];
    for (int x = 0; x < ImageWidth; x++)
    {
      for (int j = 2 * x; j <= 2 * x + 1; j++)
      {
        tr1[3 * j] = 0;
        tr1[3 * j + 1] = 0;
        tr1[3 * j + 2] = 0;

        tr2[3 * j] = 0;
        tr2[3 * j + 1] = 0;
        tr2[3 * j + 2] = 0;
      }
    }
  }

  memset(PrintEditResult, 0, ImageWidth*ImageHeight);

  int a, b, c;
  for(int n = 0; n < TabletSetupData.printLabelCount[SelectedFace]; n++)
  {
    for(int m = 0; m < TabletSetupData.printLabelDataCnt[SelectedFace][n]; m++)
    {
      tempX = TabletSetupData.printLabelData[SelectedFace][n][m][0];
      tempY = TabletSetupData.printLabelData[SelectedFace][n][m][1];

      PrintEditResult[ImageWidth * tempY + tempX] = n + 1;

      if((n + 1) % 2 == 0)
      {
        a = 17;
        b = 41;
        c = 73;
      }
      else
      {
        a = 73;
        b = 17;
        c = 41;
      }
        
      tr1 = (byte*)img1->ScanLine[tempY * 2];
      tr2 = (byte*)img1->ScanLine[tempY * 2 + 1];

      for (int j = 2 * tempX; j <= 2 * tempX + 1; j++)
      {
        tr1[3 * j + 0] = ((n + 1) * a) & 0xFF;
        tr1[3 * j + 1] = ((n + 1) * b) & 0xFF;
        tr1[3 * j + 2] = ((n + 1) * c) & 0xFF;

        tr2[3 * j + 0] = ((n + 1) * a) & 0xFF;
        tr2[3 * j + 1] = ((n + 1) * b) & 0xFF;
        tr2[3 * j + 2] = ((n + 1) * c) & 0xFF;
      }
    }
  }

  Image3->Picture->Bitmap->Assign(img1);
  Image3->Refresh();
  delete(img1);

  Panel23->Visible = true;
  PrintLabelEditMode = PRINT_LABEL_EDIT_MODE_SELECT_LABEL;

  PrintLabelEditOptionBtn1->Down = true;
  PrintLabelEditOptionBtn1->Font->Color = clRed;
	PrintLabelEditOptionBtn2->Font->Color = clGray;

  Panel24->Color = clGray;
  Panel24->Caption = "N/A";

  SelectedPrintLabelN = 0;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::PrintLabelEditOptionBtn1Click(
      TObject *Sender)
{
  PrintLabelEditMode = PRINT_LABEL_EDIT_MODE_SELECT_LABEL;

  PrintLabelEditOptionBtn1->Font->Color = clRed;
	PrintLabelEditOptionBtn2->Font->Color = clGray;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::PrintLabelEditOptionBtn2Click(
      TObject *Sender)
{
  PrintLabelEditMode = PRINT_LABEL_EDIT_MODE_APPLY_LABEL;

  PrintLabelEditOptionBtn1->Font->Color = clGray;
	PrintLabelEditOptionBtn2->Font->Color = clRed;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::TntBitBtn1Click(
      TObject *Sender)
{
  PrintEditSW = 1;
  LoadPrintGroupInformation();
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::RearrangePrintLabel(int targetLabelN)
{
  int PrintLabelCount[THREED_PRINT_MAX_LABEL_COUNT];
  memset(PrintLabelCount, 0, sizeof(int) * THREED_PRINT_MAX_LABEL_COUNT);
  
  for (int y = 0; y < ImageHeight; y++)
  {
    for (int x = 0; x < ImageWidth; x++)
    {
      int tempAddress = ImageWidth * y + x;

      if(PrintEditResult[tempAddress] == targetLabelN)
      {
        PrintLabelCount[SelectedPrintLabelN - 1]++;
      }
      else if(PrintEditResult[tempAddress])
      {
        PrintLabelCount[PrintEditResult[tempAddress] - 1]++;
      }
    }
  }

  for(int m = 0; m < THREED_PRINT_MAX_LABEL_COUNT; m++)
  {
    if(PrintLabelCount[m] >= PRINT_LABEL_DATA_SIZE)
    {
      MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_11, mtConfirmation, TMsgDlgButtons() << mbOK);
      return;
    }
  }

  for (int y = 0; y < ImageHeight; y++)
  {
    for (int x = 0; x < ImageWidth; x++)
    {
      int tempAddress = ImageWidth * y + x;

      if(PrintEditResult[tempAddress] == targetLabelN)
      {
        PrintEditResult[tempAddress] = SelectedPrintLabelN;
      }
    }
  }

  Byte *ptr, *tr1, *tr2, *tr;
  int tempX, tempY;

  Graphics::TBitmap *img1;
  img1 = new Graphics::TBitmap();
  img1->Width = ImageWidth * 2;
  img1->Height = ImageHeight * 2;
  img1->PixelFormat = pf24bit;

  for (int y = 0; y < ImageHeight; y++)
  {
    tr1 = (byte*)img1->ScanLine[y * 2];
    tr2 = (byte*)img1->ScanLine[y * 2 + 1];
    for (int x = 0; x < ImageWidth; x++)
    {
      for (int j = 2 * x; j <= 2 * x + 1; j++)
      {
        tr1[3 * j] = 0;
        tr1[3 * j + 1] = 0;
        tr1[3 * j + 2] = 0;

        tr2[3 * j] = 0;
        tr2[3 * j + 1] = 0;
        tr2[3 * j + 2] = 0;
      }
    }
  }

  int a, b, c;
  for(int n = 0; n < TabletSetupData.printLabelCount[SelectedFace]; n++)
  {
    for(int m = 0; m < TabletSetupData.printLabelDataCnt[SelectedFace][n]; m++)
    {
      tempX = TabletSetupData.printLabelData[SelectedFace][n][m][0];
      tempY = TabletSetupData.printLabelData[SelectedFace][n][m][1];

      tr1 = (byte*)img1->ScanLine[tempY * 2];
      tr2 = (byte*)img1->ScanLine[tempY * 2 + 1];

      int k = PrintEditResult[MAX_IMAGE_WIDTH * tempY + tempX];

      if(k % 2 == 0)
      {
        a = 17;
        b = 41;
        c = 73;
      }
      else
      {
        a = 73;
        b = 17;
        c = 41;
      }

      for (int j = 2 * tempX; j <= 2 * tempX + 1; j++)
      {
        tr1[3 * j + 0] = (k * a) & 0xFF;
        tr1[3 * j + 1] = (k * b) & 0xFF;
        tr1[3 * j + 2] = (k * c) & 0xFF;

        tr2[3 * j + 0] = (k * a) & 0xFF;
        tr2[3 * j + 1] = (k * b) & 0xFF;
        tr2[3 * j + 2] = (k * c) & 0xFF;
      }
    }
  }

  Image3->Picture->Bitmap->Assign(img1);
  Image3->Refresh();
  delete(img1);
}

//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ApplyPrintLabel()
{
  int PrintLabelCount[THREED_PRINT_MAX_LABEL_COUNT];
  memset(PrintLabelCount, 0, sizeof(int) * THREED_PRINT_MAX_LABEL_COUNT);
  
  for (int y = 0; y < ImageHeight; y++)
  {
    for (int x = 0; x < ImageWidth; x++)
    {
      int tempAddress = ImageWidth * y + x;

      if(PrintEditResult[tempAddress])
      {
        PrintLabelCount[PrintEditResult[tempAddress] - 1]++;
      }
    }
  }

  for (int n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
  {
    TabletSetupData.printLabelDataCnt[SelectedFace][n] = 0;
  }

  int labelCount = 0;
  for(int m = 0; m < THREED_PRINT_MAX_LABEL_COUNT; m++)
  {
    if(PrintLabelCount[m])
    {
      for (int y = 0; y < ImageHeight; y++)
      {
        for (int x = 0; x < ImageWidth; x++)
        {
          int tempAddress = ImageWidth * y + x;

          if(PrintEditResult[tempAddress] == m + 1)
          {
            if(TabletSetupData.printLabelDataCnt[SelectedFace][labelCount] < PRINT_LABEL_DATA_SIZE)
            {
              TabletSetupData.printLabelData[SelectedFace][labelCount][TabletSetupData.printLabelDataCnt[SelectedFace][labelCount]][0] = x;
              TabletSetupData.printLabelData[SelectedFace][labelCount][TabletSetupData.printLabelDataCnt[SelectedFace][labelCount]][1] = y;
              TabletSetupData.printLabelDataCnt[SelectedFace][labelCount]++;
            }
          }
        }
      }

      labelCount++;
    }
  }

  TabletSetupData.printLabelCount[SelectedFace] = labelCount;
}

//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::TntBitBtn2Click(
      TObject *Sender)
{
  if(PrintEditSW)
  {
    ApplyPrintLabel();
  }
  
  LoadExtractedPrintLabelData();

  GroupBox4->Visible = false;
	GroupBox17->Visible = true;
	GroupBox18->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;
	GroupBox21->Visible = true;
	Panel5->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::LoadExtractedPrintLabelData()
{
  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;
	Byte *ptr;

  int tempX, tempY;

  int a, b, c;

  if(TabletCharacter.discriminationDisplay_kind != NONE)
  {
    for(int y = 0; y < ImageHeight; y++)
    {
      ptr = (Byte*)img1->ScanLine[y];
      for(int x = 0; x < ImageWidth; x++)
      {
        ptr[3 * x + 0] = 0;
        ptr[3 * x + 1] = 0;
        ptr[3 * x + 2] = 0;
      }
    }

    for(int n = 0; n < TabletSetupData.printLabelCount[0]; n++)
    {
      for(int m = 0; m < TabletSetupData.printLabelDataCnt[0][n]; m++)
      {
        tempX = TabletSetupData.printLabelData[0][n][m][0];
        tempY = TabletSetupData.printLabelData[0][n][m][1];

        ptr = (byte*)img1->ScanLine[tempY];

        if((n + 1) % 2 == 0)
        {
          a = 17;
          b = 41;
          c = 73;
        }
        else
        {
          a = 73;
          b = 17;
          c = 41;
        }

        ptr[3 * tempX + 0] = ((n + 1) * a) & 0xFF;
        ptr[3 * tempX + 1] = ((n + 1) * b) & 0xFF;
        ptr[3 * tempX + 2] = ((n + 1) * c) & 0xFF;
      }
    }

    Image30->Picture->Bitmap->Assign(img1);
		Image30->Stretch = true;
		Image30->Refresh();

    BitBtn20->Enabled = true;
  }

	if (TabletCharacter.discriminationDisplay_num == TWO_FACE_DIFF)
	{
    for(int y = 0; y < ImageHeight; y++)
    {
      ptr = (Byte*)img1->ScanLine[y];
      for(int x = 0; x < ImageWidth; x++)
      {
        ptr[3 * x + 0] = 0;
        ptr[3 * x + 1] = 0;
        ptr[3 * x + 2] = 0;
      }
    }

    for(int n = 0; n < TabletSetupData.printLabelCount[1]; n++)
    {
      for(int m = 0; m < TabletSetupData.printLabelDataCnt[1][n]; m++)
      {
        tempX = TabletSetupData.printLabelData[1][n][m][0];
        tempY = TabletSetupData.printLabelData[1][n][m][1];

        ptr = (byte*)img1->ScanLine[tempY];

        if((n + 1) % 2 == 0)
        {
          a = 17;
          b = 41;
          c = 73;
        }
        else
        {
          a = 73;
          b = 17;
          c = 41;
        }

        ptr[3 * tempX + 0] = ((n + 1) * a) & 0xFF;
        ptr[3 * tempX + 1] = ((n + 1) * b) & 0xFF;
        ptr[3 * tempX + 2] = ((n + 1) * c) & 0xFF;
      }
    }

		Image31->Picture->Bitmap->Assign(img1);
		Image31->Stretch = true;
		Image31->Refresh();

    BitBtn21->Enabled = true;
	}

	delete(img1);
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::ReadHistoryButtonClick(
      TObject *Sender)
{
  GroupBox17->Visible = false;
  GroupBox18->Visible = false;
  SaveAndExitButton->Visible = false;
  ReadHistoryButton->Visible = false;

  SetupDataHistoryPanel->Visible = true;

  ReadSetupHistory();
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::HistoryCloseButtonClick(
      TObject *Sender)
{
  SetupDataHistoryPanel->Visible = false;

  GroupBox17->Visible = true;
  GroupBox18->Visible = true;
  SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ReadSetupHistory()
{
  HistoryGrid->Cells[0][0] = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_44;
  HistoryGrid->Cells[1][0] = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_45;
  HistoryGrid->Cells[2][0] = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_46;
  HistoryGrid->Cells[3][0] = "ID";
  HistoryGrid->Cells[4][0] = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_47;
  HistoryGrid->Cells[5][0] = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_48;

  HistoryGrid->ColWidths[0] = 70;
  HistoryGrid->ColWidths[3] = 150;
  HistoryGrid->ColWidths[4] = 70;
  HistoryGrid->ColWidths[5] = 70;

  int GridCellWidth = (HistoryGrid->Width - (HistoryGrid->ColWidths[0] + HistoryGrid->ColWidths[3] + HistoryGrid->ColWidths[4] + HistoryGrid->ColWidths[5])) / 2;
  HistoryGrid->ColWidths[1] = GridCellWidth - 15;
  HistoryGrid->ColWidths[2] = GridCellWidth - 15;

  for(int i = HistoryGrid->FixedRows; i < HistoryGrid->RowCount; ++i)
  {
    HistoryGrid->Rows[i]->Clear();
  }
  HistoryGrid->RowCount = 2;

  AnsiString setupDataBackupPath = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\SetupRecord";
  SetupBackupPathLabel->Caption = setupDataBackupPath;
  SelectedFileLabel->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_49 + "NULL";
  SelectedFileLabel->Font->Color = clBlack;

  ApplySetupDataButton->Enabled = false;

  unsigned int currentChecksum = 0;
  currentChecksum += MakeCheckSumID((unsigned int*) &TabletSetupData, sizeof(TTabletSetupData) / 4);
  currentChecksum += MakeCheckSumID((unsigned int*) &Tablet3DSetupData, sizeof(TTablet3DSetupData) / 4);

  WCHAR IDLabel[100];
  memset(IDLabel, 0, sizeof(WCHAR) * 100);
  wsprintfW(IDLabel, L"0x%08X", currentChecksum);

  GlobalSetupDataID = WideString(IDLabel);

  CurrentSetupDataIDLabel->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_50 + WideString(IDLabel);

  if(DirectoryExists(setupDataBackupPath))
  {
    int LastFileIndex = 0;
    TIniFile *iniFile = new TIniFile(setupDataBackupPath + "\\Record.ini");
    if(iniFile)
    {
      LastFileIndex = iniFile->ReadInteger("Data", "Last Index", 0);
      delete iniFile;
    }

    if(LastFileIndex)
    {
      TFileStream *recordStream;
      AnsiString FileName;
      TDateTime writeTime;
      int savedFileSize;
      unsigned int checksum;
      int expectedFile = sizeof(unsigned int) + sizeof(int) + sizeof(TDateTime) + sizeof(TTabletSetupData) + sizeof(TTablet3DSetupData);

      int dstRowIndex = 1;
      for(int fileIndex = 1; fileIndex <= LastFileIndex; fileIndex++)
      {
        FileName = setupDataBackupPath + "\\" + IntToStr(fileIndex) + ".sbf";

        if(FileExists(FileName))
        {
          recordStream = new TFileStream(FileName, fmOpenRead);
          recordStream->Read(&checksum, sizeof(int));
          recordStream->Read(&savedFileSize, sizeof(int));
          recordStream->Read(&writeTime, sizeof(TDateTime));

          delete recordStream;

          AnsiString TimeLabel;
          DateTimeToString(TimeLabel, "yy/mm/dd HH:mm:ss", writeTime);
          memset(IDLabel, 0, sizeof(WCHAR) * 100);
          wsprintfW(IDLabel, L"0x%08X", checksum);

          HistoryGrid->Cells[0][dstRowIndex] = IntToStr(dstRowIndex);
          HistoryGrid->Cells[1][dstRowIndex] = IntToStr(fileIndex) + ".sbf";
          HistoryGrid->Cells[2][dstRowIndex] = TimeLabel;
          HistoryGrid->Cells[3][dstRowIndex] = IDLabel;
          HistoryGrid->Cells[4][dstRowIndex] = FloatToStrF(savedFileSize / (double)(1024 * 1024), ffGeneral, 4, 1) + " MB";

          if(expectedFile == savedFileSize)
          {
            HistoryGrid->Cells[5][dstRowIndex] = "O";
          }
          else
          {
            HistoryGrid->Cells[5][dstRowIndex] = "X";
          }

          HistoryGrid->Row = dstRowIndex;

          dstRowIndex++;
          HistoryGrid->RowCount++;
        }
      }
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TTabletCharacterExtractForm::HistoryGridClick(
      TObject *Sender)
{
  int SelectRow = HistoryGrid->Row;
  if(SelectRow > 0 && !HistoryGrid->Cells[1][SelectRow].IsEmpty())
  {
    SelectedFileLabel->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_49 + HistoryGrid->Cells[1][SelectRow] + " / " + HistoryGrid->Cells[3][SelectRow];

    if(GlobalSetupDataID == HistoryGrid->Cells[3][SelectRow])
    {
      SelectedFileLabel->Font->Color = clGreen;
      ApplySetupDataButton->Enabled = false;
    }
    else
    {
      SelectedFileLabel->Font->Color = clRed;

      if(HistoryGrid->Cells[5][SelectRow] == WideString("O"))
      {
        ApplySetupDataButton->Enabled = true;
      }
      else
      {
        ApplySetupDataButton->Enabled = false;
      }
    }
  }
  else
  {
    SelectedFileLabel->Caption = TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_49 + "NULL";
    SelectedFileLabel->Font->Color = clBlack;
    
    ApplySetupDataButton->Enabled = false;
  }
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ApplySetupDataButtonClick(
      TObject *Sender)
{
  WideString filename, date;
  filename = HistoryGrid->Cells[1][HistoryGrid->Row];
  date = HistoryGrid->Cells[2][HistoryGrid->Row];
  if (MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_51 + filename + ", " + date + "]", mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
  {
    if (MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_52, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
    {      
      memset(&TabletSetupData, 0, sizeof(TTabletSetupData));
      memset(&Tablet3DSetupData, 0, sizeof(TTabletSetupData));

      TDateTime writeTime;
      int savedFileSize;
      unsigned int checksum;

      AnsiString setupDataBackupPath = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\SetupRecord";
      TFileStream *recordStream = new TFileStream(setupDataBackupPath + "\\" + filename, fmOpenRead);
      recordStream->Read(&checksum, sizeof(int));
      recordStream->Read(&savedFileSize, sizeof(int));
      recordStream->Read(&writeTime, sizeof(TDateTime));
      recordStream->Read(&TabletSetupData, sizeof(TTabletSetupData));
      recordStream->Read(&Tablet3DSetupData, sizeof(TTablet3DSetupData));
      delete recordStream;

      AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt";
      TFileStream *fileStream = new TFileStream(setupDataFileName, fmCreate);
      fileStream->Write(&TabletSetupData, sizeof(TTabletSetupData));
      delete fileStream;

      setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt_3D";
      TFileStream *fileStream1 = new TFileStream(setupDataFileName, fmCreate);
      fileStream1->Write(&Tablet3DSetupData, sizeof(TTablet3DSetupData));
      delete fileStream1;

      /*
      // 이력 선택 및 적용에 대한 변경사항은 저장하지 않음
      if (!DirectoryExists(setupDataBackupPath))
      {
        ForceDirectories(setupDataBackupPath);
      }

      int nextFileIndex = 0;
      TIniFile *iniFile = new TIniFile(setupDataBackupPath + "\\Record.ini");
      if(iniFile)
      {
        nextFileIndex = iniFile->ReadInteger("Data", "Last Index", 0);
        delete iniFile;
      }
      nextFileIndex++;

      AnsiString setupDataBackupFileName = setupDataBackupPath + "\\" + IntToStr(nextFileIndex) + ".sbf";
      recordStream = new TFileStream(setupDataBackupFileName, fmCreate);

      TDateTime SaveTime = Now();
      int size = sizeof(unsigned int) + sizeof(int) + sizeof(TDateTime) + sizeof(TTabletSetupData) + sizeof(TTablet3DSetupData);
      checksum = 0;
      checksum += MakeCheckSumID((unsigned int*) &TabletSetupData, sizeof(TTabletSetupData) / 4);
      checksum += MakeCheckSumID((unsigned int*) &Tablet3DSetupData, sizeof(TTablet3DSetupData) / 4);

      recordStream->Write(&checksum, sizeof(unsigned int));
      recordStream->Write(&size, sizeof(int));
      recordStream->Write(&SaveTime, sizeof(TDateTime));
      recordStream->Write(&TabletSetupData, sizeof(TTabletSetupData));
      recordStream->Write(&Tablet3DSetupData, sizeof(TTablet3DSetupData));
      delete recordStream;

      iniFile = new TIniFile(setupDataBackupPath + "\\Record.ini");
      if(iniFile)
      {
        iniFile->WriteInteger("Data", "Last Index", nextFileIndex);
        delete iniFile;
      }
      */

      CPBSetupInfo.StudySetupDataValid = false;
      CPBSetupInfo.InspectionSetupDataValid = false;

      if(SetupMode == TABLET_SETUP_MODE_NORMAL)
      {
        ProductData.ProcessingStep = TABLET_PROCESSING_STEP_FIRST_STUDY_REQUIRED;
        AnsiString fileName = GetProductDataFileName(ProductData.ProductCode);
        WriteProductData(fileName, ProductData);
      }

      AddCSVActionLog(ECSV_ACTION_TABLET_CHARACTER_EXTRACT, UserInfo.Name, ProductData.ProductName, NULL, 0);
      AddCSVActionLog(ECSV_ACTION_TABLET_CHARACTER_EXTRACT_END, UserInfo.Name, ProductData.ProductName, NULL, 0);

      SetupDataChanged = true;

      MessageDlgFA(TABLETCHARACTEREXTRACTFORM_TEXT_CAPTION_53, mtConfirmation, TMsgDlgButtons() << mbOK);

      ModalResult = mrOk;
      this->Close();
    }
  }
}
//---------------------------------------------------------------------------

unsigned int __fastcall TTabletCharacterExtractForm::MakeCheckSumID(unsigned int* src, unsigned int len)
{
	unsigned int sum = 0;
	while (len--)
	{
		sum += *src++;
	}
	return sum;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ColorRateRangeImageMouseDown(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
  TabletSetupData.TabletColorRange = X / (ColorRateRangeImage->Width / 100) + 1;
	SideFaceThresholdValueDisplay();
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ColorRateCheckBoxClick(
      TObject *Sender)
{
  if(ColorRateCheckBox->Checked)
  {
    TabletSetupData.ActiveColorRatioCheck = true;

    ColorRateRangeImage->Enabled = true;
    Panel26->Color = 0x00002200;

    SideThrEachCheckBox->Enabled = true;    
  }
  else
  {
    TabletSetupData.ActiveColorRatioCheck = false;

    ColorRateRangeImage->Enabled = false;
    Panel26->Color = clDkGray;

    SideThrEachCheckBox->Enabled = false;
    SideThrEachCheckBox->Checked = false;
    TabletSetupData.TabletColorRangeEachActive = SIDE_COLORATE_SET_EACH_DISABLE;    
  }

  Panel26->Refresh();

  SideFaceThresholdValueDisplay();
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SideThresholdForEachCamera8Change(
      TObject *Sender)
{
  if(bInit) return;

  TTrackBar *tempTrackBar = (TTrackBar *)Sender;
  int cameraIndex = tempTrackBar->Tag;
  TabletSetupData.SideThresholdForEachCamera[cameraIndex - 1] = tempTrackBar->Position;

  SideFaceThresholdValueDisplay();
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::TntFormActivate(
      TObject *Sender)
{
  SetScreenPosition(this);

  int ReadDataN;
	int ReadDataN_3D;
	ImageOption = HALF_IMAGE;
	MakeTabletCharacterData(&ProductData, &TabletCharacter, &MachineParams);
	VersionTransSW = 0;
	SelectedImage = new Graphics::TBitmap();
	SelectedImage1 = new Graphics::TBitmap();
	SelectedImage2 = new Graphics::TBitmap();
	ThreeDSelectedImage1 = new Graphics::TBitmap();
	ThreeDSelectedImage2 = new Graphics::TBitmap();
	//	StoredImageFolder = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Image\\Image";

	print1ExtractUnusalSW = 0;
	print2ExtractUnusalSW = 0;

	Disk1Print1ExtractUnusalSW = 0;
	Disk1Print2ExtractUnusalSW = 0;
	Disk2Print1ExtractUnusalSW = 0;
	Disk2Print2ExtractUnusalSW = 0;

	ImageWidth = 640;
	ImageHeight = 480;
	ImageSelectActiveSW = 0;
	SliceMaskSW = 0;
  OtherPrintSettingSW = 0;
	SelectedImageN[0] = 0;
	SelectedImageN[1] = 0;
	SelectedWorkSW[0] = 0;
	SelectedWorkSW[1] = 0;
	GroupBox16->Left = 16;
	GroupBox16->Top = 40;

	GroupBox1->Visible = false;    //이미지 선택
	GroupBox13->Visible = false;   //대표 모양 추출
	GroupBox6->Visible = false;   //식별마크 추출 작업
	Panel5->Visible = false;    // 새로운? 수정?
	GroupBox20->Visible = false;    //새로운 정보 추츌
  ExtractionSplitLineGroupBox->Visible = false;
	GroupBox21->Visible = false;    // 기존 정보 수정
	GroupBox4->Visible = false;    // 기존 정보 수정

	ShapExtractButton->Visible = true;
	DiscrimiationMarkExtract->Visible = true;
	SaveAndExitButton->Visible = true;
  ReadHistoryButton->Visible = true;

	GroupBox19->Visible = false;
	GroupBox23->Visible = false;
	Panel2->Visible = false;
	GroupBox25->Visible = false;
	GroupBox33->Visible = false;

	memset(&TabletSetupData, 0, sizeof(TTabletSetupData)); // 셋업 데이터 초기화
	memset(&Tablet3DSetupData, 0, sizeof(TTablet3DSetupData)); // 셋업 데이터 초기화
	ReadDataN = ReadSetupData(&TabletSetupData);
	ReadDataN_3D = Read3DSetupData(&Tablet3DSetupData);

  if(SetupMode == TABLET_SETUP_MODE_NORMAL)
  {
    if ((ReadDataN != sizeof(TTabletSetupData) && ReadDataN != 0)) // 파일이 존재하는 경우
    {
      if (MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_04, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
      {
        memset(&TabletSetupData, 0, sizeof(TTabletSetupData)); // 셋업 데이터 초기화
        TabletSetupData.PrintThreshold = 50;
      }
    }
    else if (ReadDataN == 0)
    {
      TabletSetupData.PrintThreshold = 50;
    }
  }

  if(SetupMode == TABLET_SETUP_MODE_NORMAL)
  {
    if ((ReadDataN_3D != sizeof(TTablet3DSetupData) && ReadDataN_3D != 0))
    {
      if (MessageDlgFA(TABLETCHARACTEREXTRACTFORM_MSG_05, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
      {
        memset(&Tablet3DSetupData, 0, sizeof(TTablet3DSetupData)); // 셋업 데이터 초기화
      }
    }
  }

	centerXInImage = 320;//270;
	centerYInImage = 190;
	ReadDataForTabletCharacterExtract();

	PrintAreaCnt = 640 * 480;
	tempUDPOS = 0;

	for (int m = 0; m < 90000; m++)
	{
		if (m == 0)
			SqrtData[m] = 128;
		else SqrtData[m] = sqrt(m)*128.0;
	}
	for (int m = 0; m <= 10000; m++)
	{
		ArcSinData[m] = (int)(asin((float)m / 10000.0)*180.0 / 3.141592 + 0.5);
	}

  for (int i = 0; i < 720; i++)
	{
		CosData[i] = cos((float)i / 2.0*PI / 180.0) * 1024;
		SinData[i] = sin((float)i / 2.0*PI / 180.0) * 1024;
	}

  Panel22->DoubleBuffered = true;
	GroupBox2->DoubleBuffered = true;
	GroupBox3->DoubleBuffered = true;
	GroupBox15->DoubleBuffered = true;
	GroupBox13->DoubleBuffered = true;
	GroupBox31->DoubleBuffered = true;
	Panel3->DoubleBuffered = true;
	ZoomOptionBoxFor3D->DoubleBuffered = true;

	GroupBox10->DoubleBuffered = true;
	GroupBox6->DoubleBuffered = true;
	Panel1->DoubleBuffered = true;
	GroupBox26->DoubleBuffered = true;
	Panel17->DoubleBuffered = true;
	GroupBox11->DoubleBuffered = true;
	ZoomOptionBox->DoubleBuffered = true;
	SetThresholdPanel->DoubleBuffered = true;

	zoomInOutShiftX = 0;
	zoomInOutShiftY = 0;
	zoomInOutSize = 2;
	zoomImageNavigateFlag = 0;
	navigateStdX = 0;
	navigateStdY = 0;
	zoomROIX1 = 0;
	zoomROIY1 = 0;
	zoomROIX2 = 0;
	zoomROIY2 = 0;

	ZoomSizeLabel->Caption = "x " + IntToStr(zoomInOutSize);

	zoomInOutShiftX3D = 0;
	zoomInOutShiftY3D = 0;
	zoomInOutSize3D = 1;
	zoomImageNavigateFlag3D = 0;
	navigateStdX3D = 0;
	navigateStdY3D = 0;
	zoomROIX1For3D = 0;
	zoomROIY1For3D = 0;
	zoomROIX2For3D = 0;
	zoomROIY2For3D = 0;

	ZoomSize3DLabel->Caption = "x " + IntToStr(zoomInOutSize3D);

	if (TabletCharacter.kind == SUGARCOATING)
	{
		SetThresholdBtn->Visible = false;
	}

	if (TabletCharacter.discriminationDisplay_kind == STAMP || TabletCharacter.tabletDivisionLineInfo)
	{
		bThreeDDataExtraction = true;
		ThreeDDiscriminationExtractButton->Enabled = true;
	}
	else
	{
		bThreeDDataExtraction = false;
		ThreeDDiscriminationExtractButton->Enabled = false;
	}

  if (TabletCharacter.kind == SUGARCOATING)
	{
    GetThreeDInfoButton->Visible = false;
	}
  else
  {
    GetThreeDInfoButton->Visible = true;
  }

  if(!TabletCharacter.MarvelingTablet &&
      TabletCharacter.kind != SUGARCOATING &&
      TabletCharacter.discriminationDisplay_kind == PRINT &&
      TabletCharacter.tabletDivisionLineInfo)
  {
    ExtractSplitLineBtn->Visible = true;
  }
  else
  {
    ExtractSplitLineBtn->Visible = false;
  }

  frontFace2DInfoMode = FRONT_GET_DATA_MODE_NONE;

  for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    AnsiString ConvertString;
    if(SystemLinkCameraInfo[globalCameraIndex] != 0)
    {
      TStaticText *CameraLabel = (TStaticText *)FindComponent("CameraLabel" + IntToStr(globalCameraIndex+1));

      ConvertString = ConvertCameraIndex(globalCameraIndex);
      CameraLabel->Caption = ConvertString;
    }
  }

  if(GlobalProgramID == PROGRAM_ID_150P)
  {
    //SELMA150P
    int MoveD1 = ComponentReposition(1,0,0,dstSideFaceImageCam3->Width);

    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      if(globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX-1 && globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX-1
      && globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX-1 && globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX-1)
      {
        TImage *dstSideFaceImageCam =  (TImage *)FindComponent("dstSideFaceImageCam" + IntToStr(globalCameraIndex+1));
        TStaticText *CameraLabel = (TStaticText *)FindComponent("CameraLabel" + IntToStr(globalCameraIndex+1));
        TTrackBar *SideTrackBar = (TTrackBar *)FindComponent("SideThresholdForEachCamera" + IntToStr(globalCameraIndex+1));

        if(SystemLinkCameraInfo[globalCameraIndex] == 0)
        {
          dstSideFaceImageCam->Visible = false;
          CameraLabel->Visible = false;
          SideTrackBar->Visible = false;
        }
        else
        {
          dstSideFaceImageCam->Left += MoveD1;
          CameraLabel->Left += MoveD1;
          SideTrackBar->Left += MoveD1;
        }
      }
    }
  }
  else if(ProductData.TabletType == TABLET_TYPE_SUGAR_COATED)
  {
    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      if(globalCameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
        globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1 ||
        globalCameraIndex == SD2_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
        globalCameraIndex == SD2_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1)
      {
        TImage *dstSideFaceImageCam =  (TImage *)FindComponent("dstSideFaceImageCam" + IntToStr(globalCameraIndex+1));
        TStaticText *CameraLabel = (TStaticText *)FindComponent("CameraLabel" + IntToStr(globalCameraIndex+1));
        TTrackBar *SideTrackBar = (TTrackBar *)FindComponent("SideThresholdForEachCamera" + IntToStr(globalCameraIndex+1));

        if(dstSideFaceImageCam)
        {
          dstSideFaceImageCam->Visible = false;
        }

        if(CameraLabel)
        {
          CameraLabel->Visible = false;
        }

        if(SideTrackBar)
        {
          SideTrackBar->Visible = false;
        }
      }
    }
  }

  makeOffsetData();
  
  SetupDataChanged = false;
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::ColorRateRangeImage_RearMouseDown(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
  TabletSetupData.TabletColorRange_Rear = X / (ColorRateRangeImage_Rear->Width / 100) + 1;
	SideFaceThresholdValueDisplay();
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::OtherPrintSettingButtonClick(
      TObject *Sender)
{
  GroupBox26->Visible = false;
	GroupBox30->Visible = true;
	GroupBox31->Visible = true;
	BitBtn27->Visible = false;
	BitBtn29->Visible = false;
	BitBtn30->Visible = false;
	BitBtn31->Visible = false;
  OtherPrintSettingButton->Visible = false;
	ZoomOptionBoxFor3D->Visible = false;
	Image70->Canvas->Brush->Style = bsSolid;
	Image70->Canvas->Brush->Color = clWhite;
	Image70->Canvas->Rectangle(0, 0, Image70->Width, Image70->Height);
	Image70->Canvas->Pen->Color = clRed;
	Image70->Canvas->Brush->Color = clRed;
	Image70->Canvas->Ellipse(Image70->Width / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 - (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Width / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5), Image70->Height / 2 + (((float)DrawMaskWidth) / 2.0 + 0.5));

	OtherPrintSettingSW = 1;
	DrawMaskWidth = 10;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = ImageWidth;
	img1->Height = ImageHeight;
	img1->PixelFormat = pf24bit;

	Byte *ptr;
	int tx, ty;
	if (SelectedFace == 0)
	{
		memset(OhterFacePrintBinaryData, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1slice_printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_slice_printData1[m][0];
				ty = Tablet3DSetupData.Disk1position_slice_printData1[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2slice_printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_slice_printData1[m][0];
				ty = Tablet3DSetupData.Disk2position_slice_printData1[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
	}
	else if (SelectedFace == 1)
	{
		memset(OhterFacePrintBinaryData, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);
		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1slice_printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_slice_printData2[m][0];
				ty = Tablet3DSetupData.Disk1position_slice_printData2[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2slice_printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_slice_printData2[m][0];
				ty = Tablet3DSetupData.Disk2position_slice_printData2[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				OhterFacePrintBinaryData[ty*IMAGE_3D_WIDTH + tx] = 1;
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
	}

	Image71->Picture->Bitmap->Assign(img1);
	Image71->Refresh();
	delete(img1);
}
//---------------------------------------------------------------------------

bool __fastcall TTabletCharacterExtractForm::OtherFacePrintInformationCalculationForThreeD(void)
{
  unsigned char tempThreeDPrintData[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	int Pixel_N_Of_Label[MAX_LABEL_COUNT];
	int rX, rY;
	int tx, ty;
	int i, j;
	int n, m, k;
	short label_Image[IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT];
	int printCenterX, printCenterY;
	int tempCount;
	int r;
	int tempX, tempY;
	int transX, transY;
  int tempAddress;

	int labelN;
	Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = IMAGE_3D_WIDTH;
	img1->Height = IMAGE_3D_HEIGHT;
	img1->PixelFormat = pf24bit;

	Byte *ptr;

  int otherface;
  if (SelectedFace == 0)
  {
    otherface = 1;
  }
  else
  {
    otherface = 0;
  }

  printCenterX = IMAGE_3D_WIDTH / 2;
  printCenterY = IMAGE_3D_HEIGHT / 2;

  memset(tempThreeDPrintData, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);

  for (int y = 0; y < IMAGE_3D_HEIGHT; y++)
  {
    for (int x = 0; x < IMAGE_3D_WIDTH; x++)
    {
      tempAddress = IMAGE_3D_WIDTH * y + x;
      if (OhterFacePrintBinaryData[tempAddress] == 2)
      {
        tempThreeDPrintData[tempAddress] = 1;
      }
    }
  }

  labelN = PrintLabelingForThreeDImage(tempThreeDPrintData, label_Image, Pixel_N_Of_Label);
  RotationAngleInSelectedImage = 0;

  memset(tempThreeDPrintData, 0, IMAGE_3D_WIDTH*IMAGE_3D_HEIGHT);

	if (SelectedFace == 0)
	{
		if (SelectDisk == DISK1)
		{
      if(Tablet3DSetupData.Disk1slice_printData1Count)
      {
        for(m = 0; m < Tablet3DSetupData.Disk1slice_printData1Count; m++)
        {
          tempX = Tablet3DSetupData.Disk1position_slice_printData1[m][0];
          tempY = Tablet3DSetupData.Disk1position_slice_printData1[m][1];

          tempAddress = IMAGE_3D_WIDTH * tempY + tempX;
          tempThreeDPrintData[tempAddress] = 1;
        }
      }

			Tablet3DSetupData.Disk1printData2Count = 0;
			Tablet3DSetupData.Disk1slice_printData2Count = 0;
			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (OhterFacePrintBinaryData[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk1printData2Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_printData2[Tablet3DSetupData.Disk1printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_printData2[Tablet3DSetupData.Disk1printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
          tempAddress = y * IMAGE_3D_WIDTH + x;
					if (OhterFacePrintBinaryData[tempAddress] == 2 && tempThreeDPrintData[tempAddress])
					{
						if (Tablet3DSetupData.Disk1slice_printData2Count < THREED_SLICE_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_slice_printData2[Tablet3DSetupData.Disk1slice_printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_slice_printData2[Tablet3DSetupData.Disk1slice_printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1slice_printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}
		}
		else
		{
      if(Tablet3DSetupData.Disk2slice_printData1Count)
      {
        for(m = 0; m < Tablet3DSetupData.Disk2slice_printData1Count; m++)
        {
          tempX = Tablet3DSetupData.Disk2position_slice_printData1[m][0];
          tempY = Tablet3DSetupData.Disk2position_slice_printData1[m][1];

          tempAddress = IMAGE_3D_WIDTH * tempY + tempX;
          tempThreeDPrintData[tempAddress] = 1;
        }
      }

      Tablet3DSetupData.Disk2printData2Count = 0;
			Tablet3DSetupData.Disk2slice_printData2Count = 0;
			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (OhterFacePrintBinaryData[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk2printData2Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk2position_printData2[Tablet3DSetupData.Disk2printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_printData2[Tablet3DSetupData.Disk2printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
          tempAddress = y * IMAGE_3D_WIDTH + x;
					if (OhterFacePrintBinaryData[tempAddress] == 2 && tempThreeDPrintData[tempAddress])
					{
						if (Tablet3DSetupData.Disk2slice_printData2Count < THREED_SLICE_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk2position_slice_printData2[Tablet3DSetupData.Disk2slice_printData2Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_slice_printData2[Tablet3DSetupData.Disk2slice_printData2Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2slice_printData2Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}
		}

		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_printData2[m][0];
				ty = Tablet3DSetupData.Disk1position_printData2[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2printData2Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_printData2[m][0];
				ty = Tablet3DSetupData.Disk2position_printData2[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}

    Image62->Picture->Bitmap->Assign(img1);
		Image62->Refresh();
		Image28->Picture->Bitmap->Assign(img1);
		Image28->Stretch = true;
		Image28->Refresh();
		delete(img1);
	}
	else
	{
    if (SelectDisk == DISK1)
		{
      if(Tablet3DSetupData.Disk1slice_printData2Count)
      {
        for(m = 0; m < Tablet3DSetupData.Disk1slice_printData2Count; m++)
        {
          tempX = Tablet3DSetupData.Disk1position_slice_printData2[m][0];
          tempY = Tablet3DSetupData.Disk1position_slice_printData2[m][1];

          tempAddress = IMAGE_3D_WIDTH * tempY + tempX;
          tempThreeDPrintData[tempAddress] = 1;
        }
      }

			Tablet3DSetupData.Disk1printData1Count = 0;
			Tablet3DSetupData.Disk1slice_printData1Count = 0;
			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (OhterFacePrintBinaryData[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk1printData1Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_printData1[Tablet3DSetupData.Disk1printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_printData1[Tablet3DSetupData.Disk1printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
          tempAddress = y * IMAGE_3D_WIDTH + x;
					if (OhterFacePrintBinaryData[tempAddress] == 2 && tempThreeDPrintData[tempAddress])
					{
						if (Tablet3DSetupData.Disk1slice_printData1Count < THREED_SLICE_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk1position_slice_printData1[Tablet3DSetupData.Disk1slice_printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk1position_slice_printData1[Tablet3DSetupData.Disk1slice_printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk1slice_printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}
		}
		else
		{
      if(Tablet3DSetupData.Disk2slice_printData2Count)
      {
        for(m = 0; m < Tablet3DSetupData.Disk2slice_printData2Count; m++)
        {
          tempX = Tablet3DSetupData.Disk2position_slice_printData2[m][0];
          tempY = Tablet3DSetupData.Disk2position_slice_printData2[m][1];

          tempAddress = IMAGE_3D_WIDTH * tempY + tempX;
          tempThreeDPrintData[tempAddress] = 1;
        }
      }

      Tablet3DSetupData.Disk2printData1Count = 0;
			Tablet3DSetupData.Disk2slice_printData1Count = 0;
			for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
					if (OhterFacePrintBinaryData[y*IMAGE_3D_WIDTH + x] == 2)
					{
						if (Tablet3DSetupData.Disk2printData1Count < THREED_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk2position_printData1[Tablet3DSetupData.Disk2printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_printData1[Tablet3DSetupData.Disk2printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
			}

      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
			{
				for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
				{
          tempAddress = y * IMAGE_3D_WIDTH + x;
					if (OhterFacePrintBinaryData[tempAddress] == 2 && tempThreeDPrintData[tempAddress])
					{
						if (Tablet3DSetupData.Disk2slice_printData1Count < THREED_SLICE_PRINT_DATA_SIZE)
						{
							Tablet3DSetupData.Disk2position_slice_printData1[Tablet3DSetupData.Disk2slice_printData1Count][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
							Tablet3DSetupData.Disk2position_slice_printData1[Tablet3DSetupData.Disk2slice_printData1Count][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
							Tablet3DSetupData.Disk2slice_printData1Count++;
						}
						else
						{
							ShowMessageW(TABLETCHARACTEREXTRACTFORM_MSG_02);
							return(0);
						}
					}
				}
      }
    }

		if (SelectDisk == DISK1)
		{
			for (int m = 0; m < Tablet3DSetupData.Disk1printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk1position_printData1[m][0];
				ty = Tablet3DSetupData.Disk1position_printData1[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}
		else
		{
			for (int m = 0; m < Tablet3DSetupData.Disk2printData1Count; m++)
			{
				tx = Tablet3DSetupData.Disk2position_printData1[m][0];
				ty = Tablet3DSetupData.Disk2position_printData1[m][1];
				ptr = (byte*)img1->ScanLine[ty];
				ptr[3 * tx] = 0;
				ptr[3 * tx + 1] = 0;
				ptr[3 * tx + 2] = 0;
			}
		}


    Image62->Picture->Bitmap->Assign(img1);
		Image62->Refresh();
		Image23->Picture->Bitmap->Assign(img1);
		Image23->Stretch = true;
		Image23->Refresh();
		delete(img1);
	}

  memset(Tablet3DSetupData.printMaskData[SelectDisk - 1][otherface], 0, sizeof(short) * THREED_PRINT_MAX_LABEL_COUNT * PRINT_LABEL_DATA_SIZE);
  for (int n = 0; n < THREED_PRINT_MAX_LABEL_COUNT; n++)
  {
    Tablet3DSetupData.printLabelDataCnt[SelectDisk - 1][otherface][n] = 0;
  }
  int tempLabelN;
  tempLabelN = 0;
  for (int n = 0; n < labelN; n++)
  {
    if (Pixel_N_Of_Label[n + 1] > 20)
    {
      for (int y = 10; y < IMAGE_3D_HEIGHT - 10; y++)
      {
        for (int x = 10; x < IMAGE_3D_WIDTH - 10; x++)
        {
          if (label_Image[y*IMAGE_3D_WIDTH + x] == n + 1)
          {
            if (Tablet3DSetupData.printLabelDataCnt[SelectDisk - 1][otherface][tempLabelN] < PRINT_LABEL_DATA_SIZE)
            {
              Tablet3DSetupData.printLabelData[SelectDisk - 1][otherface][tempLabelN][Tablet3DSetupData.printLabelDataCnt[SelectDisk - 1][otherface][tempLabelN]][0] = x - (printCenterX - IMAGE_3D_WIDTH / 2);
              Tablet3DSetupData.printLabelData[SelectDisk - 1][otherface][tempLabelN][Tablet3DSetupData.printLabelDataCnt[SelectDisk - 1][otherface][tempLabelN]][1] = y - (printCenterY - IMAGE_3D_HEIGHT / 2);
              Tablet3DSetupData.printLabelDataCnt[SelectDisk - 1][otherface][tempLabelN]++;
            }
            else
            {
              if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
              {
                tempLabelN++;
              }
            }
          }
        }
      }
      if (tempLabelN < THREED_PRINT_MAX_LABEL_COUNT - 1)
      {
        tempLabelN++;
      }
    }
  }
  Tablet3DSetupData.printLabelCount[SelectDisk - 1][otherface] = tempLabelN;
  Tablet3DSetupData.PrintAverageDepth[SelectDisk - 1][otherface] = Tablet3DSetupData.PrintAverageDepth[SelectDisk - 1][SelectedFace];
}



void __fastcall TTabletCharacterExtractForm::SideThrEachCheckBoxClick(
      TObject *Sender)
{
  if(SideThrEachCheckBox->Checked)
  {
  	TabletSetupData.TabletColorRangeEachActive = SIDE_COLORATE_SET_EACH_INABLE;

    for(int globalCameraIndex=1; globalCameraIndex<=SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
		if (globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
        {
    		TTntEdit *tempEdit = ((TTntEdit *)FindComponent("SideThrEachEdit" + IntToStr(globalCameraIndex)));
            TTrackBar *tmpTrackBar = ((TTrackBar *)FindComponent("colorRateRangeTrackBar" + IntToStr(globalCameraIndex)));
            TTntLabel *tmpLabel = ((TTntLabel *)FindComponent("colorRateRangeLabel" + IntToStr(globalCameraIndex)));

            tempEdit->Visible = true;
            tmpTrackBar->Visible = true;
            tmpLabel->Visible = true;

            tempEdit->Text = IntToStr(TabletSetupData.TabletColorRangeEach[globalCameraIndex-1]);
            tmpTrackBar->Position = TabletSetupData.TabletColorRangeEach[globalCameraIndex-1];
        }
    }

	SideFaceThresholdValueDisplay();
  }
  else
  {
  	TabletSetupData.TabletColorRangeEachActive = SIDE_COLORATE_SET_EACH_DISABLE;

    for(int globalCameraIndex=1; globalCameraIndex<=SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
		if (globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
        {
    		TTntEdit *tempEdit = ((TTntEdit *)FindComponent("SideThrEachEdit" + IntToStr(globalCameraIndex)));
            TTrackBar *tmpTrackBar = ((TTrackBar *)FindComponent("colorRateRangeTrackBar" + IntToStr(globalCameraIndex)));
            TTntLabel *tmpLabel = ((TTntLabel *)FindComponent("colorRateRangeLabel" + IntToStr(globalCameraIndex)));

            tempEdit->Visible = false;
            tmpTrackBar->Visible = false;
            tmpLabel->Visible = false;
        }
    }
  }	
}
//---------------------------------------------------------------------------

void __fastcall TTabletCharacterExtractForm::SideThrEachEdit2Click(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	int cameraIndex = theEdit->Tag;
	KeyboardForm->Text = theEdit->Text;

  if(bInit) return;
                                       
  if (KeyboardForm->ShowKeypad() == mrOk)
  {
  	theEdit->Text = KeyboardForm->Text;

    int inputVal = StrToInt(theEdit->Text);

    if(inputVal > 100)
    {
    	theEdit->Text = "100";
        inputVal = 100;
    }

   	TabletSetupData.TabletColorRangeEach[cameraIndex-1] = inputVal;


    for(int globalCameraIndex=1; globalCameraIndex<=SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
		if (globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
        {
    		TTntEdit *tempEdit = ((TTntEdit *)FindComponent("SideThrEachEdit" + IntToStr(globalCameraIndex)));

        	TabletSetupData.TabletColorRangeEach[globalCameraIndex-1] = StrToInt(tempEdit->Text);

            TTrackBar *tmpTrackBar = ((TTrackBar *)FindComponent("colorRateRangeTrackBar" + IntToStr(globalCameraIndex)));

			tmpTrackBar->Position = TabletSetupData.TabletColorRangeEach[globalCameraIndex-1];
        }
    }

	SideFaceThresholdValueDisplay();
  }
}
//---------------------------------------------------------------------------


void __fastcall TTabletCharacterExtractForm::colorRateRangeTrackBar2Change(
      TObject *Sender)
{
  if(bInit) return;

  TTrackBar *tempTrackBar = (TTrackBar *)Sender;
  int cameraIndex = tempTrackBar->Tag;
  TabletSetupData.TabletColorRangeEach[cameraIndex-1] = tempTrackBar->Position;

    for(int globalCameraIndex=1; globalCameraIndex<=SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
		if (globalCameraIndex != SD1_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_2D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
        globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
        {
    		TTntEdit *tempEdit = ((TTntEdit *)FindComponent("SideThrEachEdit" + IntToStr(globalCameraIndex)));

        	tempEdit->Text = IntToStr(TabletSetupData.TabletColorRangeEach[globalCameraIndex-1]); 
        }
    }

  SideFaceThresholdValueDisplay();
}
//---------------------------------------------------------------------------

