#ifdef PC_SIM
#include <mem.h>
#endif
#ifdef TARGET_PC
#include <mem.h>
#endif
#include <math.h>
#include "CPB_Module_Side.h"

//---------------------------------------------------------------------------
#pragma DATA_ALIGN(8)
#pragma DATA_SECTION(".sdram")
unsigned char tempHalfShapeBinaryImage[(HALF_IMAGE_WIDTH) * (HALF_IMAGE_HEIGHT)];

#pragma DATA_ALIGN(8)
#pragma DATA_SECTION(".sdram")
unsigned short RotationLineForCoatedTablet[180][SIDE_FACE_ROTATION_LINE_DATA_COUNT * 2];
int RotationLineDataCount;

int MeanColorR2;
int MeanColorG2;
int MeanColorB2;

//---------------------------------------------------------------------------
void ProcessingStartForSideFace_M45(int processingMode, int cameraIndex, int ImageConvertOption)
{
	ProcessingStartForSideFace(processingMode, cameraIndex, SIDE_FACE_M45, ImageConvertOption);
}
//---------------------------------------------------------------------------
void ProcessingStartForSideFace_P45(int processingMode, int cameraIndex, int ImageConvertOption)
{
	ProcessingStartForSideFace(processingMode, cameraIndex, SIDE_FACE_P45, ImageConvertOption);
}
//---------------------------------------------------------------------------
void ProcessingStartForSideFace_0(int processingMode, int cameraIndex, int ImageConvertOption)
{
	ProcessingStartForSideFace(processingMode, cameraIndex, SIDE_FACE_0, ImageConvertOption);
}
//---------------------------------------------------------------------------
void ProcessingStartForSideFace(int processingMode, int cameraIndex, int sideFaceOption, int ImageConvertOption)
{
	/*
	현재 정제의 바텀라인에 대해 외곽선 매칭을 통한 정제 영역 설정이 아닌 외곽라인 모델링을 통해 매칭 시도
	-> 외곽선 매칭 시 생성되어야 하는 템플릿의 양이 너무 많아짐(3차원)

	-> 그럼 뭐가 바텀라인인지 알아야겠네?
	-> 이 영역이 현재 이미지 상에서 정제의 바텀라인이다 라인걸 알기위해서는
	a) 이미지상에서 정제와 정제가 아닌 영역을 명확하게 구분해야할것이며
	b) 정제에서도 현재라인이 바텀라인이지 사이드라인이지 알아야할 것


	1. 영상에서 정제와 정제를 제외한 영역을 명확하게 구분하기 (현재 상태에서 잘되는 걸로 가정)
	2. 정제의 사이드라인찾기
	a) 단순하게 일직선라인을 매칭시키면 정제 모양에 따라 매칭된 부분이 사이드 라인인지 바텀라인인지 알 수 없음(사각형 정제)
	b) 사이드 라인을 알면 정제의 틸팅각도를 확인할 수 있음.. 어디에 활용하는데?
	c) 틸팅각도를 찾는것 자체가 사이드 라인을 확인하기 위함 아니냐?... 탑라인 매칭에 활용될 수는 있겠다
	d) 사이드 라인을 찾는 것의 목적은 이미지 상에서 바텀라인의 예상 후보영역을 제한하기 위함임



	e-1) important point -> 일직선 라인의 side line 매칭 시 이점을 반드시 포함해야한다.
	e-2) important point -> binary 좌우 끝점이면서 하단과 좌, 우측의(센터기준 좌측 영역이면 기준픽셀의 좌측과 비교, 우측영역이면 기준픽셀의 우측과 비교)  미분값이 특정값 이상인 경우
	e-3) 그럼 여기서 binary 라는 변수가 존재하는데
	e-4) 기본적인 shape binary image(현재 프로세스 결과)는 정제 영역은 반드시 포함되지만, 배경이 포함될 수 있음
	e-5) 그럼 여기서 shpae Binary image를 필터링하여 정제와 배경을 분리해야함

	*/
	//
	// 상 좌 우 shift
	// 뭐를?

	ProcessingModeGlobal = processingMode;

	DefectSW = 0;
	TheOhterSideShapeMatchingSW = 0;

	DataInitiate(NOT_THREED, cameraIndex);
	ColorChange(cameraIndex, ImageConvertOption);

	PreProcessingForSideFace(cameraIndex); // 여기까지 PC에서 12ms 정도 소요.

	if (TabletCharacter.kind != SUGARCOATING)
	{
		if (DefectSW == 0)
		{
			if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
			{
				SideFaceShapeMatching(sideFaceOption, cameraIndex); // PC에서 16ms 정도 소요.
			}
			else
			{
				GetTabletSideShapeInformation(cameraIndex);

				if (DefectSW == 0)
				{
					SideFaceShapeMatchingForETC(cameraIndex);
				}
			}

			if (ProcessingModeGlobal == INSPECTION_MODE)
			{
				if (DefectSW == 0)
				{
					if (TabletCharacter.kind == SUGARCOATING)
					{
						DefectSearchForSideShapeForSugarCoating(cameraIndex);
					}
					else
					{
						if (TabletCharacter.HighResolutionImage)
						{
							HighResolutionDefectSearchForSideShape(cameraIndex);
						}
						else
						{
							DefectSearchForSideShape(cameraIndex); // 이것은 의외로 별로 안느리다. PC에서 4ms 정도 소요.
						}
					}
				}

				if (DefectSW == 0 && TabletCharacter.tabletLayerCount < 3)
					DefectSearchForSideColorDirty(cameraIndex);

				if (DefectSW == 0)
					DefectCheckForEdgeBreak(cameraIndex);
			}
		}
	}
	else
	{
		if (DefectSW == 0)
		{
			SideFaceShapeMatching(sideFaceOption, cameraIndex);

			if (ProcessingModeGlobal == INSPECTION_MODE)
			{
				if (DefectSW == 0)
				{
					if (TabletCharacter.kind == SUGARCOATING)
					{
						DefectSearchForSideShapeForSugarCoating(cameraIndex);
					}
					else
					{
						if (TabletCharacter.HighResolutionImage)
						{
							HighResolutionDefectSearchForSideShape(cameraIndex);
						}
						else
						{
							DefectSearchForSideShape(cameraIndex);
						}
					}
				}

				if (DefectSW == 0)
					DefectSearchForSideColorDirty(cameraIndex);
			}
		}
	}

	if (ProcessingModeGlobal == STUDY_MODE)
	{
		SideFaceColorCheck(cameraIndex);
	}
	else if (ProcessingModeGlobal == INSPECTION_MODE && sideFaceOption != SIDE_FACE_0)
	{
		if (TabletGradeData.ETC_ActiveSideEdgeDefectCheck)
		{
			if (TabletCharacter.kind != SUGARCOATING && DefectSW == 0 && TabletCharacter.HighResolutionImage == 0)
			{
				DefectSearhForUninsArea(cameraIndex, sideFaceOption);
			}
		}
	}

#ifdef PC_SIM
	memcpy(InspectionArea_Virtual, InspectionArea, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
}
//---------------------------------------------------------------------------
void PreProcessingForSideFace(int cameraIndex)
{
	int x, y;
	int protoThrshold;
	int gradX, gradY;
	int tempCount;
	int tempSum;
	int startX, endX, startY, endY;
	int halfStartX, halfEndX, halfStartY, halfEndY;
	int tempAddress;
	int maxLabelN;
	short *tempLabelImage;
	short *tempLabelImage2;
	unsigned char *tempBinaryImage;
	int minX, maxX, minY, maxY;
	int option;
	int value[3];
	int ColorFactorCheckSW;
	int colorFactorRate[3];
	int higherFactorTable[3];
	int imgHigherFactorTable[3];
	int m, k;
	int tempValue;
	int tempFactor;
	int maxHeight;
	int heightCheckSW;
	int ClosedAreaSize;
	int areaHeight;
	int colorDistribution[3];
	int tempAddress2;
	int gradValue;
	int maxValue;
	int G1, G2;
	int i;
	int shiftX;
	int shiftY;
	int gettingDataSW;
	unsigned short OutLineData[20000 * 3];
	int OutLineDataCount;
	int SymmetryPositionX;
	int range;
	int topEndSW;
	int bottomEndSW;
	int r;
	int rX, rY;
	int tempX, tempY;
	int matchingValue;
	int matchingShiftX;
	int matchingShiftY;
	int matchingAngle;
	int fstMatchingShiftX;
	int fstMatchingShiftY;
	int fstMatchingAngle;
	int tabletStartEdge[2];
	int tabletEndEdge[2];
	int uLength;
	int dX, dY;
	int protoTabletAngle;
	int upSW1, upSW2;
	int downSW1, downSW2;
	int left, right, top, bottom;
	int ROIWidth, ROIHeight;
	int StudyColorRatio[3];
	int StudyColorRatio_Rear[3];

	int tempSelectedRGB;
	int tempSelectedRGB_Rear;

#ifdef PC_SIM
	int centerShiftX, centerShiftY;
#endif

	if (cameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX ||
		cameraIndex == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX ||
		cameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX ||
		cameraIndex == SD2_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX)
	{
		option = CASE2;
	}
	else
	{
		option = CASE1;
	}

	startX = TabletSetupData.ImageCutStartX[cameraIndex - 1] + 4;
	endX = TabletSetupData.ImageCutEndX[cameraIndex - 1] - 4;
	startY = TabletSetupData.ImageCutStartY[cameraIndex - 1] + 4;
	endY = TabletSetupData.ImageCutEndY[cameraIndex - 1] - 4;

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

	ROIWidth = endX - startX;
	ROIHeight = endY - startY;

	halfStartX = startX / 2;
	halfEndX = endX / 2;
	halfStartY = startY / 2;
	halfEndY = endY / 2;

	tempBinaryImage = BrightPixelNeighborPrint;

	tempLabelImage = HalfLabelImage;
	tempLabelImage2 = RotationEdgeImage;

	ProtoTabletRotationAngle = 0;

	protoThrshold = TabletSetupData.SideFaceShapeExtractThreshold + TabletSetupData.SideThresholdForEachCamera[cameraIndex - 1];
	if (protoThrshold <= 1)
		protoThrshold = 1;
	else if (protoThrshold >= 160)
		protoThrshold = 160;

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;
			tempSum = (OneColorImage[tempAddress] + OneColorImage[tempAddress - 1] + OneColorImage[tempAddress + 1] + OneColorImage[tempAddress - MAX_IMAGE_WIDTH] + OneColorImage[tempAddress + MAX_IMAGE_WIDTH]) / 5;

			MeanOneColorImage[tempAddress] = tempSum;
		}
	}

	tempSelectedRGB = tempSelectedRGB_Rear = 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)
			{
				tempSelectedRGB = 2;
			}
		}
		if (TabletSetupData.protoStudyColorB > TabletSetupData.protoStudyColorG * 110 / 100)
		{
			if (TabletSetupData.protoStudyColorB > TabletSetupData.protoStudyColorR * 110 / 100)
			{
				tempSelectedRGB = 0;
			}
		}
	}

	if (TabletCharacter.tabletLayerCount == 1)
	{
		if (ProcessingModeGlobal == INSPECTION_MODE)
		{
			value[0] = TabletStudyData.SideFaceTabletBColor[cameraIndex - 1];
			value[1] = TabletStudyData.SideFaceTabletGColor[cameraIndex - 1];
			value[2] = TabletStudyData.SideFaceTabletRColor[cameraIndex - 1];

			if (value[0] + value[1] + value[2])
			{
				StudyColorRatio[0] = value[0] * 1000 / (value[0] + value[1] + value[2]);
				StudyColorRatio[1] = value[1] * 1000 / (value[0] + value[1] + value[2]);
				StudyColorRatio[2] = value[2] * 1000 / (value[0] + value[1] + value[2]);
			}
			else
			{
				StudyColorRatio[0] = TabletSetupData.TabletColorRatio[0];
				StudyColorRatio[1] = TabletSetupData.TabletColorRatio[1];
				StudyColorRatio[2] = TabletSetupData.TabletColorRatio[2];
			}
		}
		else
		{
			StudyColorRatio[0] = TabletSetupData.TabletColorRatio[0];
			StudyColorRatio[1] = TabletSetupData.TabletColorRatio[1];
			StudyColorRatio[2] = TabletSetupData.TabletColorRatio[2];
		}

		tempSelectedRGB_Rear = tempSelectedRGB;
	}
	else
	{
		StudyColorRatio[0] = TabletSetupData.TabletColorRatio[0];
		StudyColorRatio[1] = TabletSetupData.TabletColorRatio[1];
		StudyColorRatio[2] = TabletSetupData.TabletColorRatio[2];

		StudyColorRatio_Rear[0] = TabletSetupData.TabletColorRatio_Rear[0];
		StudyColorRatio_Rear[1] = TabletSetupData.TabletColorRatio_Rear[1];
		StudyColorRatio_Rear[2] = TabletSetupData.TabletColorRatio_Rear[2];

		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)
				{
					tempSelectedRGB_Rear = 2;
				}
			}
			if (TabletSetupData.rear_protoStudyColorB > TabletSetupData.rear_protoStudyColorG * 110 / 100)
			{
				if (TabletSetupData.rear_protoStudyColorB > TabletSetupData.rear_protoStudyColorR * 110 / 100)
				{
					tempSelectedRGB_Rear = 0;
				}
			}
		}
	}

	if (TabletCharacter.kind == SUGARCOATING)
	{
		protoThrshold = 35; // 검사 영역이 이상한것 같으면 shutter speed를 올리자

		memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		memset(tempLabelImage2, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 2);

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (OneColorImage[tempAddress] > protoThrshold)
				{
					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}

		maxLabelN = LabellingForTabletImage(tempLabelImage2, ShapeBinaryImage, startX, endX, startY, endY, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);

		memset(ShapeBinaryImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (tempLabelImage2[tempAddress] == maxLabelN)
				{
					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}

		// 채우기 -> 인쇄, 이물 등으로 인해 정제의 내부가 binary로 포함되지 않을 수 있음
		for (y = startY; y < endY; y++)
		{
			minX = MAX_IMAGE_WIDTH;
			maxX = 0;

			for (x = startX; x < endX; x++)
			{
				if (ShapeBinaryImage[y * MAX_IMAGE_WIDTH + x])
				{
					if (minX > x)
						minX = x;
					if (maxX < x)
						maxX = x;
				}
			}

			for (x = minX; x <= maxX; x++)
			{
				ShapeBinaryImage[y * MAX_IMAGE_WIDTH + x] = 1;
			}
		}

		minX = MAX_IMAGE_WIDTH;
		maxX = 0;
		minY = MAX_IMAGE_HEIGHT;
		maxY = 0;
		ProtoTabletCenterX = ProtoTabletCenterY = tempCount = 0;

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ShapeBinaryImage[tempAddress])
				{
					ProtoTabletCenterX += x;
					ProtoTabletCenterY += y;
					tempCount++;

					if (minY > y)
						minY = y;
					if (maxY < y)
						maxY = y;
					if (minX > x)
						minX = x;
					if (maxX < x)
						maxX = x;
				}
			}
		}

		// 확대
		memcpy(tempBinaryImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY + 2; y < endY - 2; y++)
		{
			for (x = startX + 2; x < endX - 2; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (!tempBinaryImage[tempAddress] &&
					(tempBinaryImage[tempAddress - 2] || tempBinaryImage[tempAddress + 2] ||
					tempBinaryImage[tempAddress - 2 * MAX_IMAGE_WIDTH] || tempBinaryImage[tempAddress + 2 * MAX_IMAGE_WIDTH]))
				{
					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}

		if (tempCount)
		{
			ProtoTabletCenterX /= tempCount;
			ProtoTabletCenterY /= tempCount;

			if (ProcessingModeGlobal == INSPECTION_MODE || ProcessingModeGlobal == STUDY_MODE)
			{
				if (tempCount < ROIWidth * ROIHeight / 20)
				{
					DefectSW = 3;
					return;
				}
			}
		}
		else
		{
			ProtoTabletCenterX = HALF_IMAGE_WIDTH;
			ProtoTabletCenterY = HALF_IMAGE_HEIGHT;

			DefectSW = 3;
			return;
		}

		areaHeight = abs(minY - maxY);
	}
	else
	{
		memset(tempLabelImage, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT * 2);
		memset(tempHalfShapeBinaryImage, 0, HALF_IMAGE_WIDTH * HALF_IMAGE_HEIGHT);

		if (!TabletSetupData.ActiveColorRatioCheck)
		{
			if (tempSelectedRGB != tempSelectedRGB_Rear)
			{
				for (y = halfStartY; y < halfEndY; ++y)
				{
					for (x = halfStartX; x < halfEndX; ++x)
					{			
						tempAddress = y * 2 * MAX_IMAGE_WIDTH + x * 2;

						if ((ColorSourceImage[(tempAddress + 0) * 3 + tempSelectedRGB] > protoThrshold ||
							ColorSourceImage[(tempAddress + 1) * 3 + tempSelectedRGB] > protoThrshold ||
							ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH) * 3 + tempSelectedRGB] > protoThrshold ||
							ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH + 1) * 3 + tempSelectedRGB] > protoThrshold) ||
							(ColorSourceImage[(tempAddress + 0) * 3 + tempSelectedRGB_Rear] > protoThrshold || 
							ColorSourceImage[(tempAddress + 1) * 3 + tempSelectedRGB_Rear] > protoThrshold || 
							ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH) * 3 + tempSelectedRGB_Rear] > protoThrshold || 
							ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH + 1) * 3 + tempSelectedRGB_Rear] > protoThrshold))
						{
							tempHalfShapeBinaryImage[y * HALF_IMAGE_WIDTH + x] = 1;
						}
					}
				}
			}
			else
			{
				for (y = halfStartY; y < halfEndY; ++y)
				{
					for (x = halfStartX; x < halfEndX; ++x)
					{			
						tempAddress = y * 2 * MAX_IMAGE_WIDTH + x * 2;

						if (ColorSourceImage[(tempAddress + 0) * 3 + tempSelectedRGB] > protoThrshold ||
							ColorSourceImage[(tempAddress + 1) * 3 + tempSelectedRGB] > protoThrshold ||
							ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH) * 3 + tempSelectedRGB] > protoThrshold ||
							ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH + 1) * 3 + tempSelectedRGB] > protoThrshold)
						{
							tempHalfShapeBinaryImage[y * HALF_IMAGE_WIDTH + x] = 1;
						}
					}
				}
			}
		}
		else
		{
			for (y = startY; y < endY; ++y)
			{
				for (x = startX; x < endX; ++x)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ColorSourceImage[tempAddress * 3 + tempSelectedRGB] > protoThrshold ||
						ColorSourceImage[tempAddress * 3 + tempSelectedRGB_Rear] > protoThrshold)
					{
						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] > (StudyColorRatio[0] * (100 - TabletSetupData.TabletColorRangeEach[cameraIndex-1])) / 100 &&
									colorFactorRate[0] < (StudyColorRatio[0] * (100 + TabletSetupData.TabletColorRangeEach[cameraIndex-1])) / 100 &&
									colorFactorRate[1] > (StudyColorRatio[1] * (100 - TabletSetupData.TabletColorRangeEach[cameraIndex-1])) / 100 &&
									colorFactorRate[1] < (StudyColorRatio[1] * (100 + TabletSetupData.TabletColorRangeEach[cameraIndex-1])) / 100 &&
									colorFactorRate[2] > (StudyColorRatio[2] * (100 - TabletSetupData.TabletColorRangeEach[cameraIndex-1])) / 100 &&
									colorFactorRate[2] < (StudyColorRatio[2] * (100 + TabletSetupData.TabletColorRangeEach[cameraIndex-1])) / 100)
								{
									tempHalfShapeBinaryImage[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = 1;
								}							
							}
							else
							{
								if (colorFactorRate[0] > (StudyColorRatio[0] * (100 - TabletSetupData.TabletColorRange)) / 100 &&
									colorFactorRate[0] < (StudyColorRatio[0] * (100 + TabletSetupData.TabletColorRange)) / 100 &&
									colorFactorRate[1] > (StudyColorRatio[1] * (100 - TabletSetupData.TabletColorRange)) / 100 &&
									colorFactorRate[1] < (StudyColorRatio[1] * (100 + TabletSetupData.TabletColorRange)) / 100 &&
									colorFactorRate[2] > (StudyColorRatio[2] * (100 - TabletSetupData.TabletColorRange)) / 100 &&
									colorFactorRate[2] < (StudyColorRatio[2] * (100 + TabletSetupData.TabletColorRange)) / 100)
								{
									tempHalfShapeBinaryImage[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = 1;
								}								
							}

						}

						if (TabletCharacter.tabletLayerCount > 1)
						{
							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] > (StudyColorRatio_Rear[0] * (100 - TabletSetupData.TabletColorRange_Rear)) / 100 &&
									colorFactorRate[0] < (StudyColorRatio_Rear[0] * (100 + TabletSetupData.TabletColorRange_Rear)) / 100 &&
									colorFactorRate[1] > (StudyColorRatio_Rear[1] * (100 - TabletSetupData.TabletColorRange_Rear)) / 100 &&
									colorFactorRate[1] < (StudyColorRatio_Rear[1] * (100 + TabletSetupData.TabletColorRange_Rear)) / 100 &&
									colorFactorRate[2] > (StudyColorRatio_Rear[2] * (100 - TabletSetupData.TabletColorRange_Rear)) / 100 &&
									colorFactorRate[2] < (StudyColorRatio_Rear[2] * (100 + TabletSetupData.TabletColorRange_Rear)) / 100)
								{
									tempHalfShapeBinaryImage[(y / 2) * HALF_IMAGE_WIDTH + (x / 2)] = 1;
								}
							}
						}
					}
				}
			}
		}

		maxLabelN = LabellingForTabletImage(tempLabelImage, tempHalfShapeBinaryImage, halfStartX, halfEndX, halfStartY, halfEndY, HALF_IMAGE_WIDTH, HALF_IMAGE_HEIGHT);

		for (y = halfStartY; y < halfEndY; ++y)
		{
			for (x = halfStartX; x < halfEndX; ++x)
			{							
				if (tempLabelImage[HALF_IMAGE_WIDTH * y + x] == maxLabelN)
				{
					tempAddress = y * 2 * MAX_IMAGE_WIDTH + x * 2;
					ShapeBinaryImage[tempAddress] = 1;
					ShapeBinaryImage[tempAddress + 1] = 1;
					ShapeBinaryImage[tempAddress + MAX_IMAGE_WIDTH] = 1;
					ShapeBinaryImage[tempAddress + MAX_IMAGE_WIDTH + 1] = 1;
				}
			}
		}

		// 채우기 -> 인쇄, 이물 등으로 인해 정제의 내부가 binary로 포함되지 않을 수 있음
		for (y = startY; y < endY; y++)
		{
			minX = MAX_IMAGE_WIDTH;
			maxX = 0;

			for (x = startX; x < endX; x++)
			{
				if (ShapeBinaryImage[y * MAX_IMAGE_WIDTH + x])
				{
					if (minX > x)
						minX = x;
					if (maxX < x)
						maxX = x;
				}
			}

			for (x = minX; x <= maxX; x++)
			{
				ShapeBinaryImage[y * MAX_IMAGE_WIDTH + x] = 1;
			}
		}

		memset(tempBinaryImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

		// 벨트로 예상되는 영역 제거, 벨트의 굵기를 최대 32px로 가정
		range = 32;

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ShapeBinaryImage[tempAddress])
				{
					topEndSW = bottomEndSW = 0;
					for (r = 4; r <= range; r += 4)
					{
						if (y - r > startY && !ShapeBinaryImage[tempAddress - r * MAX_IMAGE_WIDTH])
						{
							topEndSW = 1;
							break;
						}
					}

					if (!topEndSW)
						continue;

					for (r = 4; r <= range; r += 4)
					{
						if (y + r < endY && !ShapeBinaryImage[tempAddress + r * MAX_IMAGE_WIDTH])
						{
							bottomEndSW = 1;
							break;
						}
					}

					if (topEndSW && bottomEndSW)
					{
						tempBinaryImage[tempAddress] = 1;
					}
				}
			}
		}
		// end

		// 벨트예상군 제거
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				if (tempBinaryImage[y * MAX_IMAGE_WIDTH + x])
				{
					ShapeBinaryImage[y * MAX_IMAGE_WIDTH + x] = 0;
				}
			}
		}

		// 제거된 영역 중 정제로 예상되는 부분 복원
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (tempBinaryImage[tempAddress])
				{
					topEndSW = bottomEndSW = 0;

					for (r = 4; r <= range; r += 4)
					{
						if (y - r > startY && ShapeBinaryImage[tempAddress - r * MAX_IMAGE_WIDTH])
						{
							tempBinaryImage[tempAddress] = 2;
							topEndSW = 1;
							break;
						}
					}

					if (!topEndSW)
					{
						for (r = 4; r <= range; r += 4)
						{
							if (y + r < endY && ShapeBinaryImage[tempAddress + r * MAX_IMAGE_WIDTH])
							{
								tempBinaryImage[tempAddress] = 2;
								break;
							}
						}
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				if (tempBinaryImage[y * MAX_IMAGE_WIDTH + x] == 2)
				{
					ShapeBinaryImage[y * MAX_IMAGE_WIDTH + x] = 1;
				}
			}
		}

#ifdef PC_SIM
		memcpy(AdjustThreeD_Data, tempBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
		// end

		// 하단부가 이미지 영역을 벗어난 경우에 대한 예외처리? 
		// 이것은 굳이 불필요한 듯하다. 하단부가 밝은 경우 붙기도 하는데 그런 경우에도 아무 문제 없다.
		/*for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * (endY - 4) + x;
			if (ShapeBinaryImage[tempAddress])
			{
				DefectSW = 3;
				break;
			}
		}*/
		// end

		// 확대
		memcpy(realBinaryArea, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		memcpy(tempBinaryImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY + 6; y < endY - 6; y++)
		{
			for (x = startX + 8; x < endX - 8; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				
				if (!tempBinaryImage[tempAddress] && 
					(tempBinaryImage[tempAddress - 8] || tempBinaryImage[tempAddress + 8] || 
					tempBinaryImage[tempAddress - 6 * MAX_IMAGE_WIDTH] || tempBinaryImage[tempAddress + 6 * MAX_IMAGE_WIDTH]))
				{
					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}

		if (!(TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL))
		{
			// 확대
			memcpy(tempBinaryImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
			for (y = startY; y < endY; y++)
			{
				for (x = startX + 4; x < endX - 4; x++)
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;

					if (!tempBinaryImage[tempAddress] && (tempBinaryImage[tempAddress - 4] || tempBinaryImage[tempAddress + 4]))
					{
						ShapeBinaryImage[tempAddress] = 1;
					}
				}
			}
		}

		minX = MAX_IMAGE_WIDTH;
		maxX = 0;
		minY = MAX_IMAGE_HEIGHT;
		maxY = 0;
		ProtoTabletCenterX = ProtoTabletCenterY = tempCount = 0;
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				if (ShapeBinaryImage[MAX_IMAGE_WIDTH * y + x])
				{
					ProtoTabletCenterX += x;
					ProtoTabletCenterY += y;
					tempCount++;

					if (minY > y)
						minY = y;
					if (maxY < y)
						maxY = y;
					if (minX > x)
						minX = x;
					if (maxX < x)
						maxX = x;
				}
			}
		}

		areaHeight = abs(minY - maxY);

		if (tempCount)
		{
			ProtoTabletCenterX /= tempCount;
			ProtoTabletCenterY /= tempCount;

			if (ProcessingModeGlobal == INSPECTION_MODE || ProcessingModeGlobal == STUDY_MODE)
			{
				if (tempCount < ROIWidth * ROIHeight / 20)
				{
					DefectSW = 3;
					return;
				}
			}
		}
		else
		{
			ProtoTabletCenterX = HALF_IMAGE_WIDTH;
			ProtoTabletCenterY = HALF_IMAGE_HEIGHT;

			DefectSW = 3;
			return;
		}

		memset(noneGradientArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY + 8; y < endY - 8; y++)
		{
			for (x = startX + 8; x < endX - 8; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if ((ShapeBinaryImage[tempAddress] || ShapeBinaryImage[tempAddress - 10] || ShapeBinaryImage[tempAddress + 10]) &&
					(OneColorImage[tempAddress + 8] - OneColorImage[tempAddress] > 8 && 
					OneColorImage[tempAddress - 8] - OneColorImage[tempAddress] > 8 && 
					OneColorImage[tempAddress - 8 * MAX_IMAGE_WIDTH] - OneColorImage[tempAddress] > 8 && 
					OneColorImage[tempAddress + 8 * MAX_IMAGE_WIDTH] - OneColorImage[tempAddress] > 8))
				{
					noneGradientArea[tempAddress] = 1;
				}
			}
		}

		for (y = startY + 8; y < endY - 8; y++)
		{
			for (x = startX + 8; x < endX - 8; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if ((!noneGradientArea[tempAddress] &&
					!noneGradientArea[tempAddress - 8] &&
					!noneGradientArea[tempAddress + 8] &&
					!noneGradientArea[tempAddress - 8 * MAX_IMAGE_WIDTH] &&
					!noneGradientArea[tempAddress + 8 * MAX_IMAGE_WIDTH]) &&
					(ShapeBinaryImage[tempAddress] || ShapeBinaryImage[tempAddress - 10] || ShapeBinaryImage[tempAddress + 10]) &&
					(OneColorImage[tempAddress] - OneColorImage[tempAddress + 8] > 8 &&
					OneColorImage[tempAddress] - OneColorImage[tempAddress - 8] > 8 && 
					OneColorImage[tempAddress] - OneColorImage[tempAddress - 8 * MAX_IMAGE_WIDTH] > 8 && 
					OneColorImage[tempAddress] - OneColorImage[tempAddress + 8 * MAX_IMAGE_WIDTH] > 8))
				{
					noneGradientArea[tempAddress] = 1;
				}
			}
		}

		if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
		{
			for (y = startY + 3; y < endY - 3; y++)
			{
				for (x = startX + 2; x < endX - 2; x++)
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;

					if (!noneGradientArea[tempAddress] &&
						(ShapeBinaryImage[tempAddress] || ShapeBinaryImage[tempAddress - 10] || ShapeBinaryImage[tempAddress + 10]))
					{						
						if (x < ProtoTabletCenterX)
							gradX = OneColorImage[tempAddress + 2] - OneColorImage[tempAddress - 2];
						else
							gradX = OneColorImage[tempAddress - 2] - OneColorImage[tempAddress + 2];

						gradY = OneColorImage[tempAddress - 640] - OneColorImage[tempAddress + 1920];

						if (gradX > abs(gradY))
						{
							GradientImage[tempAddress] = gradX;
						}
					}
				}
			}

			for (y = startY + 3; y < endY - 3; y++)
			{
				for (x = startX + 2; x < endX - 2; x++)
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;

					if (!noneGradientArea[tempAddress] && ShapeBinaryImage[tempAddress])
					{
						gradY = OneColorImage[tempAddress - 640] - OneColorImage[tempAddress + 1920];

						if (gradY > 0)
						{
							GradientImage[tempAddress] = max(GradientImage[tempAddress], gradY);
						}
					}
				}
			}

			// 각인에 의해 측면 영역 매칭에 실패하는 경우가 있음
			memcpy(TempImage, GradientImage, 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 ((ShapeBinaryImage[tempAddress] &&
						ShapeBinaryImage[tempAddress - 20] &&
						ShapeBinaryImage[tempAddress + 20] &&
						ShapeBinaryImage[tempAddress - 20 * MAX_IMAGE_WIDTH] &&
						ShapeBinaryImage[tempAddress + 20 * MAX_IMAGE_WIDTH]) &&
						TempImage[tempAddress] > 10 &&
						(OneColorImage[tempAddress] - OneColorImage[tempAddress - MAX_IMAGE_WIDTH * 4] > 10 &&
						OneColorImage[tempAddress] - OneColorImage[tempAddress - MAX_IMAGE_WIDTH * 8] > 10 && 
						OneColorImage[tempAddress] - OneColorImage[tempAddress + MAX_IMAGE_WIDTH * 4] > 10 && 
						OneColorImage[tempAddress] - OneColorImage[tempAddress + MAX_IMAGE_WIDTH * 8] > 10))
					{
						GradientImage[tempAddress] = 0;
						GradientImage[tempAddress - MAX_IMAGE_WIDTH] = 0;
						GradientImage[tempAddress + MAX_IMAGE_WIDTH] = 0;
						GradientImage[tempAddress - 2 * MAX_IMAGE_WIDTH] = 0;
						GradientImage[tempAddress + 2 * MAX_IMAGE_WIDTH] = 0;

						noneGradientArea[tempAddress] = 1;
						noneGradientArea[tempAddress - MAX_IMAGE_WIDTH] = 1;
						noneGradientArea[tempAddress + MAX_IMAGE_WIDTH] = 1;
						noneGradientArea[tempAddress - 2 * MAX_IMAGE_WIDTH] = 1;
						noneGradientArea[tempAddress + 2 * MAX_IMAGE_WIDTH] = 1;
					}
				}
			}
		}
	}

	if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
	{
		if (option == CASE1)
		{
			TabletMatchingResult.SearchStartXForSideShape = minX;

			if (TabletMatchingResult.SearchStartXForSideShape <= startX + 2)
			{
				maxHeight = 0;
				for (x = startX; x <= startX + 2; x++)
				{
					heightCheckSW = 0;
					ClosedAreaSize = 0;
					for (y = startY; y < endY; y++)
					{
						tempAddress = MAX_IMAGE_WIDTH * y + x;

						if (ShapeBinaryImage[tempAddress])
						{
							heightCheckSW = 1;
							ClosedAreaSize++;
						}
						else if (heightCheckSW)
						{
							heightCheckSW = 0;
						}

						if (maxHeight < ClosedAreaSize)
						{
							maxHeight = ClosedAreaSize;
						}

						if (!heightCheckSW)
							ClosedAreaSize = 0;
					}
				}

				if (maxHeight > areaHeight / 5)
				{
					DefectSW = 2;
				}
				TabletMatchingResult.SearchStartXForSideShape = startX;
			}
		}
		if (option == CASE2)
		{
			TabletMatchingResult.SearchStartXForSideShape = maxX;

			if (TabletMatchingResult.SearchStartXForSideShape >= endX - 2)
			{
				maxHeight = 0;
				for (x = endX - 2; x < endX; x++)
				{
					heightCheckSW = 0;
					ClosedAreaSize = 0;
					for (y = startY; y < endY; y++)
					{
						tempAddress = MAX_IMAGE_WIDTH * y + x;

						if (ShapeBinaryImage[tempAddress])
						{
							heightCheckSW = 1;
							ClosedAreaSize++;
						}
						else if (heightCheckSW)
						{
							heightCheckSW = 0;
						}

						if (maxHeight < ClosedAreaSize)
						{
							maxHeight = ClosedAreaSize;
						}

						if (!heightCheckSW)
							ClosedAreaSize = 0;
					}
				}

				if (maxHeight > areaHeight / 5)
				{
					DefectSW = 2;
				}

				TabletMatchingResult.SearchStartXForSideShape = endX;
			}
		}
	}
	else
	{
		TabletMatchingResult.SearchStartXForSideShape = minX;

		if (TabletMatchingResult.SearchStartXForSideShape <= startX + 2)
		{
			maxHeight = 0;
			for (x = startX; x <= startX + 2; x++)
			{
				heightCheckSW = 0;
				ClosedAreaSize = 0;
				for (y = startY; y < endY; y++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ShapeBinaryImage[tempAddress])
					{
						heightCheckSW = 1;
						ClosedAreaSize++;
					}
					else if (heightCheckSW)
					{
						heightCheckSW = 0;
					}

					if (maxHeight < ClosedAreaSize)
					{
						maxHeight = ClosedAreaSize;
					}

					if (!heightCheckSW)
						ClosedAreaSize = 0;
				}
			}

			if (maxHeight > areaHeight / 5)
			{
				DefectSW = 2;
			}
			TabletMatchingResult.SearchStartXForSideShape = startX;
		}

		TabletMatchingResult.SearchEndXForSideShape = maxX;

		if (TabletMatchingResult.SearchEndXForSideShape >= endX - 2)
		{
			maxHeight = 0;
			for (x = endX - 2; x < endX; x++)
			{
				heightCheckSW = 0;
				ClosedAreaSize = 0;
				for (y = startY; y < endY; y++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ShapeBinaryImage[tempAddress])
					{
						heightCheckSW = 1;
						ClosedAreaSize++;
					}
					else if (heightCheckSW)
					{
						heightCheckSW = 0;
					}

					if (maxHeight < ClosedAreaSize)
					{
						maxHeight = ClosedAreaSize;
					}

					if (!heightCheckSW)
						ClosedAreaSize = 0;
				}
			}

			if (maxHeight > areaHeight / 5)
			{
				DefectSW = 2;
			}

			TabletMatchingResult.SearchEndXForSideShape = endX;
		}
	}
	TabletMatchingResult.SideShapeEndY = maxY;

	tabletAreaInfo[AREA_INFO_ST_X_ADDRESS] = minX - 10;
	tabletAreaInfo[AREA_INFO_END_X_ADDRESS] = maxX + 10;
	tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS] = minY - 10;
	tabletAreaInfo[AREA_INFO_END_Y_ADDRESS] = maxY + 10;

	tabletAreaInfo[AREA_INFO_ST_X_ADDRESS] = max(startX, tabletAreaInfo[AREA_INFO_ST_X_ADDRESS]);
	tabletAreaInfo[AREA_INFO_END_X_ADDRESS] = min(endX, tabletAreaInfo[AREA_INFO_END_X_ADDRESS]);
	tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS] = max(startY, tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS]);
	tabletAreaInfo[AREA_INFO_END_Y_ADDRESS] = min(endY, tabletAreaInfo[AREA_INFO_END_Y_ADDRESS]);
}
//---------------------------------------------------------------------------
void SideFaceSetUpDataTransForm(int spbIndex, TSideData *RESTRICT(FullSizeSideData))
{
	int m, x, y;
	unsigned short sizeTransform[2000][2];
	unsigned short eraseEdgeLine[2000];

	unsigned short firstTransformForFace1[2000][3];
	unsigned short firstTransformForFace2[2000][3];

	unsigned short SecondTransformForFace1[2000][3];
	unsigned short SecondTransformForFace2[2000][3];

	unsigned short transfarentEdgeDataPoint[2000][3];
	unsigned short transfarentEdgeDataPoint2[2000][3];
	unsigned char unVisibleEdgeLineCheck[2000];

	int tAngleX;
	int tAngleY;

	int tempX, tempY;
	int tabletCenterX, tabletCenterY, tabletCenterZ;

	int startX1, startY1, endX1, endY1;
	int startX2, startY2, endX2, endY2;
	int start_Number, end_Number;

	int face1Height, face2Height;

	int cameraIndex;
	int shapeEndY;

	int FrontFaceCameraResolution;
	int SideFaceCameraResolution;
	int adjustMiddleHeight;

	int AngleXZeroPos;

	int XAxisDataMakeCount;
	int YAxisDataMakeCount;

	int SideAngle;
	int tempCount;

	unsigned char *tempImage;

	int lineMinX, lineMaxX, lineMinY, lineMaxY;
	int width, height;
	int SideWallLength;
	int halfSideWallLength;
	int shiftCount;
	int shapeMinX, shapeMaxX;
	int ShapeWidth;
	int tempSideWallDataCount;

	// 측면 카메라에서 분할선 매칭에 필요한 데이터 생성
	int tabletLength;
	int avgResolution;
	unsigned short protoLineData[SIDE_FACE_ROTATION_LINE_DATA_COUNT * 2];
	int r;

	int tempIndex;

	const int HALF_CAMERA_INDEX = 9;
	const int MODULE1_3D_CAM_INDEX = 5;
	const int MODULE2_3D_CAM_INDEX = 13;

	int ProcessingSW;	

	TSideShapeData (*SideShapeData)[MAX_ANGLE1_RANGE * 2 + 1];

	tempImage = OneColorImage;

	AngleXZeroPos = 60;

	if (TabletCharacter.middle_height != 0)
	{
		if (TabletCharacter.kind != SUGARCOATING)
		{
			if (TabletCharacter.shape == ROUND ||
				TabletCharacter.shape == OBLONG ||
				TabletCharacter.shape == OVAL)
			{

				int kmax;
				if (spbIndex >= 0)
				{
					kmax = SIDE_ANGLE_TOTAL_COUNT;
				}
				else
				{
					kmax = SYSTEM_TOTAL_CAMERA_COUNT;
				}

				for (int k = 0; k < kmax; ++k)
				{
					if (spbIndex >= 0)
					{
						SideAngle = k;

						cameraIndex = GetGlobalCameraIndex(spbIndex, SideAngle);

						if (cameraIndex == -1)
							continue;

						FrontFaceCameraResolution = TabletSetupData.cameraZoom[0];
						SideFaceCameraResolution = TabletSetupData.cameraZoom[cameraIndex - 1];

						SideShapeData = SideData[SideAngle].SideShapeData;
					}
					else
					{
						cameraIndex = k + 1;

						if (cameraIndex < HALF_CAMERA_INDEX)
						{
							if (cameraIndex < MODULE1_3D_CAM_INDEX)
							{
								tempIndex = 2;
							}
							else
							{
								tempIndex = 3;
							}
						}
						else
						{
							if (cameraIndex < MODULE2_3D_CAM_INDEX)
							{
								tempIndex = 4;
							}
							else
							{
								tempIndex = 5;
							}
						}

						ProcessingSW = 0;
						switch (cameraIndex)
						{
						case SD1_2D_SIDE_FACE_M45_CAMERA_INDEX:
						case SD2_2D_SIDE_FACE_M45_CAMERA_INDEX:
						case SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX:
						case SD2_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX:
							SideAngle = MINUS_45_ANGLE_CAM;
							ProcessingSW = 1;
							break;

						case SD1_2D_SIDE_FACE_00_CAMERA_INDEX:
						case SD2_2D_SIDE_FACE_00_CAMERA_INDEX:
						case SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX:
						case SD2_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX:
							SideAngle = ZERO_ANGLE_CAM;
							ProcessingSW = 1;
							break;

						case SD1_2D_SIDE_FACE_P45_CAMERA_INDEX:
						case SD2_2D_SIDE_FACE_P45_CAMERA_INDEX:
						case SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX:
						case SD2_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX:
							SideAngle = PLUS_45_ANGLE_CAM;
							ProcessingSW = 1;
							break;
						}

						if (!ProcessingSW)
							continue;

						FrontFaceCameraResolution = TabletSetupData.cameraZoom[0];
						SideFaceCameraResolution = TabletSetupData.cameraZoom[(cameraIndex - 1) % 4];

						SideShapeData = FullSizeSideData[cameraIndex - tempIndex].SideShapeData;						
					}

					memset(SideShapeData, 0, sizeof(TSideShapeData) * (MAX_ANGLE2_RANGE * 2 + 1) * (MAX_ANGLE1_RANGE * 2 + 1));

					shapeMinX = MAX_IMAGE_WIDTH;
					shapeMaxX = 0;
					for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
					{
						sizeTransform[m][0] = (TabletSetupData.FrontShapeEdgePoint[m][0] - HALF_IMAGE_WIDTH) * FrontFaceCameraResolution / SideFaceCameraResolution + HALF_IMAGE_WIDTH;
						sizeTransform[m][1] = (TabletSetupData.FrontShapeEdgePoint[m][1] - HALF_IMAGE_HEIGHT) * FrontFaceCameraResolution / SideFaceCameraResolution + HALF_IMAGE_HEIGHT;

						if (sizeTransform[m][0] < shapeMinX)
							shapeMinX = sizeTransform[m][0];
						if (sizeTransform[m][0] > shapeMaxX)
							shapeMaxX = sizeTransform[m][0];
					}

					ShapeWidth = abs(shapeMaxX - shapeMinX);

					adjustMiddleHeight = (TabletCharacter.middle_height * 140 / 100) * FrontFaceCameraResolution / SideFaceCameraResolution;

					memset(tempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
					memset(RotationEdgeImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_WIDTH * 2);
					memset(unVisibleEdgeLineCheck, 0, 2000);
					memset(eraseEdgeLine, 0, 2000 * 2);

					// 45도 상에서 실제로 보이는 에지 라인만 추출////////////
					startX1 = 1000;
					endX1 = -1;
					for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
					{
						if (SideAngle == MINUS_45_ANGLE_CAM)
						{
							tempX = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * CosData[SIDE_CAMERA_ANGLE * 2] + (sizeTransform[m][1] - HALF_IMAGE_WIDTH) * SinData[SIDE_CAMERA_ANGLE * 2]) / 1024 + HALF_IMAGE_WIDTH;
							tempY = (-(sizeTransform[m][0] - HALF_IMAGE_WIDTH) * SinData[SIDE_CAMERA_ANGLE * 2] + (sizeTransform[m][1] - HALF_IMAGE_WIDTH) * CosData[SIDE_CAMERA_ANGLE * 2]) / 1024 + HALF_IMAGE_WIDTH;
						}
						else if (SideAngle == ZERO_ANGLE_CAM)
						{
							tempX = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * CosData[0] - (sizeTransform[m][1] - HALF_IMAGE_WIDTH) * SinData[0]) / 1024 + HALF_IMAGE_WIDTH;
							tempY = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * SinData[0] + (sizeTransform[m][1] - HALF_IMAGE_WIDTH) * CosData[0]) / 1024 + HALF_IMAGE_WIDTH;
						}
						else if (SideAngle == PLUS_45_ANGLE_CAM)
						{
							tempX = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * CosData[SIDE_CAMERA_ANGLE * 2] - (sizeTransform[m][1] - HALF_IMAGE_WIDTH) * SinData[SIDE_CAMERA_ANGLE * 2]) / 1024 + HALF_IMAGE_WIDTH;
							tempY = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * SinData[SIDE_CAMERA_ANGLE * 2] + (sizeTransform[m][1] - HALF_IMAGE_WIDTH) * CosData[SIDE_CAMERA_ANGLE * 2]) / 1024 + HALF_IMAGE_WIDTH;
						}

						if (startX1 > tempX)
						{
							start_Number = m;
							startX1 = tempX;
							startY1 = tempY;
						}
						else if (startX1 == tempX)
						{
							if (startY1 > tempY)
							{
								start_Number = m;
								startX1 = tempX;
								startY1 = tempY;
							}
						}
						if (endX1 <= tempX)
						{
							end_Number = m;
							endX1 = tempX;
							endY1 = tempY;
						}
						else if (endX1 == tempX)
						{
							if (endY1 > tempY)
							{
								start_Number = m;
								endX1 = tempX;
								endY1 = tempY;
							}
						}

						if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_WIDTH)
						{
							RotationEdgeImage[tempY * MAX_IMAGE_WIDTH + tempX] = m;
						}
					}

					if (SideAngle == MINUS_45_ANGLE_CAM)
					{
						for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
						{
							if (sizeTransform[m][0] > shapeMaxX - 2 * ShapeWidth / 7)
							{
								eraseEdgeLine[m] = 1;
							}
						}
					}
					else if (SideAngle == PLUS_45_ANGLE_CAM)
					{
						for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
						{
							if (sizeTransform[m][0] < shapeMinX + 2 * ShapeWidth / 7)
							{
								eraseEdgeLine[m] = 1;
							}
						}
					}
					else
					{
						for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
						{
							if (sizeTransform[m][0] > shapeMaxX - ShapeWidth / 10)
							{
								eraseEdgeLine[m] = 1;
							}
						}
					}

					for (x = 1; x < MAX_IMAGE_WIDTH - 1; x++)
					{
						for (y = MAX_IMAGE_WIDTH - 1; y >= 1; y--)
						{
							if (RotationEdgeImage[y * 640 + x])
							{
								unVisibleEdgeLineCheck[RotationEdgeImage[y * MAX_IMAGE_WIDTH + x]] = 1;
								break;
							}
							if (RotationEdgeImage[y * 640 + x - 1])
							{
								unVisibleEdgeLineCheck[RotationEdgeImage[y * MAX_IMAGE_WIDTH + x - 1]] = 1;
								break;
							}
							if (RotationEdgeImage[y * 640 + x + 1])
							{
								unVisibleEdgeLineCheck[RotationEdgeImage[y * MAX_IMAGE_WIDTH + x + 1]] = 1;
								break;
							}
						}
					}

					tabletCenterX = 320;
					tabletCenterY = 240;
					tabletCenterZ = 360; // TabletSetupData.DiskBaseHeightPosition[cameraIndex - 1];

					face1Height = tabletCenterZ - adjustMiddleHeight;
					face2Height = tabletCenterZ;

					XAxisDataMakeCount = 0;
					for (tAngleX = -MAX_ANGLE1_RANGE; tAngleX <= MAX_ANGLE1_RANGE; tAngleX++)
					{
						YAxisDataMakeCount = 0;
						for (tAngleY = -MAX_ANGLE2_RANGE; tAngleY <= MAX_ANGLE2_RANGE; tAngleY++)
						{
							for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
							{
								firstTransformForFace1[m][0] = sizeTransform[m][0];
								firstTransformForFace1[m][1] = ((sizeTransform[m][1] - tabletCenterY) * CosData[AngleXZeroPos + tAngleX * 2] - (face1Height - tabletCenterZ) * SinData[AngleXZeroPos + tAngleX * 2]) / 1024 + tabletCenterY;
								firstTransformForFace1[m][2] = ((sizeTransform[m][1] - tabletCenterY) * SinData[AngleXZeroPos + tAngleX * 2] + (face1Height - tabletCenterZ) * CosData[AngleXZeroPos + tAngleX * 2]) / 1024 + tabletCenterZ;
							}

							for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
							{
								firstTransformForFace2[m][0] = sizeTransform[m][0];
								firstTransformForFace2[m][1] = ((sizeTransform[m][1] - tabletCenterY) * CosData[AngleXZeroPos + tAngleX * 2] - (face2Height - tabletCenterZ) * SinData[AngleXZeroPos + tAngleX * 2]) / 1024 + tabletCenterY;
								firstTransformForFace2[m][2] = ((sizeTransform[m][1] - tabletCenterY) * SinData[AngleXZeroPos + tAngleX * 2] + (face2Height - tabletCenterZ) * CosData[AngleXZeroPos + tAngleX * 2]) / 1024 + tabletCenterZ;
							}

							for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
							{
								SecondTransformForFace1[m][1] = firstTransformForFace1[m][1];
								if (tAngleY < 0)
								{
									SecondTransformForFace1[m][0] = ((firstTransformForFace1[m][0] - tabletCenterX) * CosData[-tAngleY * 2] + (firstTransformForFace1[m][2] - tabletCenterZ) * SinData[-tAngleY * 2]) / 1024 + tabletCenterX;
									SecondTransformForFace1[m][2] = (-(firstTransformForFace1[m][0] - tabletCenterX) * SinData[-tAngleY * 2] + (firstTransformForFace1[m][2] - tabletCenterZ) * CosData[-tAngleY * 2]) / 1024 + tabletCenterZ;
								}
								else
								{
									SecondTransformForFace1[m][0] = ((firstTransformForFace1[m][0] - tabletCenterX) * CosData[tAngleY * 2] - (firstTransformForFace1[m][2] - tabletCenterZ) * SinData[tAngleY * 2]) / 1024 + tabletCenterX;
									SecondTransformForFace1[m][2] = ((firstTransformForFace1[m][0] - tabletCenterX) * SinData[tAngleY * 2] + (firstTransformForFace1[m][2] - tabletCenterZ) * CosData[tAngleY * 2]) / 1024 + tabletCenterZ;
								}
							}

							for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
							{
								SecondTransformForFace2[m][1] = firstTransformForFace2[m][1];
								if (tAngleY < 0)
								{
									SecondTransformForFace2[m][0] = ((firstTransformForFace2[m][0] - tabletCenterX) * CosData[-tAngleY * 2] + (firstTransformForFace2[m][2] - tabletCenterZ) * SinData[-tAngleY * 2]) / 1024 + tabletCenterX;
									SecondTransformForFace2[m][2] = (-(firstTransformForFace2[m][0] - tabletCenterX) * SinData[-tAngleY * 2] + (firstTransformForFace2[m][2] - tabletCenterZ) * CosData[-tAngleY * 2]) / 1024 + tabletCenterZ;
								}
								else
								{
									SecondTransformForFace2[m][0] = ((firstTransformForFace2[m][0] - tabletCenterX) * CosData[tAngleY * 2] - (firstTransformForFace2[m][2] - tabletCenterZ) * SinData[tAngleY * 2]) / 1024 + tabletCenterX;
									SecondTransformForFace2[m][2] = ((firstTransformForFace2[m][0] - tabletCenterX) * SinData[tAngleY * 2] + (firstTransformForFace2[m][2] - tabletCenterZ) * CosData[tAngleY * 2]) / 1024 + tabletCenterZ;
								}
							}

							if (SideAngle == MINUS_45_ANGLE_CAM)
							{
								for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
								{
									transfarentEdgeDataPoint[m][0] = ((SecondTransformForFace1[m][0] - tabletCenterX) * CosData[SIDE_CAMERA_ANGLE * 2] + (SecondTransformForFace1[m][1] - tabletCenterY) * SinData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterX;
									transfarentEdgeDataPoint[m][1] = (-(SecondTransformForFace1[m][0] - tabletCenterX) * SinData[SIDE_CAMERA_ANGLE * 2] + (SecondTransformForFace1[m][1] - tabletCenterY) * CosData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterY;
									transfarentEdgeDataPoint[m][2] = SecondTransformForFace1[m][2];
								}
								for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
								{
									transfarentEdgeDataPoint2[m][0] = ((SecondTransformForFace2[m][0] - tabletCenterX) * CosData[SIDE_CAMERA_ANGLE * 2] + (SecondTransformForFace2[m][1] - tabletCenterY) * SinData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterX;
									transfarentEdgeDataPoint2[m][1] = (-(SecondTransformForFace2[m][0] - tabletCenterX) * SinData[SIDE_CAMERA_ANGLE * 2] + (SecondTransformForFace2[m][1] - tabletCenterY) * CosData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterY;
									transfarentEdgeDataPoint2[m][2] = SecondTransformForFace2[m][2];
								}
							}
							else if (SideAngle == ZERO_ANGLE_CAM)
							{
								for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
								{
									transfarentEdgeDataPoint[m][0] = ((SecondTransformForFace1[m][0] - tabletCenterX) * CosData[0] - (SecondTransformForFace1[m][1] - tabletCenterY) * SinData[0]) / 1024 + tabletCenterX;
									transfarentEdgeDataPoint[m][1] = ((SecondTransformForFace1[m][0] - tabletCenterX) * SinData[0] + (SecondTransformForFace1[m][1] - tabletCenterY) * CosData[0]) / 1024 + tabletCenterY;

									transfarentEdgeDataPoint[m][2] = SecondTransformForFace1[m][2];
								}
								for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
								{
									transfarentEdgeDataPoint2[m][0] = ((SecondTransformForFace2[m][0] - tabletCenterX) * CosData[0] - (SecondTransformForFace2[m][1] - tabletCenterY) * SinData[0]) / 1024 + tabletCenterX;
									transfarentEdgeDataPoint2[m][1] = ((SecondTransformForFace2[m][0] - tabletCenterX) * SinData[0] + (SecondTransformForFace2[m][1] - tabletCenterY) * CosData[0]) / 1024 + tabletCenterY;

									transfarentEdgeDataPoint2[m][2] = SecondTransformForFace2[m][2];
								}
							}
							else if (SideAngle == PLUS_45_ANGLE_CAM)
							{
								for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
								{
									transfarentEdgeDataPoint[m][0] = ((SecondTransformForFace1[m][0] - tabletCenterX) * CosData[SIDE_CAMERA_ANGLE * 2] - (SecondTransformForFace1[m][1] - tabletCenterY) * SinData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterX;
									transfarentEdgeDataPoint[m][1] = ((SecondTransformForFace1[m][0] - tabletCenterX) * SinData[SIDE_CAMERA_ANGLE * 2] + (SecondTransformForFace1[m][1] - tabletCenterY) * CosData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterY;
									transfarentEdgeDataPoint[m][2] = SecondTransformForFace1[m][2];
								}
								for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
								{
									transfarentEdgeDataPoint2[m][0] = ((SecondTransformForFace2[m][0] - tabletCenterX) * CosData[SIDE_CAMERA_ANGLE * 2] - (SecondTransformForFace2[m][1] - tabletCenterY) * SinData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterX;
									transfarentEdgeDataPoint2[m][1] = ((SecondTransformForFace2[m][0] - tabletCenterX) * SinData[SIDE_CAMERA_ANGLE * 2] + (SecondTransformForFace2[m][1] - tabletCenterY) * CosData[SIDE_CAMERA_ANGLE * 2]) / 1024 + tabletCenterY;
									transfarentEdgeDataPoint2[m][2] = SecondTransformForFace2[m][2];
								}
							}

							startX1 = transfarentEdgeDataPoint[start_Number][0];
							startY1 = transfarentEdgeDataPoint[start_Number][2];
							startX2 = transfarentEdgeDataPoint2[start_Number][0];
							startY2 = transfarentEdgeDataPoint2[start_Number][2];

							endX1 = transfarentEdgeDataPoint[end_Number][0];
							endY1 = transfarentEdgeDataPoint[end_Number][2];
							endX2 = transfarentEdgeDataPoint2[end_Number][0];
							endY2 = transfarentEdgeDataPoint2[end_Number][2];

							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startX1 = startX1;
							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startY1 = startY1;
							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startX2 = startX2;
							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startY2 = startY2;

							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endX1 = endX1;
							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endY1 = endY1;
							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endX2 = endX2;
							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endY2 = endY2;

							shapeEndY = 0;

							lineMinX = MAX_IMAGE_WIDTH;
							lineMaxX = 0;
							lineMinY = MAX_IMAGE_HEIGHT;
							lineMaxY = 0;
							for (m = 0; m < TabletSetupData.FrontShapeEdgePointCount; m++)
							{
								if (unVisibleEdgeLineCheck[m])
								{
									tempX = transfarentEdgeDataPoint2[m][0];
									tempY = transfarentEdgeDataPoint2[m][2];

									if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
									{
										if (!eraseEdgeLine[m])
										{
											if (SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountBottom < 480)
											{
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointBottom[SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountBottom * 2 + 0] = tempX;
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointBottom[SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountBottom * 2 + 1] = tempY;
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountBottom++;
											}
										}

										if (shapeEndY < transfarentEdgeDataPoint2[m][2])
											shapeEndY = transfarentEdgeDataPoint2[m][2];

										if (lineMinX > tempX)
											lineMinX = tempX;
										if (lineMaxX < tempX)
											lineMaxX = tempX;
										if (lineMinY > tempY)
											lineMinY = tempY;
										if (lineMaxY < tempY)
											lineMaxY = tempY;
									}
								}
							}

							SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].ShapeEndY = shapeEndY;

							if (SideAngle == PLUS_45_ANGLE_CAM)
							{
								lineMinX = MAX_IMAGE_WIDTH;
								lineMaxX = 0;
								lineMinY = MAX_IMAGE_HEIGHT;
								lineMaxY = 0;
								for (y = endY1; y <= endY2; y++)
								{
									if ((endY1 - endY2))
									{
										tempX = (endX1 - endX2) * (y - endY1) / (endY1 - endY2) + endX1;

										if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && y > 0 && y < MAX_IMAGE_HEIGHT)
										{
											tempImage[MAX_IMAGE_WIDTH * y + tempX] = 2;

											if (lineMinX > tempX)
												lineMinX = tempX;
											if (lineMaxX < tempX)
												lineMaxX = tempX;
											if (lineMinY > y)
												lineMinY = y;
											if (lineMaxY < y)
												lineMaxY = y;
										}
									}
								}

								for (y = lineMinY; y <= lineMaxY; y++)
								{
									for (x = lineMinX; x <= lineMaxX; x++)
									{
										if (tempImage[MAX_IMAGE_WIDTH * y + x] == 2)
										{
											if (SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountRight < MAX_TABLET_HEIGHT)
											{
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointRight[SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountRight * 2 + 0] = x;
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointRight[SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountRight * 2 + 1] = y;
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountRight++;
											}

											tempImage[MAX_IMAGE_WIDTH * y + x] = 0;
										}
									}
								}
							}
							else
							{
								lineMinX = MAX_IMAGE_WIDTH;
								lineMaxX = 0;
								lineMinY = MAX_IMAGE_HEIGHT;
								lineMaxY = 0;
								for (y = startY1; y <= startY2; y++)
								{
									if ((startY1 - startY2))
									{
										tempX = (startX1 - startX2) * (y - startY1) / (startY1 - startY2) + startX1;

										if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && y > 0 && y < MAX_IMAGE_HEIGHT)
										{
											tempImage[MAX_IMAGE_WIDTH * y + tempX] = 3;

											if (lineMinX > tempX)
												lineMinX = tempX;
											if (lineMaxX < tempX)
												lineMaxX = tempX;
											if (lineMinY > y)
												lineMinY = y;
											if (lineMaxY < y)
												lineMaxY = y;
										}
									}
								}

								for (y = lineMinY; y <= lineMaxY; y++)
								{
									for (x = lineMinX; x <= lineMaxX; x++)
									{
										if (tempImage[MAX_IMAGE_WIDTH * y + x] == 3)
										{
											if (SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountLeft < MAX_TABLET_HEIGHT)
											{
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointLeft[SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountLeft * 2 + 0] = x;
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointLeft[SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountLeft * 2 + 1] = y;
												SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountLeft++;
											}

											tempImage[MAX_IMAGE_WIDTH * y + x] = 0;
										}
									}
								}
							}

							if (SideAngle == PLUS_45_ANGLE_CAM)
							{
								width = abs(SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endX1 - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endX2);
								height = abs(SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endY1 - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endY2);
							}
							else
							{
								width = abs(SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startX1 - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startX2);
								height = abs(SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startY1 - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startY2);
							}
							SideWallLength = sqrt((double)width * width + (double)height * height);

							if (MAX_TABLET_HEIGHT < SideWallLength)
								SideWallLength = MAX_TABLET_HEIGHT;

							halfSideWallLength = SideWallLength * 2 / 5;

							shiftCount = 0;
							if (SideAngle == PLUS_45_ANGLE_CAM)
							{
								for (y = SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endY2 - SideWallLength; y <= SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endY2 - halfSideWallLength; y++)
								{
									tempX = 0;

									for (m = 0; m < SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountRight; m++)
									{
										if (y == SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointRight[m * 2 + 1])
										{
											tempX = SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointRight[m * 2 + 0];
											break;
										}
									}

									if (tempX)
									{
										SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].shiftTopLineX[shiftCount] = tempX - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endX2;
										SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].shiftTopLineY[shiftCount] = y - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].endY2;
										shiftCount++;
									}
								}
							}
							else
							{
								for (y = SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startY2 - SideWallLength; y <= SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startY2 - halfSideWallLength; y++)
								{
									tempX = 0;

									for (m = 0; m < SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointCountLeft; m++)
									{
										if (y == SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointLeft[m * 2 + 1])
										{
											tempX = SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].SideShapeEdgePointLeft[m * 2 + 0];
											break;
										}
									}

									if (tempX)
									{
										SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].shiftTopLineX[shiftCount] = tempX - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startX2;
										SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].shiftTopLineY[shiftCount] = y - SideShapeData[YAxisDataMakeCount][XAxisDataMakeCount].startY2;
										shiftCount++;
									}
								}
							}

							YAxisDataMakeCount++;
						}
						XAxisDataMakeCount++;
					}
				}
			}
		}
	}

	if (TabletCharacter.kind == SUGARCOATING)
	{
		memset(protoLineData, 0, sizeof(unsigned short) * SIDE_FACE_ROTATION_LINE_DATA_COUNT * 2);
		memset(RotationLineForCoatedTablet, 0, sizeof(unsigned short) * 180 * SIDE_FACE_ROTATION_LINE_DATA_COUNT * 2);
		RotationLineDataCount = 0;

		tabletLength = SIDE_FACE_ROTATION_LINE_DATA_COUNT;

		// 초기 데이터 생성
		tabletCenterX = 320;
		tabletCenterY = 240;
		startX1 = tabletCenterX - tabletLength / 2;

		RotationLineDataCount = tabletLength;
		for (m = 0; m < RotationLineDataCount; m++)
		{
			protoLineData[m * 2 + 0] = startX1 + m;
			protoLineData[m * 2 + 1] = tabletCenterY;
		}

		int r2;
		for (r = 0, r2 = 0; r < 360; r += 2, ++r2)
		{
			for (m = 0; m < RotationLineDataCount; m++)
			{
				tempX = ((CosData[r] * (protoLineData[m * 2 + 0] - tabletCenterX) - SinData[r] * (protoLineData[m * 2 + 1] - tabletCenterY)) / 1024) + tabletCenterX;
				tempY = ((SinData[r] * (protoLineData[m * 2 + 0] - tabletCenterX) + CosData[r] * (protoLineData[m * 2 + 1] - tabletCenterY)) / 1024) + tabletCenterY;

				tempY = ((tempY - tabletCenterY) * SinData[60]) / 1024 + 240;

				if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
				{
					RotationLineForCoatedTablet[r2][m * 2 + 0] = tempX;
					RotationLineForCoatedTablet[r2][m * 2 + 1] = tempY;
				}
			}
		}
	}

	if (TabletCharacter.middle_height != 0)
	{
		memset(SideWallMatchingData.SideWallData, 0, sizeof(TSideWallData) * (MAX_SIDE_WALL_ROT_RANGE * 2 + 1));
		memset(sizeTransform, 0, sizeof(unsigned short) * 2000 * 2);

		tempSideWallDataCount = 0;
		for (y = HALF_IMAGE_HEIGHT - 170; y <= HALF_IMAGE_HEIGHT + 170; y++)
		{
			sizeTransform[tempSideWallDataCount][0] = HALF_IMAGE_WIDTH;
			sizeTransform[tempSideWallDataCount][1] = y;
			tempSideWallDataCount++;
		}

		for (tAngleX = -MAX_SIDE_WALL_ROT_RANGE; tAngleX <= MAX_SIDE_WALL_ROT_RANGE; tAngleX++)
		{
			tempCount = 0;
			for (m = 0; m < tempSideWallDataCount; m++)
			{
				if (tAngleX < 0)
				{
					tempX = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * CosData[-tAngleX * 2] + (sizeTransform[m][1] - HALF_IMAGE_HEIGHT) * SinData[-tAngleX * 2]) / 1024 + HALF_IMAGE_WIDTH;
					tempY = (-(sizeTransform[m][0] - HALF_IMAGE_WIDTH) * SinData[-tAngleX * 2] + (sizeTransform[m][1] - HALF_IMAGE_HEIGHT) * CosData[-tAngleX * 2]) / 1024 + HALF_IMAGE_HEIGHT;
				}
				else
				{
					tempX = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * CosData[tAngleX * 2] - (sizeTransform[m][1] - HALF_IMAGE_HEIGHT) * SinData[tAngleX * 2]) / 1024 + HALF_IMAGE_WIDTH;
					tempY = ((sizeTransform[m][0] - HALF_IMAGE_WIDTH) * SinData[tAngleX * 2] + (sizeTransform[m][1] - HALF_IMAGE_HEIGHT) * CosData[tAngleX * 2]) / 1024 + HALF_IMAGE_HEIGHT;
				}

				if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
				{
					if (tempCount < 360)
					{
						SideWallMatchingData.SideWallData[tAngleX + MAX_SIDE_WALL_ROT_RANGE].SideWallPxData[tempCount * 2 + 0] = tempX;
						SideWallMatchingData.SideWallData[tAngleX + MAX_SIDE_WALL_ROT_RANGE].SideWallPxData[tempCount * 2 + 1] = tempY;
						tempCount++;
					}
				}
			}

			SideWallMatchingData.SideWallData[tAngleX + MAX_SIDE_WALL_ROT_RANGE].SideWallPxDataCount = tempCount;
		}
	}

	// (측면) 분할선 정보
	memset(protoLineData, 0, sizeof(unsigned short) * SIDE_FACE_ROTATION_LINE_DATA_COUNT * 2);
	memset(SideFaceDivisionLineData, 0, sizeof(unsigned short) * 180 * SIDE_FACE_DIVISION_LINE_DATA_COUNT * 2);
	SideFaceDivisionLineDataCount = 0;

	avgResolution = tempCount = 0;
	for (cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		if (cameraIndex == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX ||
			cameraIndex == SD2_2D_SIDE_FACE_M45_CAMERA_INDEX ||
			cameraIndex == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX ||
			cameraIndex == SD2_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX ||
			cameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX ||
			cameraIndex == SD2_2D_SIDE_FACE_00_CAMERA_INDEX ||
			cameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX ||
			cameraIndex == SD2_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX ||
			cameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX ||
			cameraIndex == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX ||
			cameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX ||
			cameraIndex == SD2_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX)
		{
			avgResolution += TabletSetupData.cameraZoom[cameraIndex - 1];
			tempCount++;
		}
	}

	if (tempCount)
	{
		avgResolution /= tempCount;
	}
	else
	{
		avgResolution = 430;
	}

	FrontFaceCameraResolution = TabletSetupData.cameraZoom[0];
	SideFaceCameraResolution = avgResolution;

	tabletLength = TabletCharacter.length * FrontFaceCameraResolution / SideFaceCameraResolution;
	tabletLength = tabletLength * 150 / 100;

	if (tabletLength > SIDE_FACE_DIVISION_LINE_DATA_COUNT)
	{
		tabletLength = SIDE_FACE_DIVISION_LINE_DATA_COUNT;
	}

	// 초기 데이터 생성
	tabletCenterX = 320;
	tabletCenterY = 240;
	startX1 = tabletCenterX - tabletLength / 2;

	SideFaceDivisionLineDataCount = tabletLength;
	for (m = 0; m < SideFaceDivisionLineDataCount; m++)
	{
		protoLineData[m * 2 + 0] = startX1 + m;
		protoLineData[m * 2 + 1] = tabletCenterY;
	}

	int r2;
	for (r = 0, r2 = 0; r < 360; r += 2, ++r2)
	{
		for (m = 0; m < SideFaceDivisionLineDataCount; m++)
		{
			tempX = ((CosData[r] * (protoLineData[m * 2 + 0] - tabletCenterX) - SinData[r] * (protoLineData[m * 2 + 1] - tabletCenterY)) / 1024) + tabletCenterX;
			tempY = ((SinData[r] * (protoLineData[m * 2 + 0] - tabletCenterX) + CosData[r] * (protoLineData[m * 2 + 1] - tabletCenterY)) / 1024) + tabletCenterY;

			tempY = ((tempY - tabletCenterY) * SinData[60]) / 1024 + 240;

			if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
			{
				SideFaceDivisionLineData[r2][m * 2 + 0] = tempX;
				SideFaceDivisionLineData[r2][m * 2 + 1] = tempY;
			}
		}
	}
}
//---------------------------------------------------------------------------
#ifndef TARGET_CPB
void SideFaceSetUpDataTransForm_For_PCSIM(TSideData *RESTRICT(FullSizeSideData))
{
	SideFaceSetUpDataTransForm(-1, FullSizeSideData);
}
//---------------------------------------------------------------------------
void SetSideFaceDataAddress(TSideData *RESTRICT(FullSizeSideData))
{
	SideData = FullSizeSideData;
}
#endif
//---------------------------------------------------------------------------
void SideFaceColorCheck(int cameraIndex)
{
	int startX, endX, startY, endY;
	int tempAddress;
	int areaValue;
	int accBColor, accGColor, accRColor;
	int tempCount;
	int x, y;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	accBColor = accGColor = accRColor = tempCount = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			areaValue = InspectionArea[tempAddress];

			if (areaValue == NORMAL_INPECTION_AREA)
			{
				accBColor += ColorSourceImage[tempAddress * 3 + 0];
				accGColor += ColorSourceImage[tempAddress * 3 + 1];
				accRColor += ColorSourceImage[tempAddress * 3 + 2];

				tempCount++;
			}
		}
	}

	TabletStudyData.SideFaceTabletBColor[cameraIndex - 1] = -1;
	TabletStudyData.SideFaceTabletGColor[cameraIndex - 1] = -1;
	TabletStudyData.SideFaceTabletRColor[cameraIndex - 1] = -1;

	if (DefectSW == 0)
	{
		if (tempCount)
		{
			accBColor /= tempCount;
			accGColor /= tempCount;
			accRColor /= tempCount;

			TabletStudyData.SideFaceTabletBColor[cameraIndex - 1] = accBColor;
			TabletStudyData.SideFaceTabletGColor[cameraIndex - 1] = accGColor;
			TabletStudyData.SideFaceTabletRColor[cameraIndex - 1] = accRColor;
		}
	}
}
//---------------------------------------------------------------------------
int SideFaceSplitLineMask(int cameraIndex)
{
	int x, y;
	int tempAddress;
	int startX, startY, endX, endY;
	int madeEdgeLine[MAX_IMAGE_WIDTH];
	int shapeLeftEdgeX;
	int shapeRightEdgeX;
	int shapeLeftEdgeY;
	int shapeRightEdgeY;
	int m;
	int tempX, tempY;
	int i, j;
	int SideAngle;
	int shapeCenterX, shapeCenterY;
	int gradCenterX, gradCenterY;
	int tempCount;
	int r;
	int topSW, bottomSW, leftSW, rightSW;
	int topleftSW, toprightSW, bottomleftSW, bottomrightSW;
	int tempAddress2;
	int selfBValue, selfGValue, selfRValue;
	int colorBDiff, colorGDiff, colorRDiff;
	int maxColorDiff1;
	int maxColorDiff2;
	int minThreshold;
	int colorDiffSum;
	int shiftX, shiftY;
	int maxGradValue;
	int gradSum;
	int splitLineRotationAngle;
	int matchingX, matchingY;
	int tempSplitLineRotationAngle;
	int tempMatchingX, tempMatchingY;
	int colorDiff;
	int avgGradVal;
	int StartSW;
	int dataMatchingCount;
	int dataCount;
	int groupN;
	int maxSizeLabelN[3];
	int GradSW;
	int stAngle, edAngle;
	int remakeInspectionAreaSW;

	short *label_Image;
	unsigned char *sideFaceInterestedBinArea;

	remakeInspectionAreaSW = 0;

	if (cameraIndex == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX ||
		cameraIndex == SD2_2D_SIDE_FACE_M45_CAMERA_INDEX ||
		cameraIndex == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX ||
		cameraIndex == SD2_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX)
	{
		SideAngle = MINUS_45_ANGLE_CAM;
	}
	else if (cameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_SIDE_FACE_00_CAMERA_INDEX ||
			 cameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX)
	{
		SideAngle = ZERO_ANGLE_CAM;
	}
	else if (cameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX ||
			 cameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX)
	{
		SideAngle = PLUS_45_ANGLE_CAM;
	}

	label_Image = LabelImage_Virtual;
	sideFaceInterestedBinArea = TempImage3;
	memset(sideFaceInterestedBinArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(madeEdgeLine, 0, sizeof(int) * MAX_IMAGE_WIDTH);

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	// bin 축소
	memcpy(TempImage, ShapeBinaryImage, 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 (ShapeBinaryImage[tempAddress])
			{
				if (ShapeBinaryImage[tempAddress - 10] == 0)
					TempImage[tempAddress] = 0;
				else if (ShapeBinaryImage[tempAddress + 10] == 0)
					TempImage[tempAddress] = 0;
				else if (ShapeBinaryImage[tempAddress - 10 * MAX_IMAGE_WIDTH] == 0)
					TempImage[tempAddress] = 0;
				else if (ShapeBinaryImage[tempAddress + 10 * MAX_IMAGE_WIDTH] == 0)
					TempImage[tempAddress] = 0;
			}
		}
	}

	shapeLeftEdgeX = MAX_IMAGE_WIDTH;
	shapeRightEdgeX = 0;

	if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
	{
		for (m = 0; m < finalMatchingShapeData.SideShapeEdgePointCountBottom; m++)
		{
			tempX = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2] + TabletMatchingResult.TabletSideShapeShiftX + TabletMatchingResult.TabletSideShapeTopLineShiftX;
			tempY = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2 + 1] + TabletMatchingResult.TabletSideShapeShiftY + TabletMatchingResult.TabletSideShapeTopLineShiftY + tempShiftTopLine[m];

			if (tempX > 0 && tempX < MAX_IMAGE_WIDTH)
			{
				if (shapeLeftEdgeX > tempX)
				{
					shapeLeftEdgeX = tempX;
					shapeLeftEdgeY = tempY - 4;
				}
				if (shapeRightEdgeX < tempX)
				{
					shapeRightEdgeX = tempX;
					shapeRightEdgeY = tempY - 4;
				}
			}

			for (i = tempX - 4; i <= tempX + 4; i++)
			{
				if (i > 0 && i < MAX_IMAGE_WIDTH)
				{
					madeEdgeLine[i] = tempY - 4;
				}
			}
		}
	}
	else
	{
		for (m = 0; m < TabletETCMatchingResult.tabletShapeTopLineCount; m++)
		{
			tempX = TabletETCMatchingResult.tabletShapeTopLine[m * 2 + 0];
			tempY = TabletETCMatchingResult.tabletShapeTopLine[m * 2 + 1];

			if (tempX > 0 && tempX < MAX_IMAGE_WIDTH)
			{
				if (shapeLeftEdgeX > tempX)
				{
					shapeLeftEdgeX = tempX;
					shapeLeftEdgeY = tempY - 4;
				}
				if (shapeRightEdgeX < tempX)
				{
					shapeRightEdgeX = tempX;
					shapeRightEdgeY = tempY - 4;
				}
			}

			for (i = tempX - 4; i <= tempX + 4; i++)
			{
				if (i > 0 && i < MAX_IMAGE_WIDTH)
				{
					madeEdgeLine[i] = tempY - 4;
				}
			}
		}
	}

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			if (madeEdgeLine[x])
			{
				tempY = madeEdgeLine[x];

				if (y < tempY)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					if (TempImage[tempAddress])
					{
						sideFaceInterestedBinArea[tempAddress] = 1;
					}
				}
			}
		}
	}

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			if (SideAngle == PLUS_45_ANGLE_CAM)
			{
				if (x > shapeRightEdgeX)
					continue;
			}
			else
			{
				if (x < shapeLeftEdgeX)
					continue;
			}

			if (madeEdgeLine[x])
				continue;

			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (TempImage[tempAddress] && !sideFaceInterestedBinArea[tempAddress])
			{
				if (SideAngle == PLUS_45_ANGLE_CAM)
				{
					if (y < shapeLeftEdgeY)
					{
						sideFaceInterestedBinArea[tempAddress] = 1;
					}
				}
				else
				{
					if (y < shapeRightEdgeY)
					{
						sideFaceInterestedBinArea[tempAddress] = 1;
					}
				}
			}
		}
	}

	shapeCenterX = shapeCenterY = tempCount = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			if (sideFaceInterestedBinArea[tempAddress])
			{
				shapeCenterX += x;
				shapeCenterY += y;
				tempCount++;
			}
		}
	}

	if (tempCount)
	{
		shapeCenterX /= tempCount;
		shapeCenterY /= tempCount;
	}
	else
	{
		// 마스킹 영역을 생성하지 않음
		return remakeInspectionAreaSW;
	}

	minThreshold = SIDE_EDGE_DARK_THRESH;
	memset(GradientImage, 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 (sideFaceInterestedBinArea[tempAddress])
			{
				topSW = bottomSW = leftSW = rightSW = 0;
				topleftSW = toprightSW = bottomleftSW = bottomrightSW = 0;
				colorDiffSum = 0;
				GradSW = 0;

				selfBValue = ColorSourceImage[tempAddress * 3 + 0];
				selfGValue = ColorSourceImage[tempAddress * 3 + 1];
				selfRValue = ColorSourceImage[tempAddress * 3 + 2];

				maxColorDiff1 = 0;
				for (r = 10; r >= 2; r -= 2)
				{
					// left
					tempAddress2 = tempAddress - r;

					if (sideFaceInterestedBinArea[tempAddress2])
					{
						colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
						colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
						colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

						colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

						if (colorDiff > minThreshold)
						{
							maxColorDiff1 += colorDiff;

							leftSW = 1;
						}
					}
				}

				if (leftSW)
				{
					maxColorDiff2 = 0;
					for (r = 10; r >= 2; r -= 2)
					{
						// right
						tempAddress2 = tempAddress + r;

						if (sideFaceInterestedBinArea[tempAddress2])
						{
							colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
							colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
							colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

							colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

							if (colorDiff > minThreshold)
							{
								maxColorDiff2 += colorDiff;

								rightSW = 1;
							}
						}
					}
				}

				if (leftSW && rightSW)
				{
					colorDiffSum += (maxColorDiff1 + maxColorDiff2) / 8;
					GradSW++;
				}

				maxColorDiff1 = 0;
				for (r = 10; r >= 2; r -= 2)
				{
					// top
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;

					if (sideFaceInterestedBinArea[tempAddress2])
					{
						colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
						colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
						colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

						colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

						if (colorDiff > minThreshold)
						{
							maxColorDiff1 += colorDiff;

							topSW = 1;
						}
					}
				}

				if (topSW)
				{
					maxColorDiff2 = 0;
					for (r = 10; r >= 2; r -= 2)
					{
						// bottom
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;

						if (sideFaceInterestedBinArea[tempAddress2])
						{
							colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
							colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
							colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

							colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

							if (colorDiff > minThreshold)
							{
								maxColorDiff2 += colorDiff;

								bottomSW = 1;
							}
						}
					}
				}

				if (topSW && bottomSW)
				{
					colorDiffSum += (maxColorDiff1 + maxColorDiff2) / 8;
					GradSW++;
				}

				maxColorDiff1 = 0;
				for (r = 10; r >= 2; r -= 2)
				{
					// top left
					tempAddress2 = tempAddress - r - r * MAX_IMAGE_WIDTH;

					if (sideFaceInterestedBinArea[tempAddress2])
					{
						colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
						colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
						colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

						colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

						if (colorDiff > minThreshold)
						{
							maxColorDiff1 += colorDiff;

							topleftSW = 1;
						}
					}
				}

				if (topleftSW)
				{
					maxColorDiff2 = 0;
					for (r = 10; r >= 2; r -= 2)
					{
						// bottom right
						tempAddress2 = tempAddress + r + r * MAX_IMAGE_WIDTH;

						if (sideFaceInterestedBinArea[tempAddress2])
						{
							colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
							colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
							colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

							colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

							if (colorDiff > minThreshold)
							{
								maxColorDiff2 += colorDiff;

								bottomrightSW = 1;
							}
						}
					}
				}

				if (topleftSW && bottomrightSW)
				{
					colorDiffSum += (maxColorDiff1 + maxColorDiff2) / 8;
					GradSW++;
				}

				maxColorDiff1 = 0;
				for (r = 10; r >= 2; r -= 2)
				{
					// top right
					tempAddress2 = tempAddress + r - r * MAX_IMAGE_WIDTH;

					if (sideFaceInterestedBinArea[tempAddress2])
					{
						colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
						colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
						colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

						colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

						if (colorDiff > minThreshold)
						{
							maxColorDiff1 += colorDiff;

							toprightSW = 1;
						}
					}
				}

				if (toprightSW)
				{
					maxColorDiff2 = 0;
					for (r = 10; r >= 2; r -= 2)
					{
						// bottom left
						tempAddress2 = tempAddress - r + r * MAX_IMAGE_WIDTH;

						if (sideFaceInterestedBinArea[tempAddress2])
						{
							colorBDiff = ColorSourceImage[tempAddress2 * 3 + 0] - selfBValue;
							colorGDiff = ColorSourceImage[tempAddress2 * 3 + 1] - selfGValue;
							colorRDiff = ColorSourceImage[tempAddress2 * 3 + 2] - selfRValue;

							colorDiff = max(colorBDiff, max(colorGDiff, colorRDiff));

							if (colorDiff > minThreshold)
							{
								maxColorDiff2 += colorDiff;

								bottomleftSW = 1;
							}
						}
					}
				}

				if (toprightSW && bottomleftSW)
				{
					colorDiffSum += (maxColorDiff1 + maxColorDiff2) / 8;
					GradSW++;
				}

				if (GradSW >= 2 && colorDiffSum > 20) // 노이즈성 데이터 제거
					GradientImage[tempAddress] = min(255, colorDiffSum);
			}
		}
	}

	memset(label_Image, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	groupN = SmallSizePixelLabeling(GradientImage, label_Image, startX, endX, startY, endY, MAX_IMAGE_WIDTH);

	maxSizeLabelN[0] = -1;
	tempCount = 0;
	for (m = 0; m < groupN; m++)
	{
		if (labelingPxCount[m] > tempCount)
		{
			tempCount = labelingPxCount[m];
			maxSizeLabelN[0] = m;
		}
	}

	maxSizeLabelN[1] = -1;
	tempCount = 0;
	for (m = 0; m < groupN; m++)
	{
		if (m != maxSizeLabelN[0])
		{
			if (labelingPxCount[m] > tempCount)
			{
				tempCount = labelingPxCount[m];
				maxSizeLabelN[1] = m;
			}
		}
	}

	maxSizeLabelN[2] = -1;
	tempCount = 0;
	for (m = 0; m < groupN; m++)
	{
		if (m != maxSizeLabelN[0] && m != maxSizeLabelN[1])
		{
			if (labelingPxCount[m] > tempCount)
			{
				tempCount = labelingPxCount[m];
				maxSizeLabelN[2] = m;
			}
		}
	}

	gradCenterX = gradCenterY = tempCount = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			if (label_Image[tempAddress] != maxSizeLabelN[0] &&
				label_Image[tempAddress] != maxSizeLabelN[1] &&
				label_Image[tempAddress] != maxSizeLabelN[2])
			{
				GradientImage[tempAddress] = 0;
			}
			else
			{
				gradCenterX += x;
				gradCenterY += y;
				tempCount++;
			}
		}
	}

	if (tempCount)
	{
		gradCenterX /= tempCount;
		gradCenterY /= tempCount;
	}
	else
	{
		gradCenterX = shapeCenterX;
		gradCenterY = shapeCenterY;
	}

	shiftX = HALF_IMAGE_WIDTH - gradCenterX;
	shiftY = HALF_IMAGE_HEIGHT - gradCenterY;

	minThreshold = 20;

	maxGradValue = 0;

	if (TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
	{
		stAngle = 90 - 45;
		edAngle = 90 + 45;
	}
	else
	{
		stAngle = 0;
		edAngle = 180;
	}

	if (TabletCharacter.tabletDivisionLineInfo == ONESIDE_DIVISION_LINE)
	{
		for (r = stAngle; r < edAngle; r += 4)
		{
			for (i = -8; i <= 8; i += 4)
			{
				for (j = -32; j <= 32; j += 4)
				{
					gradSum = tempCount = 0;
					StartSW = 0;
					dataCount = dataMatchingCount = 0;

					for (m = 0; m < SideFaceDivisionLineDataCount; m++)
					{
						tempX = SideFaceDivisionLineData[r][m * 2 + 0] - shiftX + j;
						tempY = SideFaceDivisionLineData[r][m * 2 + 1] - shiftY + i;

						if (tempX > startX && tempX < endX && tempY > startY && tempY < endY)
						{
							tempAddress = MAX_IMAGE_WIDTH * tempY + tempX;

							if (sideFaceInterestedBinArea[tempAddress])
							{
								gradSum += GradientImage[tempAddress];
								tempCount++;
							}

							if (!StartSW && sideFaceInterestedBinArea[tempAddress])
							{
								StartSW = 1;
							}
							else if (StartSW && !sideFaceInterestedBinArea[tempAddress])
							{
								break;
							}

							if (StartSW)
							{
								dataCount++;

								if (GradientImage[tempAddress] > minThreshold)
								{
									dataMatchingCount++;
								}
							}
						}
					}

					if (tempCount)
					{
						avgGradVal = gradSum / tempCount;

						if (avgGradVal > minThreshold)
						{
							// matching 결과에 따른 데이터의 연속성에 대한 검증
							if (dataMatchingCount > dataCount * 70 / 100)
							{
								if (maxGradValue < gradSum)
								{
									maxGradValue = gradSum;
									matchingX = j;
									matchingY = i;
									splitLineRotationAngle = r;
								}
							}
						}
					}
				}
			}
		}
	}
	else
	{
		for (r = stAngle; r < edAngle; r += 4)
		{
			for (i = -8; i <= 8; i += 4)
			{
				for (j = -32; j <= 32; j += 4)
				{
					gradSum = tempCount = 0;
					StartSW = 0;
					dataCount = dataMatchingCount = 0;

					for (m = 0; m < SideFaceDivisionLineDataCount; m++)
					{
						tempX = SideFaceDivisionLineData[r][m * 2 + 0] - shiftX + j;
						tempY = SideFaceDivisionLineData[r][m * 2 + 1] - shiftY + i;

						if (tempX > startX && tempX < endX && tempY > startY && tempY < endY)
						{
							tempAddress = MAX_IMAGE_WIDTH * tempY + tempX;

							if (sideFaceInterestedBinArea[tempAddress])
							{
								gradSum += GradientImage[tempAddress];
								tempCount++;
							}
						}
					}

					if (tempCount)
					{
						avgGradVal = gradSum / tempCount;

						if (avgGradVal > minThreshold)
						{
							if (maxGradValue < gradSum)
							{
								maxGradValue = gradSum;
								matchingX = j;
								matchingY = i;
								splitLineRotationAngle = r;
							}
						}
					}
				}
			}
		}
	}

	if (maxGradValue)
	{
		tempSplitLineRotationAngle = splitLineRotationAngle;
		tempMatchingX = matchingX;
		tempMatchingY = matchingY;

		maxGradValue = 0;
		for (r = tempSplitLineRotationAngle - 8; r < tempSplitLineRotationAngle + 8; r += 2)
		{
			if (r < 0 || r >= 180)
				continue;

			for (i = tempMatchingY - 4; i <= tempMatchingY + 4; i += 2)
			{
				for (j = tempMatchingX - 4; j <= tempMatchingX + 4; j += 2)
				{
					gradSum = 0;
					for (m = 0; m < SideFaceDivisionLineDataCount; m += 2)
					{
						tempX = SideFaceDivisionLineData[r][m * 2 + 0] - shiftX + j;
						tempY = SideFaceDivisionLineData[r][m * 2 + 1] - shiftY + i;

						if (tempX > startX && tempX < endX && tempY > startY && tempY < endY)
						{
							tempAddress = MAX_IMAGE_WIDTH * tempY + tempX;

							if (GradientImage[tempAddress] > minThreshold)
							{
								gradSum += GradientImage[tempAddress];
								gradSum += GradientImage[tempAddress - 2];
								gradSum += GradientImage[tempAddress + 2];
								gradSum += GradientImage[tempAddress - 2 * MAX_IMAGE_WIDTH];
								gradSum += GradientImage[tempAddress + 2 * MAX_IMAGE_WIDTH];

								gradSum += GradientImage[tempAddress - 4];
								gradSum += GradientImage[tempAddress + 4];
								gradSum += GradientImage[tempAddress - 4 * MAX_IMAGE_WIDTH];
								gradSum += GradientImage[tempAddress + 4 * MAX_IMAGE_WIDTH];
							}
						}
					}

					if (maxGradValue < gradSum)
					{
						maxGradValue = gradSum;
						matchingX = j;
						matchingY = i;
						splitLineRotationAngle = r;
					}
				}
			}
		}

		for (m = 0; m < SideFaceDivisionLineDataCount; m++)
		{
			tempX = SideFaceDivisionLineData[splitLineRotationAngle][m * 2 + 0] - shiftX + matchingX;
			tempY = SideFaceDivisionLineData[splitLineRotationAngle][m * 2 + 1] - shiftY + matchingY;

			for (i = tempY - 4; i <= tempY + 4; i++)
			{
				for (j = tempX - 10; j <= tempX + 10; j++)
				{
					if (j > startX && j < endX && i > startY && i < endY)
					{
						tempAddress = MAX_IMAGE_WIDTH * i + j;

						if (TempImage[tempAddress])
						{
							if (InspectionArea[tempAddress] == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA ||
								InspectionArea[tempAddress] == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
							{
								InspectionArea[tempAddress] = SIDE_SHAPE_UNINSPECTION_AREA;
								remakeInspectionAreaSW = 1;
							}
						}
					}
				}
			}
		}
	}

	return remakeInspectionAreaSW;
}
//---------------------------------------------------------------------------
void SideFaceShapeMatching(int option, int cameraIndex)
{
	if (option == SIDE_FACE_M45)
	{
		if (TabletCharacter.kind == UNCOATING || TabletCharacter.kind == FILMCOATING)
		{
			SideFaceShapeMatchingForEachCase(CASE1, cameraIndex);
		}
		else
		{
			SideFaceShapeMatchingForSugarCoating(cameraIndex);
		}
	}
	else if (option == SIDE_FACE_0)
	{
		if (TabletCharacter.kind == UNCOATING || TabletCharacter.kind == FILMCOATING)
		{
			SideFaceShapeMatchingForEachCase(CASE1, cameraIndex);
		}
		else
		{
			SideFaceShapeMatchingForSugarCoating(cameraIndex);
		}
	}
	else if (option == SIDE_FACE_P45)
	{
		if (TabletCharacter.kind == UNCOATING || TabletCharacter.kind == FILMCOATING)
		{
			SideFaceShapeMatchingForEachCase(CASE2, cameraIndex);
		}
		else
		{
			SideFaceShapeMatchingForSugarCoating(cameraIndex);
		}
	}
}
//---------------------------------------------------------------------------
void GetTabletSideShapeInformation(int cameraIndex)
{
	int x, y;
	int startX, endX, startY, endY;
	int tempAddress, tempAddress2;
	int threshold;
	int tempX, tempY;
	int avgValue;
	int tempCount;
	int imageAreaStartX, imageAreaStartY, imageAreaEndX, imageAreaEndY;
	int maxGradX, maxGradY;
	int side, left, right, top, bottom;
	int shapeGroupN;
	short *label_Image;
	int tMax;
	int maxPixelLabelN;
	int m;
	int deltaThreshold;
	unsigned char smallSizeGradientImage[(HALF_IMAGE_WIDTH) * (HALF_IMAGE_HEIGHT)];
	int halfWidth;
	int sideWallMatchingStRange;
	int sideWallMatchingEdRange;
	int shapeCenterX, shapeCenterY;
	int shapeMinX, shapeMaxX, shapeMinY, shapeMaxY;
	int sideWallAngle;
	int leftShiftCenterX, rightShiftCenterX, shiftCenterY;
	int wallShiftX;
	int continuousLength;
	int currentMaxLength;
	int gradValue;
	int maxGradValueforMaxLength;
	int i, j;
	int maxLeftMatchingValue;
	int maxRightMatchingValue;
	int maxMatchingValue;
	int matchingLeftShiftX;
	int matchingRightShiftX;
	unsigned char *sideGradientImage;
	unsigned char *tabletTopBottomEdgeInfo;
	int leftWeight;
	int rightWeight;
	int disContinuousSW;
	int leftSideTopPos[2];
	int leftSideBottomPos[2];
	int rightSideTopPos[2];
	int rightSideBottomPos[2];
	int leftLength, rightLength;
	int xDiff, yDiff;
	int tempX2, tempY2;
	int SideAngle;
	int interestedPxCount;
	int halfStartX, halfEndX, halfStartY, halfEndY;
	int maxColor;
	int eraseInterestedPixelCount;
	int tabletTopBottomThreshold;
	int leftNotInterestedAreaCount;
	int leftInterestedAreaCount;
	int rightNotInterestedAreaCount;
	int rightInterestedAreaCount;
	int matchingLeftNotInterestedAreaCount;
	int matchingLeftInterestedAreaCount;
	int matchingRightNotInterestedAreaCount;
	int matchingRightInterestedAreaCount;
	int addStep;
	int maskSize;
	int matchingLeftTopWallInfo[2];
	int matchingLeftBottomWallInfo[2];
	int matchingRightTopWallInfo[2];
	int matchingRightBottomWallInfo[2];
	int matchingSW;
	int shapeEdge1[2];
	int shapeEdge2[2];
	short tempShapeBottomLine[MAX_IMAGE_WIDTH][2];
	int tempShapeBottomLineCount;
	int minX, minY;
	int binSW;
	int writeStartY;
	int stPoint, endPoint;
	int tempStPoint;
	int maxX;
	int allRoundSymmetryTabletSW;
	int allFactorValue[3];
	int retrySW;
	int colorDiff;
	int selfValue;
	int r;
	int maxValuePos;
	int weight;
	int leftShiftXForLeftMatching;
	int rightShiftXForLeftMatching;
	int leftShiftXForRightMatching;
	int rightShiftXForRightMatching;
	int getThresholdSW;
	int lowerHeightTabletSW;
	int tabletThreshold;
	int pX, pY;
	int uLength;
	int sinV;
	int angle;
	int shapeCenter[2];
	int constCosV, constSinV;
	int rotateX, rotateY;
	int rStartX, rEndX, rStartY, rEndY;
	int maxValue;
	int tempAngle;
	int AssignPos[MAX_IMAGE_WIDTH];
	int labelCount;
	int maxLabelN;
	int BottomLineInfo[360][3];
	int AvgBottomLineInfo[360][3];
	int n;
	int minAngle, maxAngle;
	int startAngle, endAngle;

	// 임시 버퍼
	unsigned char *tempRotateGradientImg;

	deltaThreshold = 8;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	startX = imageAreaStartX = TabletSetupData.ImageCutStartX[cameraIndex - 1];
	startY = imageAreaStartY = TabletSetupData.ImageCutStartY[cameraIndex - 1];
	endX = imageAreaEndX = TabletSetupData.ImageCutEndX[cameraIndex - 1];
	endY = imageAreaEndY = TabletSetupData.ImageCutEndY[cameraIndex - 1];

	sideGradientImage = TempImage2;
	tabletTopBottomEdgeInfo = TempImage3;
	memset(sideGradientImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(tabletTopBottomEdgeInfo, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(GradientImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(&TabletETCMatchingResult, 0, sizeof(TTabletETCMatchingResult));

	if (cameraIndex == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX ||
		cameraIndex == SD2_2D_SIDE_FACE_M45_CAMERA_INDEX ||
		cameraIndex == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX ||
		cameraIndex == SD2_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX)
	{
		sideWallMatchingStRange = MAX_SIDE_WALL_ROT_RANGE;
		sideWallMatchingEdRange = MAX_SIDE_WALL_ROT_RANGE + 30;

		leftWeight = 2;
		rightWeight = 1;

		SideAngle = MINUS_45_ANGLE_CAM;
	}
	else if (cameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_SIDE_FACE_00_CAMERA_INDEX ||
			 cameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX)
	{
		sideWallMatchingStRange = MAX_SIDE_WALL_ROT_RANGE - 15;
		sideWallMatchingEdRange = MAX_SIDE_WALL_ROT_RANGE + 15;

		leftWeight = 1;
		rightWeight = 1;

		SideAngle = ZERO_ANGLE_CAM;
	}
	else if (cameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX ||
			 cameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX ||
			 cameraIndex == SD2_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX)
	{
		sideWallMatchingStRange = MAX_SIDE_WALL_ROT_RANGE - 30;
		sideWallMatchingEdRange = MAX_SIDE_WALL_ROT_RANGE;

		leftWeight = 1;
		rightWeight = 2;

		SideAngle = PLUS_45_ANGLE_CAM;
	}

	allRoundSymmetryTabletSW = 1;
	if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
	{
		allRoundSymmetryTabletSW = 0;
	}
	else if (TabletCharacter.length > TabletCharacter.width * 150 / 100)
	{
		allRoundSymmetryTabletSW = 0;
	}

	lowerHeightTabletSW = 0;
	if (TabletCharacter.middle_height < 50)
	{
		lowerHeightTabletSW = 1;
	}

	// gradient data 추출
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			if (x > imageAreaStartX + 4 && x < imageAreaEndX - 5 && y > imageAreaStartY + 4 && y < imageAreaEndY - 5)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ShapeBinaryImage[tempAddress] ||
					ShapeBinaryImage[tempAddress - 10] ||
					ShapeBinaryImage[tempAddress + 10])
				{
					if (x < ProtoTabletCenterX)
					{
						allFactorValue[0] = abs(ColorSourceImage[(tempAddress - 4) * 3 + 0] - ColorSourceImage[tempAddress * 3 + 0]);
						allFactorValue[1] = abs(ColorSourceImage[(tempAddress - 4) * 3 + 1] - ColorSourceImage[tempAddress * 3 + 1]);
						allFactorValue[2] = abs(ColorSourceImage[(tempAddress - 4) * 3 + 2] - ColorSourceImage[tempAddress * 3 + 2]);
					}
					else
					{
						allFactorValue[0] = abs(ColorSourceImage[(tempAddress + 4) * 3 + 0] - ColorSourceImage[tempAddress * 3 + 0]);
						allFactorValue[1] = abs(ColorSourceImage[(tempAddress + 4) * 3 + 1] - ColorSourceImage[tempAddress * 3 + 1]);
						allFactorValue[2] = abs(ColorSourceImage[(tempAddress + 4) * 3 + 2] - ColorSourceImage[tempAddress * 3 + 2]);
					}

					maxGradX = max(allFactorValue[0], max(allFactorValue[1], allFactorValue[2]));
					if (maxGradX > deltaThreshold)
					{
						sideGradientImage[tempAddress] = maxGradX;
					}
				}
			}
		}
	}

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			if (x > imageAreaStartX + 4 && x < imageAreaEndX - 5 && y > imageAreaStartY + 4 && y < imageAreaEndY - 5)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ShapeBinaryImage[tempAddress] ||
					ShapeBinaryImage[tempAddress - 10] ||
					ShapeBinaryImage[tempAddress + 10])
				{
					if (y < ProtoTabletCenterY)
					{
						allFactorValue[0] = abs(ColorSourceImage[(tempAddress + 640) * 3 + 0] - ColorSourceImage[(tempAddress - MAX_IMAGE_WIDTH * 3) * 3 + 0]);
						allFactorValue[1] = abs(ColorSourceImage[(tempAddress + 640) * 3 + 1] - ColorSourceImage[(tempAddress - MAX_IMAGE_WIDTH * 3) * 3 + 1]);
						allFactorValue[2] = abs(ColorSourceImage[(tempAddress + 640) * 3 + 2] - ColorSourceImage[(tempAddress - MAX_IMAGE_WIDTH * 3) * 3 + 2]);
					}
					else
					{
						allFactorValue[0] = abs(ColorSourceImage[(tempAddress - 640) * 3 + 0] - ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH * 3) * 3 + 0]);
						allFactorValue[1] = abs(ColorSourceImage[(tempAddress - 640) * 3 + 1] - ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH * 3) * 3 + 1]);
						allFactorValue[2] = abs(ColorSourceImage[(tempAddress - 640) * 3 + 2] - ColorSourceImage[(tempAddress + MAX_IMAGE_WIDTH * 3) * 3 + 2]);
					}

					maxGradY = max(allFactorValue[0], max(allFactorValue[1], allFactorValue[2]));

					GradientImage[tempAddress] = sideGradientImage[tempAddress];
					if (maxGradY > deltaThreshold)
					{
						GradientImage[tempAddress] = max(GradientImage[tempAddress], maxGradY);
					}
				}
			}
		}
	}
	// end

	// 추출된 gradient data 중 잡음성 데이터 제거
	memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;

			if (x > imageAreaStartX + 4 && x < imageAreaEndX - 5 && y > imageAreaStartY + 4 && y < imageAreaEndY - 5)
			{
				if (GradientImage[tempAddress])
				{
					left = GradientImage[tempAddress - 1];
					right = GradientImage[tempAddress + 1];
					top = min(GradientImage[tempAddress - 640], GradientImage[tempAddress - 1280]);
					bottom = min(GradientImage[tempAddress + 640], GradientImage[tempAddress + 1280]);

					if ((left == 0 && right == 0)) // || (top == 0 && bottom == 0))
					{
						TempImage[tempAddress] = 1;
					}
				}
			}
		}
	}

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;

			if (GradientImage[tempAddress] && TempImage[tempAddress])
			{
				GradientImage[tempAddress] = 0;
			}
			else if (noneGradientArea[tempAddress])
			{
				GradientImage[tempAddress] = 0;
			}
		}
	}
	// end

#ifdef PC_SIM
	memcpy(GradientImageForFstStudy, GradientImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif

	// gradient data에 대한 labeling 시도-> 대부분의 데이터는 정제 모양을 포함하는 데이터이므로 이외의 데이터를 필터링 하기 위함임
	halfStartX = startX / 2;
	halfEndX = endX / 2;
	halfStartY = startY / 2;
	halfEndY = endY / 2;

	halfWidth = HALF_IMAGE_WIDTH;
	memset(smallSizeGradientImage, 0, (HALF_IMAGE_WIDTH) * (HALF_IMAGE_HEIGHT));
	for (y = startY; y < endY; ++y)
	{
		for (x = startX; x < endX; ++x)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;

			if (GradientImage[tempAddress])
			{
				smallSizeGradientImage[halfWidth * (y / 2) + (x / 2)] = GradientImage[tempAddress];
			}
		}
	}

	label_Image = RotationEdgeImage;
	memset(label_Image, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	shapeGroupN = SmallSizePixelLabeling(smallSizeGradientImage, label_Image, halfStartX, halfEndX, halfStartY, halfEndY, halfWidth);

	tMax = 1;
	maxPixelLabelN = -1;
	for (m = 1; m <= shapeGroupN; m++)
	{
		if (labelingPxCount[m] > tMax)
		{
			tMax = labelingPxCount[m];
			maxPixelLabelN = m;
		}
	}
	// end

	shapeMinX = MAX_IMAGE_WIDTH;
	shapeMaxX = 0;
	shapeMinY = MAX_IMAGE_HEIGHT;
	shapeMaxY = 0;

	tempCount = 0;

	memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (y = startY; y < endY; ++y)
	{
		for (x = startX; x < endX; ++x)
		{
			tempAddress = (y / 2) * halfWidth + (x / 2);

			if (label_Image[tempAddress] == maxPixelLabelN)
			{
				tempAddress2 = MAX_IMAGE_WIDTH * y + x;

				TempImage[tempAddress2] = 128;

				if (sideGradientImage[tempAddress2] > deltaThreshold)
				{
					if (shapeMinX > x)
						shapeMinX = x;
					if (shapeMaxX < x)
						shapeMaxX = x;
				}

				if (shapeMinY > y)
					shapeMinY = y;
				if (shapeMaxY < y)
					shapeMaxY = y;

				tempCount++;
			}
		}
	}

	// gradient data 기반 shapebinary image 생성
	memset(ShapeBinaryImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (y = startY; y < endY; y++)
	{
		minX = MAX_IMAGE_WIDTH;
		maxX = 0;

		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;

			if (TempImage[tempAddress])
			{
				if (minX > x)
					minX = x;
				if (maxX < x)
					maxX = x;
			}
		}

		for (x = minX; x <= maxX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;
			ShapeBinaryImage[tempAddress] = 1;
		}
	}

	memcpy(TempImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;

			if (!TempImage[tempAddress])
			{
				top = 0;
				for (tempY = y - 6; tempY <= y - 2; tempY += 2)
				{
					if (TempImage[tempY * MAX_IMAGE_WIDTH + x])
					{
						top = 1;
						break;
					}
				}

				bottom = 0;
				for (tempY = y + 6; tempY >= y + 2; tempY -= 2)
				{
					if (TempImage[tempY * MAX_IMAGE_WIDTH + x])
					{
						bottom = 1;
						break;
					}
				}

				if (top && bottom)
				{
					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}
	}

	if (tempCount)
	{
		shapeCenterX = (shapeMinX + shapeMaxX) / 2;
		shapeCenterY = (shapeMinY + shapeMaxY) / 2;

		TabletETCMatchingResult.tabletCenterX = shapeCenterX;
		TabletETCMatchingResult.tabletCenterY = shapeCenterY;
	}
	else
	{
		DefectSW = 2;
		return;
	}
	// end

	// 정제 상하단 경계 정보 -> 일반형 정제를 제외한 나머지 모양들의 경우 측면기둥라인 매칭 과정에서 정제의 제형특성으로 인해 매칭에 실패하는 경우가 발생함
	// 이를 위해 탑라인으로 예상되는 영역을 구분하기 위해 아래 로직 적용
	getThresholdSW = 0;
	if (allRoundSymmetryTabletSW || lowerHeightTabletSW)
	{
		// 정제 영역 내에서 중앙에 가까운 영역을 필터링하고 정제 상단부분과 정제 가운데(어두워지는 영역)의 경게에 대한 gradient data 추출
		maskSize = max(15, 20 * TabletCharacter.middle_height / 40);
		for (y = startY; y < endY; ++y)
		{
			for (x = startX; x < endX; ++x)
			{
				if (x > imageAreaStartX + 4 && x < imageAreaEndX - 5 && y > imageAreaStartY + 4 && y < imageAreaEndY - 5)
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;

					if (ShapeBinaryImage[tempAddress])
					{
						if (!(ShapeBinaryImage[tempAddress - maskSize] == 0 ||
							  ShapeBinaryImage[tempAddress + maskSize] == 0 ||
							  ShapeBinaryImage[tempAddress - maskSize * MAX_IMAGE_WIDTH] == 0 ||
							  ShapeBinaryImage[tempAddress + maskSize * MAX_IMAGE_WIDTH] == 0))
						{
							top = OneColorImage[tempAddress] - OneColorImage[tempAddress + MAX_IMAGE_WIDTH * 6];

							side = 0;
							if (SideAngle == MINUS_45_ANGLE_CAM)
							{
								side = OneColorImage[tempAddress] - OneColorImage[tempAddress - 6];
							}
							else if (SideAngle == PLUS_45_ANGLE_CAM)
							{
								side = OneColorImage[tempAddress] - OneColorImage[tempAddress + 6];
							}

							if (top > deltaThreshold || side > deltaThreshold)
							{
								tabletTopBottomEdgeInfo[halfWidth * (y / 2) + (x / 2)] = 128;
							}
						}
					}
				}
			}
		}
		// end

		interestedPxCount = 0;
		maxColor = 0;
		for (y = halfStartY; y < halfEndY; y++)
		{
			for (x = halfStartX; x < halfEndX; x++)
			{
				tempAddress = halfWidth * y + x;
				if (tabletTopBottomEdgeInfo[tempAddress])
				{
					interestedPxCount++;

					tempAddress2 = MAX_IMAGE_WIDTH * (y * 2) + (x * 2);

					if (maxColor < OneColorImage[tempAddress2])
					{
						maxColor = OneColorImage[tempAddress2];
					}
				}
			}
		}

		// top bottom 경계값 찾기
		// 정제 영역의 최대값을 시작으로 단계적으로 내려가면서 gradient data -> 가운데의 어두워지는 영역과 밝은 탑 라인의 경계 부분을 덮게 되는 경우의 threshold 를 찾음
		tabletTopBottomThreshold = maxColor;
		for (threshold = maxColor; threshold >= 40; threshold -= addStep)
		{
			eraseInterestedPixelCount = 0;
			for (y = halfStartY; y < halfEndY; y++)
			{
				for (x = halfStartX; x < halfEndX; x++)
				{
					tempAddress = halfWidth * y + x;
					if (tabletTopBottomEdgeInfo[tempAddress])
					{
						tempAddress2 = MAX_IMAGE_WIDTH * (y * 2) + (x * 2);

						if (OneColorImage[tempAddress2] > threshold)
						{
							eraseInterestedPixelCount++;
						}
					}
				}
			}

			addStep = 6 * (100 - (eraseInterestedPixelCount * 100 / interestedPxCount)) / 100;

			if (eraseInterestedPixelCount > interestedPxCount * 50 / 100)
			{
				tabletTopBottomThreshold = threshold;
				break;
			}
		}

		getThresholdSW = 1;
		// end

		// 정제 상단으로 예상되는 영역에 대한 binary 화
		memset(tabletTopBottomEdgeInfo, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				if (x > imageAreaStartX + 4 && x < imageAreaEndX - 5 && y > imageAreaStartY + 4 && y < imageAreaEndY - 5)
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;

					if (OneColorImage[tempAddress] > tabletTopBottomThreshold)
					{
						tabletTopBottomEdgeInfo[tempAddress] = 1;
					}
				}
			}
		}

		for (x = startX; x < endX; x++)
		{
			binSW = 0;
			for (y = endY - 1; y >= startY; y--)
			{
				if (x > imageAreaStartX + 4 && x < imageAreaEndX - 5 && y > imageAreaStartY + 4 && y < imageAreaEndY - 5)
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;

					if (tabletTopBottomEdgeInfo[tempAddress])
					{
						binSW = 1;
						writeStartY = y;
						break;
					}
				}
			}

			if (binSW)
			{
				for (y = writeStartY; y >= startY; y--)
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;
					if (ShapeBinaryImage[tempAddress])
					{
						tabletTopBottomEdgeInfo[tempAddress] = 1;
					}
				}
			}
		}
		// end
	}
	// end

	// 측면 기둥 라인 매칭 시도
	leftShiftCenterX = shapeMinX - HALF_IMAGE_WIDTH;
	rightShiftCenterX = shapeMaxX - HALF_IMAGE_WIDTH;
	shiftCenterY = shapeCenterY - HALF_IMAGE_HEIGHT;

	leftShiftXForLeftMatching = 12;
	rightShiftXForLeftMatching = 24;
	leftShiftXForRightMatching = 24;
	rightShiftXForRightMatching = 12;

	retrySW = 0;

RETRY:
	matchingSW = 0;
	maxMatchingValue = 0;

	for (sideWallAngle = sideWallMatchingStRange; sideWallAngle <= sideWallMatchingEdRange; sideWallAngle++)
	{
		maxRightMatchingValue = maxLeftMatchingValue = 0;
		for (wallShiftX = -leftShiftXForLeftMatching; wallShiftX <= rightShiftXForLeftMatching; wallShiftX += 2)
		{
			continuousLength = 0;
			currentMaxLength = 0;
			gradValue = 0;
			maxGradValueforMaxLength = 0;
			leftNotInterestedAreaCount = leftInterestedAreaCount = 0;
			for (m = 0; m < SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount; m += 4)
			{
				tempX = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 0] + leftShiftCenterX + wallShiftX;
				tempY = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 1] + shiftCenterY;

				if (tempX > imageAreaStartX + 4 && tempX < imageAreaEndX - 4 && tempY > imageAreaStartY + 4 && tempY < imageAreaEndY - 4)
				{
					if (tempX >= shapeMinX && tempX <= shapeCenterX && tempY >= shapeMinY && tempY <= shapeMaxY)
					{
						tempAddress = tempY * MAX_IMAGE_WIDTH + tempX;

						disContinuousSW = 1;
						for (j = -2; j <= 2; j += 2)
						{
							for (i = -2; i <= 2; i += 2)
							{
								if (TempImage[tempAddress + i + j * MAX_IMAGE_WIDTH])
								{
									disContinuousSW = 0;
									break;
								}
							}
						}

						if (!disContinuousSW)
						{
							for (i = -2; i <= 2; i += 2)
							{
								// 끊어진 상태에 대한 check 와 gradient sum의 매칭 범위는 서로 달리 한다
								// 끊어진 상태의 경우 disk 벨트, 정제 색상등에 의해 기둥의 gradient 값이 나오지 않을 수 있기 때문에 매칭 범위를 넓혀주고
								// grad 값을 계산할때는 정확한 기둥 위치를 찾아야 하므로 매칭 범위를 좁게 한다
								gradValue += sideGradientImage[tempAddress + i];
							}

							continuousLength++;

							if (tabletTopBottomEdgeInfo[tempAddress + 8])
							{
								leftNotInterestedAreaCount++;
							}
							else
							{
								leftInterestedAreaCount++;
							}

							if (currentMaxLength < continuousLength)
							{
								currentMaxLength = continuousLength;
								maxGradValueforMaxLength = gradValue;

								matchingLeftNotInterestedAreaCount = leftNotInterestedAreaCount;
								matchingLeftInterestedAreaCount = leftInterestedAreaCount;
							}
						}
						else
						{
							continuousLength = 0;
							gradValue = 0;
							leftNotInterestedAreaCount = leftInterestedAreaCount = 0;
						}
					}
				}
			}

			if (allRoundSymmetryTabletSW)
			{
				if (retrySW == 0)
				{
					if (SideAngle != ZERO_ANGLE_CAM)
					{
						if (abs(MAX_SIDE_WALL_ROT_RANGE - sideWallAngle) > 15)
						{
							// 기울기가 큰 경우에만 아래의 조건을 적용한다.
							if (matchingLeftNotInterestedAreaCount > matchingLeftInterestedAreaCount * 3)
							{
								currentMaxLength = 0;
							}
						}
					}
				}
				else
				{
					if (SideAngle == MINUS_45_ANGLE_CAM)
					{
						// 1차 매칭이 실패한 경우에는 camera 각도별 중요 기둥에 대해서만 매칭결과를 확인한다
						if (abs(MAX_SIDE_WALL_ROT_RANGE - sideWallAngle) > 15)
						{
							// 기울기가 큰 경우에만 아래의 조건을 적용한다.
							if (matchingLeftNotInterestedAreaCount > matchingLeftInterestedAreaCount * 3)
							{
								currentMaxLength = 0;
							}
						}
					}
				}
			}

			if (currentMaxLength)
			{
				if (maxLeftMatchingValue < maxGradValueforMaxLength)
				{
					maxLeftMatchingValue = maxGradValueforMaxLength;
					matchingLeftShiftX = wallShiftX;
				}
			}
		}

		for (wallShiftX = -leftShiftXForRightMatching; wallShiftX <= rightShiftXForRightMatching; wallShiftX += 2)
		{
			continuousLength = 0;
			currentMaxLength = 0;
			gradValue = 0;
			maxGradValueforMaxLength = 0;
			rightNotInterestedAreaCount = rightInterestedAreaCount = 0;
			for (m = 0; m < SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount; m += 4)
			{
				tempX = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 0] + rightShiftCenterX + wallShiftX;
				tempY = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 1] + shiftCenterY;

				if (tempX > imageAreaStartX + 4 && tempX < imageAreaEndX - 4 && tempY > imageAreaStartY + 4 && tempY < imageAreaEndY - 4)
				{
					if (tempX >= shapeCenterX && tempX <= shapeMaxX && tempY >= shapeMinY && tempY <= shapeMaxY)
					{
						tempAddress = tempY * MAX_IMAGE_WIDTH + tempX;
						disContinuousSW = 1;
						for (j = -2; j <= 2; j += 2)
						{
							for (i = -2; i <= 2; i += 2)
							{
								if (TempImage[tempAddress + i + j * MAX_IMAGE_WIDTH])
								{
									disContinuousSW = 0;
									break;
								}
							}
						}

						if (!disContinuousSW)
						{
							for (i = -2; i <= 2; i += 2)
							{
								gradValue += sideGradientImage[tempAddress + i];
							}

							continuousLength++;

							if (tabletTopBottomEdgeInfo[tempAddress - 8])
							{
								rightNotInterestedAreaCount++;
							}
							else
							{
								rightInterestedAreaCount++;
							}

							if (currentMaxLength < continuousLength)
							{
								currentMaxLength = continuousLength;
								maxGradValueforMaxLength = gradValue;

								matchingRightNotInterestedAreaCount = rightNotInterestedAreaCount;
								matchingRightInterestedAreaCount = rightInterestedAreaCount;
							}
						}
						else
						{
							continuousLength = 0;
							gradValue = 0;
							rightNotInterestedAreaCount = rightInterestedAreaCount = 0;
						}
					}
				}
			}

			if (allRoundSymmetryTabletSW)
			{
				if (retrySW == 0)
				{
					if (SideAngle != ZERO_ANGLE_CAM)
					{
						if (abs(MAX_SIDE_WALL_ROT_RANGE - sideWallAngle) > 15)
						{
							// 기울기가 큰 경우에만 아래의 조건을 적용한다.
							if (matchingRightNotInterestedAreaCount > matchingRightInterestedAreaCount * 3)
							{
								currentMaxLength = 0;
							}
						}
					}
				}
				else
				{
					if (SideAngle == PLUS_45_ANGLE_CAM)
					{
						// 1차 매칭이 실패한 경우에는 camera 각도별 중요 기둥에 대해서만 매칭결과를 확인한다
						if (abs(MAX_SIDE_WALL_ROT_RANGE - sideWallAngle) > 15)
						{
							// 기울기가 큰 경우에만 아래의 조건을 적용한다.
							if (matchingRightNotInterestedAreaCount > matchingRightInterestedAreaCount * 3)
							{
								currentMaxLength = 0;
							}
						}
					}
				}
			}

			if (currentMaxLength)
			{
				if (maxRightMatchingValue < maxGradValueforMaxLength)
				{
					maxRightMatchingValue = maxGradValueforMaxLength;
					matchingRightShiftX = wallShiftX;
				}
			}
		}

		leftSideTopPos[1] = MAX_IMAGE_HEIGHT;
		leftSideBottomPos[1] = 0;

		rightSideTopPos[1] = MAX_IMAGE_HEIGHT;
		rightSideBottomPos[1] = 0;

		if (maxLeftMatchingValue)
		{
			continuousLength = 0;
			currentMaxLength = 0;
			stPoint = 0;
			endPoint = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount;
			if (SideAngle == ZERO_ANGLE_CAM || SideAngle == MINUS_45_ANGLE_CAM)
			{
				for (m = 0; m < SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount; m += 2)
				{
					tempX = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 0] + leftShiftCenterX + matchingLeftShiftX;
					tempY = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 1] + shiftCenterY;

					if (tempX > imageAreaStartX + 4 && tempX < imageAreaEndX - 4 && tempY > imageAreaStartY + 4 && tempY < imageAreaEndY - 4)
					{
						tempAddress = tempY * MAX_IMAGE_WIDTH + tempX;

						disContinuousSW = 1;
						for (j = -2; j <= 2; j += 2)
						{
							for (i = -2; i <= 2; i += 2)
							{
								if (TempImage[tempAddress + i + j * MAX_IMAGE_WIDTH])
								{
									disContinuousSW = 0;
									break;
								}
							}
						}

						if (!disContinuousSW)
						{
							if (continuousLength == 0)
							{
								tempStPoint = m;
							}
							continuousLength++;

							if (currentMaxLength < continuousLength)
							{
								currentMaxLength = continuousLength;
								stPoint = tempStPoint;
								endPoint = m;
							}
						}
						else
						{
							continuousLength = 0;
						}
					}
				}
			}

			for (m = 0; m < SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount; m += 2)
			{
				tempX = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 0] + leftShiftCenterX + matchingLeftShiftX;
				tempY = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 1] + shiftCenterY;

				if (tempX > imageAreaStartX + 4 && tempX < imageAreaEndX - 4 && tempY > imageAreaStartY + 4 && tempY < imageAreaEndY - 4)
				{
					if (m >= stPoint && m <= endPoint)
					{
						tempAddress = tempY * MAX_IMAGE_WIDTH + tempX;

						if (TempImage[tempAddress] && sideGradientImage[tempAddress])
						{
							if (leftSideTopPos[1] > tempY)
							{
								leftSideTopPos[0] = tempX;
								leftSideTopPos[1] = tempY;
							}

							if (leftSideBottomPos[1] < tempY)
							{
								leftSideBottomPos[0] = tempX;
								leftSideBottomPos[1] = tempY;
							}
						}
					}
				}
			}
		}

		if (maxRightMatchingValue)
		{
			continuousLength = 0;
			currentMaxLength = 0;
			stPoint = 0;
			endPoint = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount;
			if (SideAngle == ZERO_ANGLE_CAM || SideAngle == PLUS_45_ANGLE_CAM)
			{
				for (m = 0; m < SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount; m += 2)
				{
					tempX = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 0] + rightShiftCenterX + matchingRightShiftX;
					tempY = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 1] + shiftCenterY;

					if (tempX > imageAreaStartX + 4 && tempX < imageAreaEndX - 4 && tempY > imageAreaStartY + 4 && tempY < imageAreaEndY - 4)
					{
						tempAddress = tempY * MAX_IMAGE_WIDTH + tempX;

						disContinuousSW = 1;
						for (j = -2; j <= 2; j += 2)
						{
							for (i = -2; i <= 2; i += 2)
							{
								if (TempImage[tempAddress + i + j * MAX_IMAGE_WIDTH])
								{
									disContinuousSW = 0;
									break;
								}
							}
						}

						if (!disContinuousSW)
						{
							if (continuousLength == 0)
							{
								tempStPoint = m;
							}
							continuousLength++;

							if (currentMaxLength < continuousLength)
							{
								currentMaxLength = continuousLength;
								stPoint = tempStPoint;
								endPoint = m;
							}
						}
						else
						{
							continuousLength = 0;
						}
					}
				}
			}

			for (m = 0; m < SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxDataCount; m += 2)
			{
				tempX = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 0] + rightShiftCenterX + matchingRightShiftX;
				tempY = SideWallMatchingData.SideWallData[sideWallAngle].SideWallPxData[m * 2 + 1] + shiftCenterY;

				if (tempX > imageAreaStartX + 4 && tempX < imageAreaEndX - 4 && tempY > imageAreaStartY + 4 && tempY < imageAreaEndY - 4)
				{
					if (m >= stPoint && m <= endPoint)
					{
						tempAddress = tempY * MAX_IMAGE_WIDTH + tempX;

						if (TempImage[tempAddress] && sideGradientImage[tempAddress])
						{
							if (rightSideTopPos[1] > tempY)
							{
								rightSideTopPos[0] = tempX;
								rightSideTopPos[1] = tempY;
							}

							if (rightSideBottomPos[1] < tempY)
							{
								rightSideBottomPos[0] = tempX;
								rightSideBottomPos[1] = tempY;
							}
						}
					}
				}
			}
		}

		if (allRoundSymmetryTabletSW)
		{
			if (retrySW == 0)
			{
				xDiff = leftSideTopPos[0] - leftSideBottomPos[0];
				yDiff = leftSideTopPos[1] - leftSideBottomPos[1];
				leftLength = xDiff * xDiff + yDiff * yDiff;

				xDiff = rightSideTopPos[0] - rightSideBottomPos[0];
				yDiff = rightSideTopPos[1] - rightSideBottomPos[1];
				rightLength = xDiff * xDiff + yDiff * yDiff;

				if (leftLength > 225 && rightLength > 225)
				{
					// 기둥의 최소 length는 15px로 가정(15^2)
					if (leftLength > rightLength * 5 || leftLength * 5 < rightLength)
						continue;
				}
			}
		}

		if (leftSideTopPos[1] != MAX_IMAGE_HEIGHT && leftSideBottomPos[1] != 0 && rightSideTopPos[1] != MAX_IMAGE_HEIGHT && rightSideBottomPos[1] != 0)
		{
			if (maxMatchingValue < maxLeftMatchingValue * leftWeight + maxRightMatchingValue * rightWeight)
			{
				maxMatchingValue = maxLeftMatchingValue * leftWeight + maxRightMatchingValue * rightWeight;

				matchingLeftTopWallInfo[0] = leftSideTopPos[0];
				matchingLeftTopWallInfo[1] = leftSideTopPos[1];
				matchingLeftBottomWallInfo[0] = leftSideBottomPos[0];
				matchingLeftBottomWallInfo[1] = leftSideBottomPos[1];

				matchingRightTopWallInfo[0] = rightSideTopPos[0];
				matchingRightTopWallInfo[1] = rightSideTopPos[1];
				matchingRightBottomWallInfo[0] = rightSideBottomPos[0];
				matchingRightBottomWallInfo[1] = rightSideBottomPos[1];

				matchingSW = 1;
			}
		}
	}
	// end

	if (!matchingSW)
	{
		if (retrySW == 0)
		{
			if (allRoundSymmetryTabletSW)
			{
				retrySW = 1;
				goto RETRY;
			}
			else
			{
				DefectSW = 3;
				return;
			}
		}
		else
		{
			DefectSW = 3;
			return;
		}
	}

	TabletETCMatchingResult.topLeftWallInfo[0] = matchingLeftTopWallInfo[0];
	TabletETCMatchingResult.topLeftWallInfo[1] = matchingLeftTopWallInfo[1];

	TabletETCMatchingResult.botLeftWallInfo[0] = matchingLeftBottomWallInfo[0];
	TabletETCMatchingResult.botLeftWallInfo[1] = matchingLeftBottomWallInfo[1];

	TabletETCMatchingResult.topRightWallInfo[0] = matchingRightTopWallInfo[0];
	TabletETCMatchingResult.topRightWallInfo[1] = matchingRightTopWallInfo[1];

	TabletETCMatchingResult.botRightWallInfo[0] = matchingRightBottomWallInfo[0];
	TabletETCMatchingResult.botRightWallInfo[1] = matchingRightBottomWallInfo[1];

	// shape data 생성
	for (tempY = TabletETCMatchingResult.botLeftWallInfo[1]; tempY >= TabletETCMatchingResult.topLeftWallInfo[1]; tempY--)
	{
		if (TabletETCMatchingResult.topLeftWallInfo[1] - TabletETCMatchingResult.botLeftWallInfo[1])
		{
			tempX = (TabletETCMatchingResult.topLeftWallInfo[0] - TabletETCMatchingResult.botLeftWallInfo[0]) * (tempY - TabletETCMatchingResult.topLeftWallInfo[1]) / (TabletETCMatchingResult.topLeftWallInfo[1] - TabletETCMatchingResult.botLeftWallInfo[1]) + TabletETCMatchingResult.topLeftWallInfo[0];

			if (tempX)
			{
				if (TabletETCMatchingResult.tabletShapeLeftLineCount < MAX_IMAGE_HEIGHT)
				{
					TabletETCMatchingResult.tabletShapeLeftLine[TabletETCMatchingResult.tabletShapeLeftLineCount * 2 + 0] = tempX;
					TabletETCMatchingResult.tabletShapeLeftLine[TabletETCMatchingResult.tabletShapeLeftLineCount * 2 + 1] = tempY;
					TabletETCMatchingResult.tabletShapeLeftLineCount++;
				}
			}
		}
	}

	for (tempY = TabletETCMatchingResult.botRightWallInfo[1]; tempY >= TabletETCMatchingResult.topRightWallInfo[1]; tempY--)
	{
		if (TabletETCMatchingResult.topRightWallInfo[1] - TabletETCMatchingResult.botRightWallInfo[1])
		{
			tempX = (TabletETCMatchingResult.topRightWallInfo[0] - TabletETCMatchingResult.botRightWallInfo[0]) * (tempY - TabletETCMatchingResult.topRightWallInfo[1]) / (TabletETCMatchingResult.topRightWallInfo[1] - TabletETCMatchingResult.botRightWallInfo[1]) + TabletETCMatchingResult.topRightWallInfo[0];

			if (tempX)
			{
				if (TabletETCMatchingResult.tabletShapeRightLineCount < MAX_IMAGE_HEIGHT)
				{
					TabletETCMatchingResult.tabletShapeRightLine[TabletETCMatchingResult.tabletShapeRightLineCount * 2 + 0] = tempX;
					TabletETCMatchingResult.tabletShapeRightLine[TabletETCMatchingResult.tabletShapeRightLineCount * 2 + 1] = tempY;
					TabletETCMatchingResult.tabletShapeRightLineCount++;
				}
			}
		}
	}
	// end

	maskSize = 3;
	for (m = 0; m < TabletETCMatchingResult.tabletShapeLeftLineCount; m++)
	{
		tempX = TabletETCMatchingResult.tabletShapeLeftLine[m * 2 + 0];
		tempY = TabletETCMatchingResult.tabletShapeLeftLine[m * 2 + 1];

		for (y = tempY - maskSize; y <= tempY + maskSize; y++)
		{
			for (x = tempX - maskSize; x <= tempX + maskSize * 2; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				noneGradientArea[tempAddress] = 1;
			}
		}
	}

	for (m = 0; m < TabletETCMatchingResult.tabletShapeRightLineCount; m++)
	{
		tempX = TabletETCMatchingResult.tabletShapeRightLine[m * 2 + 0];
		tempY = TabletETCMatchingResult.tabletShapeRightLine[m * 2 + 1];

		for (y = tempY - maskSize; y <= tempY + maskSize; y++)
		{
			for (x = tempX - maskSize * 2; x <= tempX + maskSize; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				noneGradientArea[tempAddress] = 1;
			}
		}
	}

	shapeEdge1[0] = TabletETCMatchingResult.botLeftWallInfo[0];
	shapeEdge1[1] = TabletETCMatchingResult.botLeftWallInfo[1];

	shapeEdge2[0] = TabletETCMatchingResult.botRightWallInfo[0];
	shapeEdge2[1] = TabletETCMatchingResult.botRightWallInfo[1];

	// bottom line 생성 전 영역제한을 위한 데이터 생성
	for (m = 0; m < MAX_IMAGE_WIDTH; m++)
	{
		limitBinaryAreaInfo[m] = MAX_IMAGE_HEIGHT;
	}

	for (tempX = shapeEdge2[0]; tempX >= shapeEdge1[0]; tempX--)
	{
		if (shapeEdge1[0] - shapeEdge2[0])
		{
			tempY = (tempX - shapeEdge1[0]) * (shapeEdge1[1] - shapeEdge2[1]) / (shapeEdge1[0] - shapeEdge2[0]) + shapeEdge1[1];

			if (tempY)
			{
				for (tempY2 = tempY - 2; tempY2 <= tempY + 2; tempY2++)
				{
					for (tempX2 = tempX - 2; tempX2 <= tempX + 2; tempX2++)
					{
						if (limitBinaryAreaInfo[tempX2] > tempY2)
						{
							limitBinaryAreaInfo[tempX2] = tempY2;
						}
					}
				}
			}
		}
	}
	// end

	tabletThreshold = TabletSetupData.SideFaceShapeExtractThreshold;
	if (!getThresholdSW)
	{
		tabletTopBottomThreshold = 255;
	}
	else
	{
		tabletTopBottomThreshold = (tabletTopBottomThreshold + tabletThreshold) / 2;
		if (tabletTopBottomThreshold < tabletThreshold)
		{
			tabletTopBottomThreshold = 255;
		}
	}

	// bottom line 예상군 분류
	halfWidth = HALF_IMAGE_WIDTH;
	memset(smallSizeGradientImage, 0, (HALF_IMAGE_WIDTH) * (HALF_IMAGE_HEIGHT));
	for (x = shapeEdge1[0]; x < shapeEdge2[0]; ++x)	
	{
		binSW = 0;
		for (y = startY; y < endY; ++y)
		{
			if (y > limitBinaryAreaInfo[x] - 8)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (GradientImage[tempAddress] && OneColorImage[tempAddress] <= tabletTopBottomThreshold)
				{
					smallSizeGradientImage[halfWidth * (y / 2) + (x / 2)] = GradientImage[tempAddress];
					binSW = 1;
				}
			}
		}

		if (binSW == 0)
		{
			for (y = startY; y < endY; ++y)
			{
				if (y > limitBinaryAreaInfo[x])
				{
					tempAddress = y * MAX_IMAGE_WIDTH + x;

					if (GradientImage[tempAddress])
					{
						smallSizeGradientImage[halfWidth * (y / 2) + (x / 2)] = GradientImage[tempAddress];
					}
				}
			}
		}
	}

	label_Image = RotationEdgeImage;
	memset(label_Image, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	shapeGroupN = SmallSizePixelLabeling(smallSizeGradientImage, label_Image, startX / 2, endX / 2, startY / 2, endY / 2, HALF_IMAGE_WIDTH);

	tMax = 1;
	maxPixelLabelN = -1;
	for (m = 1; m <= shapeGroupN; m++)
	{
		if (labelingPxCount[m] > tMax)
		{
			tMax = labelingPxCount[m];
			maxPixelLabelN = m;
		}
	}

	memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (y = startY; y < endY; ++y)
	{
		for (x = startX; x < endX; ++x)
		{
			tempAddress = halfWidth * (y / 2) + (x / 2);

			if (label_Image[tempAddress] == maxPixelLabelN)
			{
				TempImage[MAX_IMAGE_WIDTH * y + x] = 128;
			}
		}
	}
	// end

	shapeCenter[0] = (TabletETCMatchingResult.botRightWallInfo[0] + TabletETCMatchingResult.botLeftWallInfo[0]) / 2;
	shapeCenter[1] = (TabletETCMatchingResult.botRightWallInfo[1] + TabletETCMatchingResult.botLeftWallInfo[1]) / 2;

	pX = TabletETCMatchingResult.topLeftWallInfo[0] - TabletETCMatchingResult.botLeftWallInfo[0];
	pY = TabletETCMatchingResult.topLeftWallInfo[1] - TabletETCMatchingResult.botLeftWallInfo[1];

	angle = 0;
	uLength = pX * pX + pY * pY;
	if (uLength < 90000)
	{
		uLength = SqrtData[uLength]; // sqrtdata는 128이 곱해 진 상태.
		sinV = 1280000 * pX / uLength;

		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];

		angle = (angle + 360) % 360;
		angle = (angle * 2 + 720) % 720;
	}

	memset(TempImage3, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	tempRotateGradientImg = DentedArea;

	tempAngle = angle;

	angle = (-tempAngle + 720) % 720;
	angle = (angle + 90 + 720) % 720;

	constCosV = CosData[angle];
	constSinV = SinData[angle];

	memset(TempImage2, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(tempRotateGradientImg, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	rStartY = MAX_IMAGE_HEIGHT;
	rEndY = 0;

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (ShapeBinaryImage[tempAddress])
			{
				rotateX = ((constCosV * (x - shapeCenter[0]) - constSinV * (y - shapeCenter[1])) / 1024) + shapeCenter[0];
				rotateY = ((constSinV * (x - shapeCenter[0]) + constCosV * (y - shapeCenter[1])) / 1024) + shapeCenter[1];

				if (rotateX > 2 && rotateX < MAX_IMAGE_WIDTH - 2 && rotateY > 2 && rotateY < MAX_IMAGE_HEIGHT - 2)
				{
					tempAddress2 = MAX_IMAGE_WIDTH * rotateY + rotateX;

					if (rotateY < rStartY)
						rStartY = rotateY;
					if (rotateY > rEndY)
						rEndY = rotateY;

					if (TempImage[tempAddress])
					{
						TempImage2[tempAddress2] = TempImage[tempAddress];
						TempImage2[tempAddress2 + 1] = TempImage[tempAddress];
						TempImage2[tempAddress2 + MAX_IMAGE_WIDTH] = TempImage[tempAddress];
						TempImage2[tempAddress2 + MAX_IMAGE_WIDTH + 1] = TempImage[tempAddress];
					}

					if (GradientImage[tempAddress])
					{
						tempRotateGradientImg[tempAddress2] = GradientImage[tempAddress];
						tempRotateGradientImg[tempAddress2 + 1] = GradientImage[tempAddress];
						tempRotateGradientImg[tempAddress2 + MAX_IMAGE_WIDTH] = GradientImage[tempAddress];
						tempRotateGradientImg[tempAddress2 + MAX_IMAGE_WIDTH + 1] = GradientImage[tempAddress];
					}
				}
			}
		}
	}

	rStartY = max(4, rStartY - 4);
	rEndY = min(MAX_IMAGE_HEIGHT - 4, rEndY + 4);

	rStartX = ((constCosV * (TabletETCMatchingResult.botLeftWallInfo[0] - shapeCenter[0]) - constSinV * (TabletETCMatchingResult.botLeftWallInfo[1] - shapeCenter[1])) / 1024) + shapeCenter[0];
	rEndX = ((constCosV * (TabletETCMatchingResult.botRightWallInfo[0] - shapeCenter[0]) - constSinV * (TabletETCMatchingResult.botRightWallInfo[1] - shapeCenter[1])) / 1024) + shapeCenter[0];

	angle = (-angle + 720) % 720;

	constCosV = CosData[angle];
	constSinV = SinData[angle];

	// bottom line 생성
	for (x = rStartX + 10; x < rEndX - 10; x++)
	{
		binSW = 0;
		maxColor = 0;
		for (y = rEndY; y > rStartY; y--)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (TempImage2[tempAddress])
			{
				if (maxColor < tempRotateGradientImg[tempAddress])
				{
					maxColor = tempRotateGradientImg[tempAddress];
					tempY = y;
					binSW = 1;
				}
			}
		}

		if (binSW)
		{
			rotateX = ((constCosV * (x - shapeCenter[0]) - constSinV * (tempY - shapeCenter[1])) / 1024) + shapeCenter[0];
			rotateY = ((constSinV * (x - shapeCenter[0]) + constCosV * (tempY - shapeCenter[1])) / 1024) + shapeCenter[1];

			TempImage3[MAX_IMAGE_WIDTH * rotateY + rotateX] = 1;
		}
	}

	angle = (-tempAngle + 720) % 720;
	angle = (angle - 90 + 720) % 720;

	constCosV = CosData[angle];
	constSinV = SinData[angle];

	memset(TempImage2, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(tempRotateGradientImg, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	rStartY = MAX_IMAGE_HEIGHT;
	rEndY = 0;

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (ShapeBinaryImage[tempAddress])
			{
				rotateX = ((constCosV * (x - shapeCenter[0]) - constSinV * (y - shapeCenter[1])) / 1024) + shapeCenter[0];
				rotateY = ((constSinV * (x - shapeCenter[0]) + constCosV * (y - shapeCenter[1])) / 1024) + shapeCenter[1];

				if (rotateX > 2 && rotateX < MAX_IMAGE_WIDTH - 2 && rotateY > 2 && rotateY < MAX_IMAGE_HEIGHT - 2)
				{
					tempAddress2 = MAX_IMAGE_WIDTH * rotateY + rotateX;

					if (rotateY < rStartY)
						rStartY = rotateY;
					if (rotateY > rEndY)
						rEndY = rotateY;

					if (TempImage[tempAddress])
					{
						TempImage2[tempAddress2] = TempImage[tempAddress];
						TempImage2[tempAddress2 + 1] = TempImage[tempAddress];
						TempImage2[tempAddress2 + MAX_IMAGE_WIDTH] = TempImage[tempAddress];
						TempImage2[tempAddress2 + MAX_IMAGE_WIDTH + 1] = TempImage[tempAddress];
					}

					if (GradientImage[tempAddress])
					{
						tempRotateGradientImg[tempAddress2] = GradientImage[tempAddress];
						tempRotateGradientImg[tempAddress2 + 1] = GradientImage[tempAddress];
						tempRotateGradientImg[tempAddress2 + MAX_IMAGE_WIDTH] = GradientImage[tempAddress];
						tempRotateGradientImg[tempAddress2 + MAX_IMAGE_WIDTH + 1] = GradientImage[tempAddress];
					}
				}
			}
		}
	}

	rStartY = max(4, rStartY - 4);
	rEndY = min(MAX_IMAGE_HEIGHT - 4, rEndY + 4);

	rStartX = ((constCosV * (TabletETCMatchingResult.botLeftWallInfo[0] - shapeCenter[0]) - constSinV * (TabletETCMatchingResult.botLeftWallInfo[1] - shapeCenter[1])) / 1024) + shapeCenter[0];
	rEndX = ((constCosV * (TabletETCMatchingResult.botRightWallInfo[0] - shapeCenter[0]) - constSinV * (TabletETCMatchingResult.botRightWallInfo[1] - shapeCenter[1])) / 1024) + shapeCenter[0];

	angle = (-angle + 720) % 720;

	constCosV = CosData[angle];
	constSinV = SinData[angle];

	// bottom line 생성
	for (x = rStartX + 10; x < rEndX - 10; x++)
	{
		binSW = 0;
		maxColor = 0;
		for (y = rEndY; y > rStartY; y--)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (TempImage2[tempAddress])
			{
				if (maxColor < tempRotateGradientImg[tempAddress])
				{
					maxColor = tempRotateGradientImg[tempAddress];
					tempY = y;
					binSW = 1;
				}
			}
		}

		if (binSW)
		{
			rotateX = ((constCosV * (x - shapeCenter[0]) - constSinV * (tempY - shapeCenter[1])) / 1024) + shapeCenter[0];
			rotateY = ((constSinV * (x - shapeCenter[0]) + constCosV * (tempY - shapeCenter[1])) / 1024) + shapeCenter[1];

			TempImage3[MAX_IMAGE_WIDTH * rotateY + rotateX] = 1;
		}
	}

	memcpy(TempImage2, TempImage3, 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 (TempImage2[tempAddress])
			{
				for (tempY = y - 2; tempY <= y + 2; tempY++)
				{
					for (tempX = x - 2; tempX <= x + 2; tempX++)
					{
						if (tempX > 0 && tempX < MAX_IMAGE_WIDTH && tempY > 0 && tempY < MAX_IMAGE_HEIGHT)
						{
							TempImage3[MAX_IMAGE_WIDTH * tempY + tempX] = 255;
						}
					}
				}
			}
		}
	}

	label_Image = RotationEdgeImage;
	memset(label_Image, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * sizeof(short));
	labelCount = SmallSizePixelLabeling(TempImage3, label_Image, startX, endX, startY, endY, MAX_IMAGE_WIDTH);

	maxLabelN = -1;
	tempCount = 0;
	for (m = 1; m <= labelCount; m++)
	{
		if (labelingPxCount[m] > tempCount)
		{
			tempCount = labelingPxCount[m];
			maxLabelN = m;
		}
	}

	memset(TempImage3, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	if (maxLabelN > -1)
	{
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				if (label_Image[tempAddress] == maxLabelN)
				{
					TempImage3[tempAddress] = 1;
				}
			}
		}

		shapeCenter[0] = ProtoTabletCenterX;
		shapeCenter[1] = ProtoTabletCenterY;

		memset(BottomLineInfo, 0, sizeof(int) * 360 * 3);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				if (TempImage3[tempAddress])
				{
					pX = x - shapeCenter[0];
					pY = y - shapeCenter[1];

					uLength = pX * pX + pY * pY;
					if (uLength < 90000)
					{
						uLength = SqrtData[uLength]; // sqrtdata는 128이 곱해 진 상태.
						sinV = 1280000 * pX / uLength;

						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];

						angle = (angle + 360) % 360;

						if (angle >= 0 && angle <= 360)
						{
							BottomLineInfo[angle][0] += x;
							BottomLineInfo[angle][1] += y;
							BottomLineInfo[angle][2]++;
						}
					}
				}
			}
		}

		for (m = 0; m < 360; m++)
		{
			if (BottomLineInfo[m][2])
			{
				BottomLineInfo[m][0] = BottomLineInfo[m][0] / BottomLineInfo[m][2];
				BottomLineInfo[m][1] = BottomLineInfo[m][1] / BottomLineInfo[m][2];
			}
		}

		minAngle = 1000;
		maxAngle = -1;

		memset(AvgBottomLineInfo, 0, sizeof(int) * 360 * 3);
		for (m = 0; m < 360; m++)
		{
			if (BottomLineInfo[m][2])
			{
				tempX = tempY = tempCount = 0;
				for (n = m - 2; n <= m + 2; n++)
				{
					tempAngle = (n + 360) % 360;

					if (BottomLineInfo[tempAngle][2])
					{
						tempX += BottomLineInfo[tempAngle][0];
						tempY += BottomLineInfo[tempAngle][1];
						tempCount++;
					}
				}

				if (tempCount)
				{
					tempX /= tempCount;
					tempY /= tempCount;

					tempAddress = MAX_IMAGE_WIDTH * tempY + tempX;
					if (TempImage3[tempAddress])
					{
						AvgBottomLineInfo[m][0] = tempX;
						AvgBottomLineInfo[m][1] = tempY;
						AvgBottomLineInfo[m][2] = 1;

						TempImage3[tempAddress] = 2;

						if (minAngle > m)
							minAngle = m;
						if (maxAngle < m)
							maxAngle = m;
					}
				}
			}
		}

		for (m = minAngle; m <= maxAngle - 1; m++)
		{
			startAngle = endAngle = -1;

			if (AvgBottomLineInfo[m][2])
			{
				startAngle = m;
				for (n = m + 1; n <= maxAngle - 1; n++)
				{
					if (AvgBottomLineInfo[n][2])
					{
						endAngle = n;
						break;
					}
				}
			}

			if (startAngle > -1 && endAngle > -1)
			{
				startX = AvgBottomLineInfo[startAngle][0];
				startY = AvgBottomLineInfo[startAngle][1];

				endX = AvgBottomLineInfo[endAngle][0];
				endY = AvgBottomLineInfo[endAngle][1];

				pX = endX - startX;
				pY = endY - startY;
				uLength = pX * pX + pY * pY;

				if (uLength > 1)
				{
					if (abs(pX) < abs(pY))
					{
						if (startY < endY)
						{
							for (y = startY; y <= endY - 1; y++)
							{
								x = (startX - endX) * (y - startY) / (startY - endY) + startX;

								TempImage3[MAX_IMAGE_WIDTH * y + x] = 2;
							}
						}
						else
						{
							for (y = startY; y >= endY + 1; y--)
							{
								x = (startX - endX) * (y - startY) / (startY - endY) + startX;

								TempImage3[MAX_IMAGE_WIDTH * y + x] = 2;
							}
						}
					}
					else
					{
						if (startX < endX)
						{
							for (x = startX; x <= endX - 1; x++)
							{
								y = (startY - endY) * (x - startX) / (startX - endX) + startY;

								TempImage3[MAX_IMAGE_WIDTH * y + x] = 2;
							}
						}
						else
						{
							for (x = startX; x >= endX + 1; x--)
							{
								y = (startY - endY) * (x - startX) / (startX - endX) + startY;

								TempImage3[MAX_IMAGE_WIDTH * y + x] = 2;
							}
						}
					}
				}
			}
		}
	}

	startX = TabletSetupData.ImageCutStartX[cameraIndex - 1];
	startY = TabletSetupData.ImageCutStartY[cameraIndex - 1];
	endX = TabletSetupData.ImageCutEndX[cameraIndex - 1];
	endY = TabletSetupData.ImageCutEndY[cameraIndex - 1];

	tempShapeBottomLineCount = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			if (TempImage3[tempAddress] == 2)
			{
				if (tempShapeBottomLineCount < MAX_IMAGE_WIDTH)
				{
					tempShapeBottomLine[tempShapeBottomLineCount][0] = x;
					tempShapeBottomLine[tempShapeBottomLineCount][1] = y;
					tempShapeBottomLineCount++;
				}
			}
		}
	}

	minX = MAX_IMAGE_WIDTH;
	minY = MAX_IMAGE_HEIGHT;
	for (m = 0; m < tempShapeBottomLineCount; m++)
	{
		tempX = tempShapeBottomLine[m][0];
		tempY = tempShapeBottomLine[m][1];

		if (tempX < minX)
			minX = tempX;
		if (tempY < minY)
			minY = tempY;
	}

	TabletETCMatchingResult.tabletShapeBottomLineMinX = minX;
	TabletETCMatchingResult.tabletShapeBottomLineMinY = minY;

	memcpy(TabletETCMatchingResult.tabletShapeBottomLine, tempShapeBottomLine, sizeof(short) * MAX_IMAGE_WIDTH * 2);
	TabletETCMatchingResult.tabletShapeBottomLineCount = tempShapeBottomLineCount;

	if (TabletETCMatchingResult.tabletShapeBottomLineCount == 0 ||
		TabletETCMatchingResult.tabletShapeLeftLineCount == 0 ||
		TabletETCMatchingResult.tabletShapeRightLineCount == 0)
	{
		DefectSW = 3;
	}
}
//---------------------------------------------------------------------------
void DefectSearchForSideShape(int cameraIndex)
{
	int startX, endX, startY, endY;
	int areaValue;
	int x, y, m, r, i, j, n;

	short defectPointData[MAX_DEFECT_POINT_COUNT * 3];
	int defectPointDataCnt;
	short brightDefectPointData[MAX_DEFECT_POINT_COUNT * 3];
	int brightDefectPointDataCnt;
	short colorDefectPointData[MAX_DEFECT_POINT_COUNT * 3];
	int colorDefectPointDataCnt;
	short DefectPointDataForRearrange[MAX_DEFECT_POINT_COUNT * 3];
	int DefectPointDataCntForRearrange;

	int tempAddress;
	int tempAddress2;
	int defectGroupN;
	unsigned char *tempOneColorImage;
	int brightDefectCheckSW = 0;
	int darkDefectCheckSW = 0;
	int darkSpotCheckSW = 0;
	int tempCount;
	int colorDiff[4];
	int darkDefectColorDiff;
	int brightDefectColorDiff;

	int alpha;
	int thresholdDark;
	int compareAcceptArea[11][11];
	int thresholdForEaceArea[11];
	int thresholdForEaceAreaBright[11];
	int thresholdBright;
	int tMax;
	int maxPixelDefectLabelN;
	int tempSum;

	int selfPositionValueBright;
	int selfPositionValue[4];
	short *label_Image;
	int interestedColor;
	int notInterestedColor[2];
	int colorValue[3];
	unsigned char *tempMaskBuf;
	unsigned char *candidateDefectPoint;
	int cornerDarkDefectThreshold;
	int cornerDarkDefectSize;
	int cornerBrightDefectThreshold;
	int cornerBrightDefectSize;
	int maxColorDiff;
	int maxColorDiff2;
	int tempLabelN;
	int remakeInspectionArea;
	int expectedDefect;
	int DefectSearchSW;
	int tempX, tempY;
	int breakSW;
	int edgeNeighborAreaMeanColor;
	int darkSpotThreshold;
	int topSW, bottomSW, leftSW, rightSW, topleftSW, toprightSW, bottomleftSW, bottomrightSW;

	remakeInspectionArea = 0;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	label_Image = RotationEdgeImage;

	memset(defectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
	defectPointDataCnt = 0;

	tempMaskBuf = DentedArea; // 임시 이미지 버퍼
	memset(tempMaskBuf, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	alpha = TabletGradeData.side_stain_Intensity * 2;

	edgeNeighborAreaMeanColor = tempCount = 0;
	for (y = startY; y < endY; y += 2)
	{
		for (x = startX; x < endX; x += 2)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			areaValue = InspectionArea[tempAddress];

			if (areaValue == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
			{
				edgeNeighborAreaMeanColor += ColorSourceImage[tempAddress * 3 + selectedRGB];
				tempCount++;
			}
		}
	}

	if (tempCount)
	{
		edgeNeighborAreaMeanColor /= tempCount;
	}
	else
	{
		edgeNeighborAreaMeanColor = MeanOneColor;
	}

	for (m = 0; m < 11; m++)
	{
		thresholdForEaceArea[m] = 15;
		if (m == NORMAL_INPECTION_AREA)
			thresholdForEaceArea[m] = SIDE_NORMAL_AREA_THRESH + alpha;
		if (m == NORMAL_INPECTION_AREA2)
			thresholdForEaceArea[m] = SIDE_NORMAL_AREA_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR)
			thresholdForEaceArea[m] = SIDE_EDGE_LONG_NEIGHBOR_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR)
			thresholdForEaceArea[m] = SIDE_EDGE_SHORT_NEIGHBOR_THRESH + alpha;
		if (m == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
			thresholdForEaceArea[m] = SIDE_EDGE_DARK_THRESH + (TabletGradeData.Side_Edge_Neighbor_Intensity - 1) * 2;
		if (m == SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA)
			thresholdForEaceArea[m] = SIDE_NORMAL_AREA_THRESH + alpha;

		if (m == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
		{
			thresholdForEaceArea[m] = thresholdForEaceArea[m] * edgeNeighborAreaMeanColor / 128;
		}
		else
		{
			thresholdForEaceArea[m] = thresholdForEaceArea[m] * MeanOneColor / 128;
		}
	}

	darkSpotThreshold = (SIDE_DIRTY_THRESH + (TabletGradeData.side_dirty_Intensity - 1) * 2) * MeanOneColor / 128;

	for (m = 0; m < 11; m++)
	{
		thresholdForEaceAreaBright[m] = 18;
		if (m == NORMAL_INPECTION_AREA)
			thresholdForEaceAreaBright[m] = SIDE_NORMAL_AREA_BRIGHT_THRESH + alpha;
		if (m == NORMAL_INPECTION_AREA2)
			thresholdForEaceAreaBright[m] = SIDE_NORMAL_AREA_BRIGHT_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR)
			thresholdForEaceAreaBright[m] = SIDE_BOTTOM_EDGE_BRIGHT_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR)
			thresholdForEaceAreaBright[m] = SIDE_BOTTOM_EDGE_BRIGHT_THRESH + alpha;

		thresholdForEaceAreaBright[m] = thresholdForEaceAreaBright[m] * MeanOneColor / 128;
	}

	for (m = 0; m < 11; m++)
	{
		for (n = 0; n < 11; n++)
			compareAcceptArea[m][n] = 0;

		compareAcceptArea[NORMAL_INPECTION_AREA][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[NORMAL_INPECTION_AREA2][NORMAL_INPECTION_AREA2] = 1;

		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR] = 1;

		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR] = 1;

		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR] = 1;
		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][NORMAL_INPECTION_AREA2] = 1;

		compareAcceptArea[SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA][SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA][NORMAL_INPECTION_AREA2] = 1;
	}

	tempOneColorImage = MeanOneColorImage;

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;
			if (InspectionArea[tempAddress] == NORMAL_INPECTION_AREA)
			{
				tempSum = 0;
				for (i = y - 1; i <= y + 1; i++)
				{
					for (j = x - 1; j <= x + 1; j++)
					{
						tempSum += tempOneColorImage[i * MAX_IMAGE_WIDTH + j];
					}
				}
				TempImage[tempAddress] = tempSum / 9;
			}
		}
	}

	memset(colorMaskingArea, 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;
			areaValue = InspectionArea[tempAddress];

			maxColorDiff = maxColorDiff2 = 0;
			if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
			{
				selfPositionValue[0] = ColorSourceImage[tempAddress * 3 + 0];
				selfPositionValue[1] = ColorSourceImage[tempAddress * 3 + 1];
				selfPositionValue[2] = ColorSourceImage[tempAddress * 3 + 2];
				selfPositionValue[3] = tempOneColorImage[tempAddress];

				selfPositionValueBright = TempImage[tempAddress];
				brightDefectCheckSW = 0;
				darkDefectCheckSW = 0;
				darkSpotCheckSW = 0;
				topSW = bottomSW = leftSW = rightSW = topleftSW = toprightSW = bottomleftSW = bottomrightSW = 0;

				tempCount = 0;
				thresholdDark = thresholdForEaceArea[areaValue];
				thresholdBright = thresholdForEaceAreaBright[areaValue];
				for (r = 6; r >= 2; r -= 2)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (topSW == 0)
							{
								darkSpotCheckSW++;
								topSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (bottomSW == 0)
							{
								darkSpotCheckSW++;
								bottomSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (leftSW == 0)
							{
								darkSpotCheckSW++;
								leftSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (rightSW == 0)
							{
								darkSpotCheckSW++;
								rightSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (bottomrightSW == 0)
							{
								darkSpotCheckSW++;
								bottomrightSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (topleftSW == 0)
							{
								darkSpotCheckSW++;
								topleftSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (bottomleftSW == 0)
							{
								darkSpotCheckSW++;
								bottomleftSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						brightDefectColorDiff = TempImage[tempAddress2] - selfPositionValueBright;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (toprightSW == 0)
							{
								darkSpotCheckSW++;
								toprightSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					if (tempCount >= 3)
					{
						if (darkSpotCheckSW >= 7)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = x;
								defectPointData[defectPointDataCnt * 3 + 1] = y;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff2;
								defectPointDataCnt++;
							}

							colorMaskingArea[tempAddress] = 1;
							break;
						}
						else if (darkDefectCheckSW >= 3)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = x;
								defectPointData[defectPointDataCnt * 3 + 1] = y;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;
							}

							colorMaskingArea[tempAddress] = 1;
							break;
						}
						else if (brightDefectCheckSW >= 3)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = x;
								defectPointData[defectPointDataCnt * 3 + 1] = y;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;
							}

							colorMaskingArea[tempAddress] = 1;
							break;
						}
						if (r == 2)
							break;
					}
				}
			}
			else if (areaValue == SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR || areaValue == SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR)
			{
				selfPositionValue[0] = ColorSourceImage[tempAddress * 3 + 0];
				selfPositionValue[1] = ColorSourceImage[tempAddress * 3 + 1];
				selfPositionValue[2] = ColorSourceImage[tempAddress * 3 + 2];
				selfPositionValue[3] = tempOneColorImage[tempAddress];

				brightDefectCheckSW = 0;
				darkDefectCheckSW = 0;
				tempCount = 0;
				thresholdDark = thresholdForEaceArea[areaValue];
				thresholdBright = thresholdForEaceAreaBright[areaValue];
				for (r = 4; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;

						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;

							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					if (tempCount >= 2)
					{
						if (darkDefectCheckSW >= 2)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = x;
								defectPointData[defectPointDataCnt * 3 + 1] = y;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;
							}

							colorMaskingArea[tempAddress] = 1;
							break;
						}
						else if (brightDefectCheckSW >= 3)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = x;
								defectPointData[defectPointDataCnt * 3 + 1] = y;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;
							}

							colorMaskingArea[tempAddress] = 1;
							break;
						}
						if (r == 2)
							break;
					}
				}
			}
			else if (areaValue == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
			{
				selfPositionValue[0] = ColorSourceImage[tempAddress * 3 + 0];
				selfPositionValue[1] = ColorSourceImage[tempAddress * 3 + 1];
				selfPositionValue[2] = ColorSourceImage[tempAddress * 3 + 2];

				darkDefectCheckSW = 0;
				topSW = 0;
				bottomSW = 0;
				leftSW = 0;
				rightSW = 0;
				expectedDefect = 0;

				// 측면 모서리의 경우 어두워진 불량만 체크
				thresholdDark = thresholdForEaceArea[areaValue];

				for (r = 12; r >= 2; r -= 2)
				{
					tempY = y + r;
					tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

					tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > 4) // 정제 상단부분이 아래방향보다 어둡다면 불량일 가능성이 높다
						{
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;

							bottomSW = 1;
							break;
						}
					}
				}

				if (bottomSW)
				{
					for (r = 12; r >= 2; r -= 2)
					{
						tempY = y - r;
						tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

						tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;
						if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
						{
							if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
							{
								darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
							}
							else
							{
								colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
								colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
								colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

								darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
							}

							if (darkDefectColorDiff > thresholdDark)
							{
								if (maxColorDiff < darkDefectColorDiff)
									maxColorDiff = darkDefectColorDiff;

								topSW = 1;
								break;
							}
						}
					}

					if (topSW)
						expectedDefect = 1;
				}

				if (!expectedDefect)
				{
					for (r = 12; r >= 2; r -= 2)
					{
						tempAddress2 = tempAddress - r;
						if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
						{
							if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
							{
								darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
							}
							else
							{
								colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
								colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
								colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

								darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
							}

							if (darkDefectColorDiff > thresholdDark)
							{
								if (maxColorDiff < darkDefectColorDiff)
									maxColorDiff = darkDefectColorDiff;

								leftSW = 1;
								break;
							}
						}
					}

					if (leftSW)
					{
						for (r = 12; r >= 2; r -= 2)
						{
							tempAddress2 = tempAddress + r;
							if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
							{
								if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
								{
									darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
								}
								else
								{
									colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
									colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
									colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

									darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
								}

								if (darkDefectColorDiff > thresholdDark)
								{
									if (maxColorDiff < darkDefectColorDiff)
										maxColorDiff = darkDefectColorDiff;

									rightSW = 1;
									break;
								}
							}
						}
					}

					if (rightSW)
						expectedDefect = 1;
				}

				if (expectedDefect)
				{
					breakSW = 0;
					darkDefectCheckSW = 0;
					for (tempY = y; tempY <= y + 12; tempY += 4)
					{
						for (tempX = x - 12; tempX <= x + 12; tempX += 4)
						{
							tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;
							if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
							{
								if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
								{
									darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
								}
								else
								{
									colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
									colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
									colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

									darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
								}

								if (darkDefectColorDiff > thresholdDark)
								{
									if (maxColorDiff < darkDefectColorDiff)
										maxColorDiff = darkDefectColorDiff;

									darkDefectCheckSW++;
								}
							}

							if (darkDefectCheckSW >= 5)
							{
								if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
								{
									defectPointData[defectPointDataCnt * 3 + 0] = x;
									defectPointData[defectPointDataCnt * 3 + 1] = y;
									defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
									defectPointDataCnt++;
								}

								colorMaskingArea[tempAddress] = 1;

								breakSW = 1;
								break;
							}
						}

						if (breakSW)
							break;
					}

					/*
					for (r = 12; r >= 4; r -= 4)
					{
					tempAddress2 = tempAddress - r;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
					if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
					{
					darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
					}
					else
					{
					colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
					colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
					colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

					darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
					}

					if (darkDefectColorDiff > thresholdDark)
					{
					if (maxColorDiff < darkDefectColorDiff)
					maxColorDiff = darkDefectColorDiff;

					darkDefectCheckSW++;
					}
					}
					tempAddress2 = tempAddress + r;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
					if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
					{
					darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
					}
					else
					{
					colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
					colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
					colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

					darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
					}

					if (darkDefectColorDiff > thresholdDark)
					{
					if (maxColorDiff < darkDefectColorDiff)
					maxColorDiff = darkDefectColorDiff;

					darkDefectCheckSW++;
					}
					}

					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
					if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
					{
					darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
					}
					else
					{
					colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
					colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
					colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

					darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
					}

					if (darkDefectColorDiff > thresholdDark)
					{
					if (maxColorDiff < darkDefectColorDiff)
					maxColorDiff = darkDefectColorDiff;

					darkDefectCheckSW++;
					}
					}

					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
					if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
					{
					darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
					}
					else
					{
					colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
					colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
					colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

					darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
					}

					if (darkDefectColorDiff > thresholdDark)
					{
					if (maxColorDiff < darkDefectColorDiff)
					maxColorDiff = darkDefectColorDiff;

					darkDefectCheckSW++;
					}
					}

					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
					if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
					{
					darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
					}
					else
					{
					colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
					colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
					colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

					darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
					}

					if (darkDefectColorDiff > thresholdDark)
					{
					if (maxColorDiff < darkDefectColorDiff)
					maxColorDiff = darkDefectColorDiff;

					darkDefectCheckSW++;
					}
					}

					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
					if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
					{
					darkDefectColorDiff = tempOneColorImage[tempAddress2] - selfPositionValue[3];
					}
					else
					{
					colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
					colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
					colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

					darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
					}

					if (darkDefectColorDiff > thresholdDark)
					{
					if (maxColorDiff < darkDefectColorDiff)
					maxColorDiff = darkDefectColorDiff;

					darkDefectCheckSW++;
					}
					}

					if (darkDefectCheckSW >= 5)
					{
					if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
					{
					defectPointData[defectPointDataCnt * 3 + 0] = x;
					defectPointData[defectPointDataCnt * 3 + 1] = y;
					defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
					defectPointDataCnt++;
					}

					colorMaskingArea[tempAddress] = 1;
					break;
					}
					}
					*/
				}
			}
			else if (areaValue == SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA)
			{
				selfPositionValue[0] = ColorSourceImage[tempAddress * 3 + 0];
				selfPositionValue[1] = ColorSourceImage[tempAddress * 3 + 1];
				selfPositionValue[2] = ColorSourceImage[tempAddress * 3 + 2];

				darkDefectCheckSW = 0;
				tempCount = 0;

				// 다층정 경계 영역의 경우 어두워진 불량만 체크
				thresholdDark = thresholdForEaceArea[areaValue];
				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;
						colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
						colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
						colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

						darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;
						colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
						colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
						colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

						darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;
						colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
						colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
						colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

						darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;
						colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
						colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
						colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

						darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;
						colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
						colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
						colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

						darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[tempAddress2]])
					{
						tempCount++;
						colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
						colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
						colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

						darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;

							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				if (darkDefectCheckSW == 6)
				{
					if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
					{
						defectPointData[defectPointDataCnt * 3 + 0] = x;
						defectPointData[defectPointDataCnt * 3 + 1] = y;
						defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
						defectPointDataCnt++;
					}

					colorMaskingArea[tempAddress] = 1;
					break;
				}
			}
		}
	}

	if (TabletGradeData.ETC_ApplyColorDirtyIgnoreAlgorithm && TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
	{
		interestedColor = TabletGradeData.ETC_InterestedColor;

		if (interestedColor == 0)
		{
			notInterestedColor[0] = 1;
			notInterestedColor[1] = 2;
		}
		else if (interestedColor == 1)
		{
			notInterestedColor[0] = 0;
			notInterestedColor[1] = 2;
		}
		else if (interestedColor == 2)
		{
			notInterestedColor[0] = 0;
			notInterestedColor[1] = 1;
		}

		candidateDefectPoint = PlanariztionThreeDEdgeImage;
		memcpy(candidateDefectPoint, colorMaskingArea, 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 (colorMaskingArea[tempAddress])
				{
					colorValue[interestedColor] = ColorSourceImage[tempAddress * 3 + interestedColor];
					colorValue[notInterestedColor[0]] = ColorSourceImage[tempAddress * 3 + notInterestedColor[0]];
					colorValue[notInterestedColor[1]] = ColorSourceImage[tempAddress * 3 + notInterestedColor[1]];

					if (!(colorValue[interestedColor] > colorValue[notInterestedColor[0]] + TabletGradeData.ETC_ColorDirtyIgnoreLevel &&
						  colorValue[interestedColor] > colorValue[notInterestedColor[1]] + TabletGradeData.ETC_ColorDirtyIgnoreLevel))
					{
						colorMaskingArea[tempAddress] = 0;
					}
				}
			}
		}

		memset(colorDefectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
		colorDefectPointDataCnt = 0;

		// 크기 제한을 둠. 색 반점이 사용자 설정 기준 크기보다 큰경우에는 불량으로 처리 할 것(콜마)
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (colorMaskingArea[tempAddress] && colorDefectPointDataCnt < MAX_DEFECT_POINT_COUNT)
				{
					colorDefectPointData[colorDefectPointDataCnt * 3 + 0] = x;
					colorDefectPointData[colorDefectPointDataCnt * 3 + 1] = y;
					colorDefectPointData[colorDefectPointDataCnt * 3 + 2] = 1;
					colorDefectPointDataCnt++;
				}
			}
		}

		defectGroupN = ColorDotLabeling(label_Image, colorDefectPointData, colorDefectPointDataCnt, cameraIndex);

		tMax = 1;
		maxPixelDefectLabelN = -1;

		for (m = 1; m <= defectGroupN; m++)
		{
			if (Pixel_N_Of_Label[m] > tMax)
			{
				tMax = Pixel_N_Of_Label[m];
				maxPixelDefectLabelN = m;
			}
		}
		if (maxPixelDefectLabelN > 0)
		{
			if (Pixel_N_Of_Label[maxPixelDefectLabelN] > TabletGradeData.ETC_ColorDirtySize)
			{
				DefectSW = 1;
				DefectInformationWrite(DEFECT_SIDE_COLOR_LARGE_DIRTY, cameraIndex, StartX_Label[maxPixelDefectLabelN],
									   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);
			}
		}

		if (!DefectSW)
		{
			defectGroupN = 0;

			tMax = 1;
			maxPixelDefectLabelN = -1;

			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (colorMaskingArea[tempAddress])
					{
						for (i = y - 2; i <= y + 2; i++)
						{
							for (j = x - 2; j <= x + 2; j++)
							{
								if (j > 0 && j < MAX_IMAGE_WIDTH && i > 0 && i < MAX_IMAGE_HEIGHT)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * i + j;
									tempMaskBuf[tempAddress2] = 1;
								}
							}
						}
					}
				}
			}

#ifdef PC_SIM
			memcpy(colorMaskingArea, tempMaskBuf, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif

			memcpy(DefectPointDataForRearrange, defectPointData, MAX_DEFECT_POINT_COUNT * 3 * 2);
			DefectPointDataCntForRearrange = defectPointDataCnt;

			memset(defectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
			defectPointDataCnt = 0;

			for (m = 0; m < DefectPointDataCntForRearrange; m++)
			{
				x = DefectPointDataForRearrange[m * 3 + 0];
				y = DefectPointDataForRearrange[m * 3 + 1];

				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (candidateDefectPoint[tempAddress] && !tempMaskBuf[tempAddress] && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
				{
					defectPointData[defectPointDataCnt * 3 + 0] = x;
					defectPointData[defectPointDataCnt * 3 + 1] = y;
					defectPointData[defectPointDataCnt * 3 + 2] = DefectPointDataForRearrange[m * 3 + 2];
					defectPointDataCnt++;
				}
			}
		}
	}

	cornerDarkDefectThreshold = SIDE_EDGE_DARK_THRESH + (TabletGradeData.Side_Edge_Dark_Intensity - 1) * 2;
	cornerDarkDefectSize = TabletGradeData.Side_Edge_Dark_Defect_Size;

	// edge dark
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			areaValue = InspectionArea[tempAddress];
			if (areaValue == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
			{
				selfPositionValue[0] = ColorSourceImage[tempAddress * 3 + 0];
				selfPositionValue[1] = ColorSourceImage[tempAddress * 3 + 1];
				selfPositionValue[2] = ColorSourceImage[tempAddress * 3 + 2];

				maxColorDiff = 0;

				topSW = 0;
				for (r = 12; r >= 2; r -= 2)
				{
					tempY = y - r;
					tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

					tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;
					if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
					{
						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > cornerDarkDefectThreshold)
						{
							topSW = 1;
							break;
						}
					}
				}
				if (!topSW)
					continue;

				bottomSW = 0;
				for (r = 12; r >= 2; r -= 2)
				{
					tempY = y + r;
					tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

					tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;

					if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
					{
						if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
						{
							darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
							colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
							colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

							darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
						}

						if (darkDefectColorDiff > 4) // 아래방향 기준보다 어둡다면 불량일 가능성이 높다
						{
							bottomSW = 1;
							break;
						}
					}
				}
				if (!bottomSW)
					continue;

				breakSW = 0;
				darkDefectCheckSW = 0;
				for (tempY = y; tempY <= y + 12; tempY += 4)
				{
					for (tempX = x - 12; tempX <= x + 12; tempX += 4)
					{
						tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;
						if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
						{
							if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
							{
								darkDefectColorDiff = ColorSourceImage[tempAddress2 * 3 + selectedRGB] - selfPositionValue[selectedRGB];
							}
							else
							{
								colorDiff[0] = ColorSourceImage[tempAddress2 * 3 + 0] - selfPositionValue[0];
								colorDiff[1] = ColorSourceImage[tempAddress2 * 3 + 1] - selfPositionValue[1];
								colorDiff[2] = ColorSourceImage[tempAddress2 * 3 + 2] - selfPositionValue[2];

								darkDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
							}

							if (darkDefectColorDiff > cornerDarkDefectThreshold)
							{
								darkDefectCheckSW++;

								if (maxColorDiff < darkDefectColorDiff)
									maxColorDiff = darkDefectColorDiff;
							}
						}

						if (darkDefectCheckSW >= 5)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = x;
								defectPointData[defectPointDataCnt * 3 + 1] = y;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;
							}

							breakSW = 1;
							break;
						}
					}

					if (breakSW)
						break;
				}
			}
		}
	}

	if (ProcessingModeGlobal == INSPECTION_MODE && DefectSW == 0)
	{
		DefectSearchSW = 0;

		defectGroupN = DefectLabeling(label_Image, defectPointData, defectPointDataCnt, cameraIndex);

		if (TabletCharacter.tabletDivisionLineInfo != NONE_DIVISION_LINE)
		{
			if (TabletGradeData.ETC_Side_Split_Line_UnInspection_Area_Setting)
			{
				remakeInspectionArea = SideFaceSplitLineMask(cameraIndex);

				// 불량 재검증
				if (remakeInspectionArea)
				{
					for (y = startY; y < endY; y++)
					{
						for (x = startX; x < endX; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							areaValue = InspectionArea[tempAddress];

							if (areaValue == SIDE_SHAPE_UNINSPECTION_AREA)
							{
								if (label_Image[tempAddress])
								{
									tempLabelN = label_Image[tempAddress];
									label_Image[tempAddress] = 0;

									if (PixelNInShapeEdgeNeighbor[tempLabelN] > 0)
									{
										PixelNInShapeEdgeNeighbor[tempLabelN]--;
									}

									if (PixelNInShapeSideEdge[tempLabelN] > 0)
									{
										PixelNInShapeSideEdge[tempLabelN]--;
									}

									if (Pixel_N_Of_Label[tempLabelN] > 0)
									{
										Pixel_N_Of_Label[tempLabelN]--;
									}
								}
							}
						}
					}
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 두개 이상의 영역에 분포해 있는 경우에 대한 처리
			// 일반 영역 불량 처리
			DefectSearchSW = 1;
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideNormal[m] > tMax)
				{
					tMax = PixelNInShapeSideNormal[m];
					maxPixelDefectLabelN = m;
				}
			}
			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideNormal[maxPixelDefectLabelN] * 100 / (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]) > 50)
				{
					// 라벨의 50% 이상이 일반영역에 분포하고있다면
					if (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > TabletGradeData.side_stain_Size)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_STAIN, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
				else
				{
					// 라벨의 50% 이상이 모서리 영역에 분포하고 있다면
					if (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > cornerDarkDefectSize)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_DARK, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 두개 이상의 영역에 분포해 있는 경우에 대한 처리
			// 모서리 주변 영역 불량 처리
			DefectSearchSW = 1;
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeEdgeNeighbor[m] > tMax)
				{
					tMax = PixelNInShapeEdgeNeighbor[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] * 100 / (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]) > 50)
				{
					// 라벨의 50% 이상이 모서리 주변영역에 분포하고 있다면
					if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > TabletGradeData.Side_Edge_Neighbor_Defect_Size)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_NEIGHBOR, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
				else
				{
					// 라벨의 50% 이상이 모서리 영역에 분포하고 있다면
					if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > cornerDarkDefectSize)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_DARK, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 한개 영역에 분포해 있는 경우에 대한 처리
			// 모서리 영역 불량 처리
			DefectSearchSW = 1;
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideEdge[m] > tMax)
				{
					tMax = PixelNInShapeSideEdge[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideEdge[maxPixelDefectLabelN] > cornerDarkDefectSize)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_EDGE_DARK, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideEdge[maxPixelDefectLabelN]);
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 한개 영역에 분포해 있는 경우에 대한 처리
			// 모서리 주변 영역 불량 처리
			DefectSearchSW = 1;
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeEdgeNeighbor[m] > tMax)
				{
					tMax = PixelNInShapeEdgeNeighbor[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] > TabletGradeData.Side_Edge_Neighbor_Defect_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_EDGE_NEIGHBOR, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN]);
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 한개 영역에 분포해 있는 경우에 대한 처리
			// 일반 영역 흐린 얼룩 처리
			DefectSearchSW = 1;
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideNormal[m] > tMax)
				{
					tMax = PixelNInShapeSideNormal[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideNormal[maxPixelDefectLabelN] > TabletGradeData.side_stain_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_STAIN, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN]);
				}
			}
		}

		if (DefectSW == 0)
		{
			// 일반 영역 짙은 이물류 처리
			DefectSearchSW = 1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (Pixel_N_Of_MoreDarkOfLabel[m] > TabletGradeData.side_dirty_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_DIRTY, cameraIndex, StartX_Label[m],
										   EndX_Label[m], StartY_Label[m], EndY_Label[m], Pixel_N_Of_MoreDarkOfLabel[m]);

					maxPixelDefectLabelN = m;
					break;
				}
			}
		}

		if (DefectSearchSW)
		{
#ifdef PC_SIM
			if (DefectSW)
			{
				for (y = startY; y < endY; y++)
				{
					for (x = startX; x < endX; x++)
					{
						tempAddress = MAX_IMAGE_WIDTH * y + x;

						if (label_Image[tempAddress] != maxPixelDefectLabelN)
						{
							label_Image[tempAddress] = 0;
						}
					}
				}
			}
#endif
		}

		if (DefectSW == 0)
		{
			// ignoreReflectedLightForCam2는 높이가 아주 높은 정제는 2번 카메라에서 빛 반사 과검이 있을 경우 무시하는 옵션. 
			// 동화약품의 밝은 갈색의 큰 정제에서 발생한 문제로서 다른 정제에서 문제가 된다면 설정에 따라 동작 여부를 정하자.
			// 추후 카메라의 각도 등이 변한다면 불필요해질 수도 있다.
			int ignoreReflectedLightForCam2 = 0;
			if (cameraIndex == 2 && TabletCharacter.height > 180)
			{
				ignoreReflectedLightForCam2 = 1;
			}
			
			cornerBrightDefectThreshold = SIDE_NORMAL_AREA_THRESH + (TabletGradeData.Side_Edge_Bright_Intensity - 1) * 2;
			cornerBrightDefectSize = TabletGradeData.Side_Edge_Bright_Defect_Size;

			memset(brightDefectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
			brightDefectPointDataCnt = 0;
			if (DefectSW == 0)
			{
				// bright
				for (y = startY; y < endY; y++)
				{
					for (x = startX; x < endX; x++)
					{
						tempAddress = MAX_IMAGE_WIDTH * y + x;
						areaValue = InspectionArea[tempAddress];
						if (areaValue == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
						{
							selfPositionValue[0] = ColorSourceImage[tempAddress * 3 + 0];
							selfPositionValue[1] = ColorSourceImage[tempAddress * 3 + 1];
							selfPositionValue[2] = ColorSourceImage[tempAddress * 3 + 2];

							maxColorDiff = 0;

							topSW = 0;
							for (r = 12; r >= 2; r -= 2)
							{
								tempY = y - r;
								tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

								tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;

								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										topSW = 1;
										break;
									}
								}
							}
							if (!topSW)
								continue;

							bottomSW = 0;
							for (r = 12; r >= 2; r -= 2)
							{
								tempY = y - r;
								tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

								tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;

								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										bottomSW = 1;
										break;
									}
								}
							}
							if (!bottomSW)
								continue;

							brightDefectCheckSW = 0;
							for (r = 12; r >= 2; r -= 2)
							{
								tempAddress2 = tempAddress - r;
								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress + r;
								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress - r - r * MAX_IMAGE_WIDTH;
								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress - r + r * MAX_IMAGE_WIDTH;
								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress + r - r * MAX_IMAGE_WIDTH;
								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress + r + r * MAX_IMAGE_WIDTH;
								if (InspectionArea[tempAddress2] && InspectionArea[tempAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (TabletGradeData.DirtyGradeSensitivity == GRADE_SENSITIVITY_NORMAL)
									{
										brightDefectColorDiff = selfPositionValue[selectedRGB] - ColorSourceImage[tempAddress2 * 3 + selectedRGB];
									}
									else
									{
										colorDiff[0] = selfPositionValue[0] - ColorSourceImage[tempAddress2 * 3 + 0];
										colorDiff[1] = selfPositionValue[1] - ColorSourceImage[tempAddress2 * 3 + 1];
										colorDiff[2] = selfPositionValue[2] - ColorSourceImage[tempAddress2 * 3 + 2];

										brightDefectColorDiff = max(colorDiff[0], max(colorDiff[1], colorDiff[2]));
									}

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								if (brightDefectCheckSW >= 5)
								{
									if (ignoreReflectedLightForCam2 == 1) // 2번 카메라의 빛 반사 과검 줄이는 로직을 사용하는지 여부.
									{
										// 에지 끝 부분에서 빛 반사에 의한 과검을 막기 위해서 좀더 판정 기준을 높임.
										if (x > TabletSlopeInfoStartPoint[0] - 10 && maxColorDiff < cornerBrightDefectThreshold + 20)
										{
											break;
										}
									}
									
									if (brightDefectPointDataCnt < MAX_DEFECT_POINT_COUNT)
									{
										brightDefectPointData[brightDefectPointDataCnt * 3] = x;
										brightDefectPointData[brightDefectPointDataCnt * 3 + 1] = y;
										brightDefectPointData[brightDefectPointDataCnt * 3 + 2] = maxColorDiff;
										brightDefectPointDataCnt++;
									}
									break;
								}
							}
						}
					}
				}

				defectGroupN = DefectLabeling(label_Image, brightDefectPointData, brightDefectPointDataCnt, cameraIndex);
				tMax = 1;
				maxPixelDefectLabelN = -1;
				for (m = 1; m <= defectGroupN; m++)
				{
					if (Pixel_N_Of_Label[m] > tMax)
					{
						tMax = Pixel_N_Of_Label[m];
						maxPixelDefectLabelN = m;
					}
				}

				if (maxPixelDefectLabelN > 0)
				{
					if (Pixel_N_Of_Label[maxPixelDefectLabelN] > cornerBrightDefectSize)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_BRIGHT, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);
					}
				}

				if (DefectSW == 1 && DefectInformation.defectSeries == DEFECT_SIDE_EDGE_BRIGHT)
				{
					if (TabletCharacter.tabletDivisionLineInfo != NONE_DIVISION_LINE)
					{
						if (TabletGradeData.ETC_Side_Split_Line_UnInspection_Area_Setting)
						{
							// 불량 재검증
							if (remakeInspectionArea)
							{
								DefectSW = 0;
								for (y = startY; y < endY; y++)
								{
									for (x = startX; x < endX; x++)
									{
										tempAddress = MAX_IMAGE_WIDTH * y + x;

										areaValue = InspectionArea[tempAddress];

										if (areaValue == SIDE_SHAPE_UNINSPECTION_AREA)
										{
											if (label_Image[tempAddress])
											{
												tempLabelN = label_Image[tempAddress];
												label_Image[tempAddress] = 0;

												if (Pixel_N_Of_Label[tempLabelN] > 0)
												{
													Pixel_N_Of_Label[tempLabelN]--;
												}
											}
										}
									}
								}

								tMax = 1;
								maxPixelDefectLabelN = -1;
								for (m = 1; m <= defectGroupN; m++)
								{
									if (Pixel_N_Of_Label[m] > tMax)
									{
										tMax = Pixel_N_Of_Label[m];
										maxPixelDefectLabelN = m;
									}
								}

								if (maxPixelDefectLabelN > 0)
								{
									if (Pixel_N_Of_Label[maxPixelDefectLabelN] > cornerBrightDefectSize)
									{
										DefectSW = 1;
										DefectInformationWrite(DEFECT_SIDE_EDGE_BRIGHT, cameraIndex, StartX_Label[maxPixelDefectLabelN],
															   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);
									}
								}
							}
						}
					}
				}
			}
		}
	}

#ifdef PC_SIM
	memcpy(LabelImage_Virtual, label_Image, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
}
//---------------------------------------------------------------------------
void HighResolutionDefectSearchForSideShape(int cameraIndex)
{
	int startX, endX, startY, endY;
	int areaValue;
	int selfPositionValue;
	int x, y, m, r, i, j, n;

	short defectPointData[MAX_DEFECT_POINT_COUNT * 3];
	int defectPointDataCnt;
	short brightDefectPointData[MAX_DEFECT_POINT_COUNT * 3];
	int brightDefectPointDataCnt;

	int tempAddress;
	int tempAddress2;
	int defectGroupN;

	int brightDefectCheckSW;
	int darkSpotCheckSW;
	int darkDefectCheckSW;
	int tempCount;

	int alpha;
	int thresholdDark;
	int compareAcceptArea[11][11];
	int thresholdForEaceArea[11];
	int thresholdForEaceAreaBright[11];
	int thresholdBright;
	int tMax;
	int maxPixelDefectLabelN;
	int tempSum;

	int selfPositionValueBright;
	short *label_Image;

	int cornerDarkDefectThreshold;
	int cornerDarkDefectSize;
	int cornerBrightDefectThreshold;
	int cornerBrightDefectSize;
	int maxColorDiff;
	int maxColorDiff2;

	int tempLabelN;
	int remakeInspectionArea;
	int tempImageWidth;
	int smallSizeAddress;
	int smallSizeAddress2;
	int expectedDefect;
	int edgeNeighborAreaMeanColor;

	int darkDefectColorDiff;
	int brightDefectColorDiff;
	int tempX, tempY;
	int breakSW;
	int darkSpotThreshold;
	int topSW, bottomSW, leftSW, rightSW, topleftSW, toprightSW, bottomleftSW, bottomrightSW;

	label_Image = RotationEdgeImage;

	tempImageWidth = HD_IMAGE_WIDTH;

	memset(defectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
	defectPointDataCnt = 0;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	alpha = TabletGradeData.side_stain_Intensity * 2;

	edgeNeighborAreaMeanColor = tempCount = 0;
	for (y = startY; y < endY; y += 2)
	{
		for (x = startX; x < endX; x += 2)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			areaValue = InspectionArea[tempAddress];

			if (areaValue == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
			{
				edgeNeighborAreaMeanColor += ColorSourceImage[tempAddress * 3 + selectedRGB];
				tempCount++;
			}
		}
	}

	if (tempCount)
	{
		edgeNeighborAreaMeanColor /= tempCount;
	}
	else
	{
		edgeNeighborAreaMeanColor = MeanOneColor;
	}

	for (m = 0; m < 11; m++)
	{
		thresholdForEaceArea[m] = 15;
		if (m == NORMAL_INPECTION_AREA)
			thresholdForEaceArea[m] = SIDE_NORMAL_AREA_THRESH + alpha;
		if (m == NORMAL_INPECTION_AREA2)
			thresholdForEaceArea[m] = SIDE_NORMAL_AREA_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR)
			thresholdForEaceArea[m] = SIDE_EDGE_LONG_NEIGHBOR_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR)
			thresholdForEaceArea[m] = SIDE_EDGE_SHORT_NEIGHBOR_THRESH + alpha;
		if (m == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
			thresholdForEaceArea[m] = SIDE_EDGE_DARK_THRESH + (TabletGradeData.Side_Edge_Neighbor_Intensity - 1) * 2;
		if (m == SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA)
			thresholdForEaceArea[m] = SIDE_NORMAL_AREA_THRESH + alpha;

		if (m == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
		{
			thresholdForEaceArea[m] = thresholdForEaceArea[m] * edgeNeighborAreaMeanColor / 128;
		}
		else
		{
			thresholdForEaceArea[m] = thresholdForEaceArea[m] * MeanOneColor / 128;
		}
	}

	darkSpotThreshold = (SIDE_DIRTY_THRESH + (TabletGradeData.side_dirty_Intensity - 1) * 2) * MeanOneColor / 128;

	for (m = 0; m < 11; m++)
	{
		thresholdForEaceAreaBright[m] = 18;
		if (m == NORMAL_INPECTION_AREA)
			thresholdForEaceAreaBright[m] = SIDE_NORMAL_AREA_BRIGHT_THRESH + alpha;
		if (m == NORMAL_INPECTION_AREA2)
			thresholdForEaceAreaBright[m] = SIDE_NORMAL_AREA_BRIGHT_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR)
			thresholdForEaceAreaBright[m] = SIDE_BOTTOM_EDGE_BRIGHT_THRESH + alpha;
		if (m == SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR)
			thresholdForEaceAreaBright[m] = SIDE_BOTTOM_EDGE_BRIGHT_THRESH + alpha;

		thresholdForEaceAreaBright[m] = thresholdForEaceAreaBright[m] * MeanOneColor / 128;
	}

	for (m = 0; m < 11; m++)
	{
		for (n = 0; n < 11; n++)
			compareAcceptArea[m][n] = 0;

		compareAcceptArea[NORMAL_INPECTION_AREA][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[NORMAL_INPECTION_AREA2][NORMAL_INPECTION_AREA2] = 1;

		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR] = 1;

		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR] = 1;
		compareAcceptArea[SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR][SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR] = 1;

		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR] = 1;
		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR][NORMAL_INPECTION_AREA2] = 1;

		compareAcceptArea[SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA][SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA][NORMAL_INPECTION_AREA] = 1;
		compareAcceptArea[SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA][NORMAL_INPECTION_AREA2] = 1;
	}

	memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * MAX_IMAGE_WIDTH + x;
			if (InspectionArea[tempAddress] == NORMAL_INPECTION_AREA)
			{
				tempSum = 0;
				for (i = y - 1; i <= y + 1; i++)
				{
					for (j = x - 1; j <= x + 1; j++)
					{
						tempSum += MeanOneColorImage[i * MAX_IMAGE_WIDTH + j];
					}
				}
				TempImage[tempAddress] = tempSum / 9;
			}
		}
	}

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS] * 2;
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS] * 2;
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS] * 2;
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS] * 2;

	memset(OneColorImageHighResolution, 0, HD_IMAGE_WIDTH * HD_IMAGE_HEIGHT);
	memset(LabelImageHighResolution, 0, HD_IMAGE_WIDTH * HD_IMAGE_HEIGHT * sizeof(short));

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = tempImageWidth * y + x;

			OneColorImageHighResolution[tempAddress] = tempColorSourceImage[tempAddress * 3 + selectedRGB];
		}
	}

	int xhalf, yhalf;
	for (y = startY; y < endY; ++y)
	{
		for (x = startX; x < endX; ++x)
		{
			tempAddress = tempImageWidth * y + x;
			xhalf = (x / 2);
			yhalf = (y / 2);
			smallSizeAddress = MAX_IMAGE_WIDTH * yhalf + xhalf;

			areaValue = InspectionArea[smallSizeAddress];

			maxColorDiff = maxColorDiff2 = 0;
			if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
			{
				selfPositionValue = OneColorImageHighResolution[tempAddress];
				selfPositionValueBright = TempImage[smallSizeAddress];

				brightDefectCheckSW = 0;
				darkDefectCheckSW = 0;
				darkSpotCheckSW = 0;
				topSW = bottomSW = leftSW = rightSW = topleftSW = toprightSW = bottomleftSW = bottomrightSW = 0;
				tempCount = 0;

				thresholdDark = thresholdForEaceArea[areaValue];
				thresholdBright = thresholdForEaceAreaBright[areaValue];

				for (r = 6; r >= 2; r -= 2)
				{
					tempAddress2 = tempAddress - r * 2 * tempImageWidth;
					smallSizeAddress2 = smallSizeAddress - r * MAX_IMAGE_WIDTH;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (topSW == 0)
							{
								darkSpotCheckSW++;
								topSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress + r * 2 * tempImageWidth;
					smallSizeAddress2 = smallSizeAddress + r * MAX_IMAGE_WIDTH;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (bottomSW == 0)
							{
								darkSpotCheckSW++;
								bottomSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress - r * 4;
					smallSizeAddress2 = smallSizeAddress - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (leftSW == 0)
							{
								darkSpotCheckSW++;
								leftSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress + r * 4;
					smallSizeAddress2 = smallSizeAddress + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (rightSW == 0)
							{
								darkSpotCheckSW++;
								rightSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress + r * 2 * tempImageWidth + r * 4;
					smallSizeAddress2 = smallSizeAddress + r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (bottomrightSW == 0)
							{
								darkSpotCheckSW++;
								bottomrightSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress - r * 2 * tempImageWidth - r * 4;
					smallSizeAddress2 = smallSizeAddress - r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (topleftSW == 0)
							{
								darkSpotCheckSW++;
								topleftSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress + r * 2 * tempImageWidth - r * 4;
					smallSizeAddress2 = smallSizeAddress + r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (bottomleftSW == 0)
							{
								darkSpotCheckSW++;
								bottomleftSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress - r * 2 * tempImageWidth + r * 4;
					smallSizeAddress2 = smallSizeAddress - r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						brightDefectColorDiff = TempImage[smallSizeAddress2] - selfPositionValueBright;

						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (darkDefectColorDiff > darkSpotThreshold)
						{
							if (toprightSW == 0)
							{
								darkSpotCheckSW++;
								toprightSW = 1;
							}

							if (maxColorDiff2 < darkDefectColorDiff)
								maxColorDiff2 = darkDefectColorDiff;
						}
						if (-brightDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -brightDefectColorDiff)
								maxColorDiff = -brightDefectColorDiff;
						}
					}
					if (tempCount >= 3)
					{
						if (darkSpotCheckSW >= 7)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
								defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff2;
								defectPointDataCnt++;

								LabelImageHighResolution[tempAddress] = 1;
							}
							break;
						}
						else if (darkDefectCheckSW >= 3)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
								defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;

								LabelImageHighResolution[tempAddress] = 1;
							}
							break;
						}
						else if (brightDefectCheckSW >= 3)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
								defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;

								LabelImageHighResolution[tempAddress] = 1;
							}
							break;
						}
						if (r == 1)
							break;
					}
				}
			}
			else if (areaValue == SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR || areaValue == SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR)
			{
				selfPositionValue = MeanOneColorImage[smallSizeAddress];

				brightDefectCheckSW = 0;
				darkDefectCheckSW = 0;
				tempCount = 0;

				thresholdDark = thresholdForEaceArea[areaValue];
				thresholdBright = thresholdForEaceAreaBright[areaValue];

				for (r = 4; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 4;
					smallSizeAddress2 = smallSizeAddress - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = MeanOneColorImage[smallSizeAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress + r * 4;
					smallSizeAddress2 = smallSizeAddress + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = MeanOneColorImage[smallSizeAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress + r * 2 * tempImageWidth + r * 4;
					smallSizeAddress2 = smallSizeAddress + r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = MeanOneColorImage[smallSizeAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					tempAddress2 = tempAddress - r * 2 * tempImageWidth - r * 4;
					smallSizeAddress2 = smallSizeAddress - r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = MeanOneColorImage[smallSizeAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress + r * 2 * tempImageWidth - r * 4;
					smallSizeAddress2 = smallSizeAddress + r * MAX_IMAGE_WIDTH - r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = MeanOneColorImage[smallSizeAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}

					tempAddress2 = tempAddress - r * 2 * tempImageWidth + r * 4;
					smallSizeAddress2 = smallSizeAddress - r * MAX_IMAGE_WIDTH + r * 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;

						darkDefectColorDiff = MeanOneColorImage[smallSizeAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
						}
						if (-darkDefectColorDiff > thresholdBright)
						{
							brightDefectCheckSW++;
							if (maxColorDiff < -darkDefectColorDiff)
								maxColorDiff = -darkDefectColorDiff;
						}
					}
					if (tempCount >= 2)
					{
						if (darkDefectCheckSW >= 2)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
								defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;

								LabelImageHighResolution[tempAddress] = 1;
							}
							break;
						}
						else if (brightDefectCheckSW >= 3)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
								defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;

								LabelImageHighResolution[tempAddress] = 1;
							}
							break;
						}
						if (r == 1)
							break;
					}
				}
			}
			else if (areaValue == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
			{
				selfPositionValue = OneColorImageHighResolution[tempAddress];

				darkDefectCheckSW = 0;
				topSW = 0;
				bottomSW = 0;
				leftSW = 0;
				rightSW = 0;
				expectedDefect = 0;

				maxColorDiff = 0;

				// 측면 모서리의 경우 어두워진 불량만 체크
				thresholdDark = thresholdForEaceArea[areaValue];

				for (r = 24; r >= 4; r -= 4)
				{
					tempY = y + r;
					tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

					tempAddress2 = tempImageWidth * tempY + tempX;
					smallSizeAddress2 = MAX_IMAGE_WIDTH * (tempY / 2) + tempX / 2;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						if (darkDefectColorDiff > 4) // 정제 상단부분이 아래방향보다 어둡다면 불량일 가능성이 높다
						{
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;

							bottomSW = 1;
							break;
						}
					}
				}

				if (bottomSW)
				{
					for (r = 24; r >= 4; r -= 4)
					{
						tempY = y - r;
						tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

						tempAddress2 = tempImageWidth * tempY + tempX;
						smallSizeAddress2 = MAX_IMAGE_WIDTH * (tempY / 2) + tempX / 2;
						if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
						{
							darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
							if (darkDefectColorDiff > thresholdDark) // 정제 상단부분이 아래방향보다 어둡다면 불량일 가능성이 높다
							{
								if (maxColorDiff < darkDefectColorDiff)
									maxColorDiff = darkDefectColorDiff;

								topSW = 1;
								break;
							}
						}
					}

					if (topSW)
						expectedDefect = 1;
				}

				if (!expectedDefect)
				{
					for (r = 12; r >= 2; r -= 2)
					{
						tempAddress2 = tempAddress - r * 2;
						smallSizeAddress2 = smallSizeAddress - r;
						if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
						{
							darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
							if (darkDefectColorDiff > thresholdDark)
							{
								if (maxColorDiff < darkDefectColorDiff)
									maxColorDiff = darkDefectColorDiff;

								leftSW = 1;
								break;
							}
						}
					}

					if (leftSW)
					{
						for (r = 12; r >= 2; r -= 2)
						{
							tempAddress2 = tempAddress + r * 2;
							smallSizeAddress2 = smallSizeAddress + r;
							if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
							{
								darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
								if (darkDefectColorDiff > thresholdDark)
								{
									if (maxColorDiff < darkDefectColorDiff)
										maxColorDiff = darkDefectColorDiff;

									rightSW = 1;
									break;
								}
							}
						}

						if (rightSW)
							expectedDefect = 1;
					}
				}

				if (expectedDefect)
				{
					breakSW = 0;
					darkDefectCheckSW = 0;
					int tempY2, tempX2;
					for (tempY = y, tempY2 = tempY / 2; tempY <= y + 24; tempY += 8, tempY2 += 4)
					{
						for (tempX = x - 24, tempX2 = tempX / 2; tempX <= x + 24; tempX += 8, tempX2 += 4)
						{
							tempAddress2 = tempImageWidth * tempY + tempX;
							smallSizeAddress2 = MAX_IMAGE_WIDTH * tempY2 + tempX2;
							if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
							{
								darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;

								if (darkDefectColorDiff > thresholdDark)
								{
									if (maxColorDiff < darkDefectColorDiff)
										maxColorDiff = darkDefectColorDiff;

									darkDefectCheckSW++;
								}
							}

							if (darkDefectCheckSW >= 5)
							{
								if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
								{
									defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
									defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
									defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
									defectPointDataCnt++;

									LabelImageHighResolution[tempAddress] = 1;
								}

								breakSW = 1;
								break;
							}
						}

						if (breakSW)
							break;
					}
				}
			}
			else if (areaValue == SIDE_SHAPE_MULTI_TABLET_BOUNDARY_AREA)
			{
				selfPositionValue = OneColorImageHighResolution[tempAddress];
				darkDefectCheckSW = 0;
				tempCount = 0;

				// 다층정 경계 영역 경우 어두워진 불량만 체크
				thresholdDark = thresholdForEaceArea[areaValue];
				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 8;
					smallSizeAddress2 = smallSizeAddress - r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * 8;
					smallSizeAddress2 = smallSizeAddress + r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * 2 * tempImageWidth + r * 8;
					smallSizeAddress2 = smallSizeAddress + r * MAX_IMAGE_WIDTH + r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 2 * tempImageWidth - r * 8;
					smallSizeAddress2 = smallSizeAddress - r * MAX_IMAGE_WIDTH - r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * 2 * tempImageWidth - r * 8;
					smallSizeAddress2 = smallSizeAddress + r * MAX_IMAGE_WIDTH - r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				for (r = 3; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 2 * tempImageWidth + r * 8;
					smallSizeAddress2 = smallSizeAddress - r * MAX_IMAGE_WIDTH + r * 4;
					if (compareAcceptArea[areaValue][InspectionArea[smallSizeAddress2]])
					{
						tempCount++;
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;
						if (darkDefectColorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							if (maxColorDiff < darkDefectColorDiff)
								maxColorDiff = darkDefectColorDiff;
							break;
						}
					}
				}

				if (darkDefectCheckSW == 6 && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
				{
					defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
					defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
					defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
					defectPointDataCnt++;

					LabelImageHighResolution[tempAddress] = 1;
				}
			}
		}
	}

	cornerDarkDefectThreshold = SIDE_EDGE_DARK_THRESH + (TabletGradeData.Side_Edge_Dark_Intensity - 1) * 2;
	cornerDarkDefectSize = TabletGradeData.Side_Edge_Dark_Defect_Size;

	// edge dark	
	for (y = startY; y < endY; ++y)
	{
		for (x = startX; x < endX; ++x)
		{
			tempAddress = tempImageWidth * y + x;
			xhalf = (x / 2);
			yhalf = (y / 2);
			smallSizeAddress = MAX_IMAGE_WIDTH * yhalf + xhalf;

			areaValue = InspectionArea[smallSizeAddress];
			if (areaValue == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
			{
				selfPositionValue = OneColorImageHighResolution[tempAddress];

				maxColorDiff = 0;

				topSW = 0;
				for (r = 24; r >= 4; r -= 4)
				{
					tempY = y - r;
					tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

					tempAddress2 = tempImageWidth * tempY + tempX;
					smallSizeAddress2 = MAX_IMAGE_WIDTH * (tempY / 2) + tempX / 2;
					if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
					{
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;

						if (darkDefectColorDiff > cornerDarkDefectThreshold)
						{
							topSW = 1;
							break;
						}
					}
				}
				if (!topSW)
					continue;

				bottomSW = 0;
				for (r = 24; r >= 4; r -= 4)
				{
					tempY = y + r;
					tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

					tempAddress2 = tempImageWidth * tempY + tempX;
					smallSizeAddress2 = MAX_IMAGE_WIDTH * (tempY / 2) + tempX / 2;
					if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
					{
						darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;

						if (darkDefectColorDiff > 4) // 아래방향 기준보다 어둡다면 불량일 가능성이 높다
						{
							bottomSW = 1;
							break;
						}
					}
				}
				if (!bottomSW)
					continue;

				breakSW = 0;
				darkDefectCheckSW = 0;
				int tempY2, tempX2;
				for (tempY = y, tempY2 = tempY / 2; tempY <= y + 24; tempY += 8, tempY2 += 4)
				{
					for (tempX = x - 24, tempX2 = tempX / 2; tempX <= x + 24; tempX += 8, tempX2 += 4)
					{
						tempAddress2 = tempImageWidth * tempY + tempX;
						smallSizeAddress2 = MAX_IMAGE_WIDTH * tempY2 + tempX2;
						if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
						{
							darkDefectColorDiff = OneColorImageHighResolution[tempAddress2] - selfPositionValue;

							if (darkDefectColorDiff > cornerDarkDefectThreshold)
							{
								darkDefectCheckSW++;

								if (maxColorDiff < darkDefectColorDiff)
									maxColorDiff = darkDefectColorDiff;
							}
						}

						if (darkDefectCheckSW >= 5)
						{
							if (defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
							{
								defectPointData[defectPointDataCnt * 3 + 0] = xhalf;
								defectPointData[defectPointDataCnt * 3 + 1] = yhalf;
								defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
								defectPointDataCnt++;

								LabelImageHighResolution[tempAddress] = 1;
							}

							breakSW = 1;
							break;
						}
					}

					if (breakSW)
						break;
				}
			}
		}
	}

	if (ProcessingModeGlobal == INSPECTION_MODE && DefectSW == 0)
	{
		defectGroupN = DefectLabeling(label_Image, defectPointData, defectPointDataCnt, cameraIndex);

		if (TabletCharacter.tabletDivisionLineInfo != NONE_DIVISION_LINE)
		{
			if (TabletGradeData.ETC_Side_Split_Line_UnInspection_Area_Setting)
			{
				remakeInspectionArea = SideFaceSplitLineMask(cameraIndex);

				// 불량 재검증
				if (remakeInspectionArea)
				{
					for (y = startY; y < endY; ++y)
					{
						for (x = startX; x < endX; ++x)
						{
							tempAddress = tempImageWidth * y + x;
							smallSizeAddress = MAX_IMAGE_WIDTH * (y / 2) + (x / 2);

							if (LabelImageHighResolution[tempAddress])
							{
								areaValue = InspectionArea[smallSizeAddress];

								if (areaValue == SIDE_SHAPE_UNINSPECTION_AREA)
								{
									if (label_Image[smallSizeAddress])
									{
										tempLabelN = label_Image[smallSizeAddress];
										LabelImageHighResolution[tempAddress] = 0;

										if (PixelNInShapeEdgeNeighbor[tempLabelN] > 0)
										{
											PixelNInShapeEdgeNeighbor[tempLabelN]--;
										}

										if (PixelNInShapeSideEdge[tempLabelN] > 0)
										{
											PixelNInShapeSideEdge[tempLabelN]--;
										}

										if (Pixel_N_Of_Label[tempLabelN] > 0)
										{
											Pixel_N_Of_Label[tempLabelN]--;
										}
									}
								}
							}
						}
					}
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 두개 이상의 영역에 분포해 있는 경우에 대한 처리
			// 일반 영역 불량 처리
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideNormal[m] > tMax)
				{
					tMax = PixelNInShapeSideNormal[m];
					maxPixelDefectLabelN = m;
				}
			}
			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideNormal[maxPixelDefectLabelN] * 100 / (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]) > 50)
				{
					// 라벨의 50% 이상이 일반영역에 분포하고있다면
					if (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > TabletGradeData.side_stain_Size)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_STAIN, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
				else
				{
					// 라벨의 50% 이상이 모서리 영역에 분포하고 있다면
					if (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > cornerDarkDefectSize)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_DARK, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 두개 이상의 영역에 분포해 있는 경우에 대한 처리
			// 모서리 주변 영역 불량 처리
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeEdgeNeighbor[m] > tMax)
				{
					tMax = PixelNInShapeEdgeNeighbor[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] * 100 / (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]) > 50)
				{
					// 라벨의 50% 이상이 모서리 주변영역에 분포하고 있다면
					if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > TabletGradeData.Side_Edge_Neighbor_Defect_Size)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_NEIGHBOR, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
				else
				{
					// 라벨의 50% 이상이 모서리 영역에 분포하고 있다면
					if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > cornerDarkDefectSize)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_DARK, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
					}
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 한개 영역에 분포해 있는 경우에 대한 처리
			// 모서리 영역 불량 처리
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideEdge[m] > tMax)
				{
					tMax = PixelNInShapeSideEdge[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideEdge[maxPixelDefectLabelN] > cornerDarkDefectSize)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_EDGE_DARK, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideEdge[maxPixelDefectLabelN]);
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 한개 영역에 분포해 있는 경우에 대한 처리
			// 모서리 주변 영역 불량 처리
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeEdgeNeighbor[m] > tMax)
				{
					tMax = PixelNInShapeEdgeNeighbor[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN] > TabletGradeData.Side_Edge_Neighbor_Defect_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_EDGE_NEIGHBOR, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeEdgeNeighbor[maxPixelDefectLabelN]);
				}
			}
		}

		if (DefectSW == 0)
		{
			// 불량이 한개 영역에 분포해 있는 경우에 대한 처리
			// 일반 영역 흐린 얼룩 처리
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideNormal[m] > tMax)
				{
					tMax = PixelNInShapeSideNormal[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideNormal[maxPixelDefectLabelN] > TabletGradeData.side_stain_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_STAIN, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN]);
				}
			}
		}

		if (DefectSW == 0)
		{
			// 일반 영역 짙은 이물류 처리
			for (m = 1; m <= defectGroupN; m++)
			{
				if (Pixel_N_Of_MoreDarkOfLabel[m] > TabletGradeData.side_dirty_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_DIRTY, cameraIndex, StartX_Label[m],
										   EndX_Label[m], StartY_Label[m], EndY_Label[m], Pixel_N_Of_MoreDarkOfLabel[m]);

					maxPixelDefectLabelN = m;
					break;
				}
			}
		}

		if (DefectSW == 0)
		{
			cornerBrightDefectThreshold = SIDE_NORMAL_AREA_THRESH + (TabletGradeData.Side_Edge_Bright_Intensity - 1) * 2;
			cornerBrightDefectSize = TabletGradeData.Side_Edge_Bright_Defect_Size;

			memset(brightDefectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
			brightDefectPointDataCnt = 0;
			if (DefectSW == 0)
			{
				// bright
				for (y = startY; y < endY; ++y)
				{
					for (x = startX; x < endX; ++x)
					{
						tempAddress = tempImageWidth * y + x;
						xhalf = (x / 2);
						yhalf = (y / 2);
						smallSizeAddress = MAX_IMAGE_WIDTH * yhalf + xhalf;

						areaValue = InspectionArea[smallSizeAddress];
						if (areaValue == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
						{
							selfPositionValue = OneColorImageHighResolution[tempAddress];

							maxColorDiff = 0;

							topSW = 0;
							for (r = 24; r >= 4; r -= 4)
							{
								tempY = y - r;
								tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

								tempAddress2 = tempImageWidth * tempY + tempX;
								smallSizeAddress2 = MAX_IMAGE_WIDTH * (tempY / 2) + tempX / 2;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										topSW = 1;
										break;
									}
								}
							}
							if (!topSW)
								continue;

							bottomSW = 0;
							for (r = 24; r >= 4; r -= 4)
							{
								tempY = y - r;
								tempX = (TabletSlopeInfoStartPoint[0] - TabletSlopeInfoEndPoint[0]) * (tempY - y) / (TabletSlopeInfoStartPoint[1] - TabletSlopeInfoEndPoint[1]) + x;

								tempAddress2 = tempImageWidth * tempY + tempX;
								smallSizeAddress2 = MAX_IMAGE_WIDTH * (tempY / 2) + tempX / 2;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										bottomSW = 1;
										break;
									}
								}
							}
							if (!bottomSW)
								continue;

							brightDefectCheckSW = 0;
							for (r = 12; r >= 2; r -= 2)
							{
								tempAddress2 = tempAddress - r * 2;
								smallSizeAddress2 = smallSizeAddress - r;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress + r * 2;
								smallSizeAddress2 = smallSizeAddress + r;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress - r * 2 - r * 2 * tempImageWidth;
								smallSizeAddress2 = smallSizeAddress - r - r * MAX_IMAGE_WIDTH;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress - r * 2 + r * 2 * tempImageWidth;
								smallSizeAddress2 = smallSizeAddress - r + r * MAX_IMAGE_WIDTH;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress + r * 2 - r * 2 * tempImageWidth;
								smallSizeAddress2 = smallSizeAddress + r - r * MAX_IMAGE_WIDTH;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								tempAddress2 = tempAddress + r * 2 + r * 2 * tempImageWidth;
								smallSizeAddress2 = smallSizeAddress + r + r * MAX_IMAGE_WIDTH;
								if (InspectionArea[smallSizeAddress2] && InspectionArea[smallSizeAddress2] != SIDE_SHAPE_UNINSPECTION_AREA)
								{
									brightDefectColorDiff = selfPositionValue - OneColorImageHighResolution[tempAddress2];

									if (brightDefectColorDiff > cornerBrightDefectThreshold)
									{
										brightDefectCheckSW++;

										if (maxColorDiff < brightDefectColorDiff)
											maxColorDiff = brightDefectColorDiff;
									}
								}

								if (brightDefectCheckSW >= 5)
								{
									if (brightDefectPointDataCnt < MAX_DEFECT_POINT_COUNT)
									{
										brightDefectPointData[brightDefectPointDataCnt * 3 + 0] = xhalf;
										brightDefectPointData[brightDefectPointDataCnt * 3 + 1] = yhalf;
										brightDefectPointData[brightDefectPointDataCnt * 3 + 2] = maxColorDiff;
										brightDefectPointDataCnt++;

										LabelImageHighResolution[tempAddress] = 1;
									}
									break;
								}
							}
						}
					}
				}

				defectGroupN = DefectLabeling(label_Image, brightDefectPointData, brightDefectPointDataCnt, cameraIndex);
				tMax = 1;
				maxPixelDefectLabelN = -1;
				for (m = 1; m <= defectGroupN; m++)
				{
					if (Pixel_N_Of_Label[m] > tMax)
					{
						tMax = Pixel_N_Of_Label[m];
						maxPixelDefectLabelN = m;
					}
				}

				if (maxPixelDefectLabelN > 0)
				{
					if (Pixel_N_Of_Label[maxPixelDefectLabelN] > cornerBrightDefectSize)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_EDGE_BRIGHT, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);
					}
				}

				if (DefectSW == 1 && DefectInformation.defectSeries == DEFECT_SIDE_EDGE_BRIGHT)
				{
					if (TabletCharacter.tabletDivisionLineInfo != NONE_DIVISION_LINE)
					{
						if (TabletGradeData.ETC_Side_Split_Line_UnInspection_Area_Setting)
						{
							// 불량 재검증
							if (remakeInspectionArea)
							{
								DefectSW = 0;
								for (y = startY; y < endY; ++y)
								{
									for (x = startX; x < endX; ++x)
									{
										tempAddress = tempImageWidth * y + x;
										smallSizeAddress = MAX_IMAGE_WIDTH * (y / 2) + (x / 2);

										if (LabelImageHighResolution[tempAddress])
										{
											areaValue = InspectionArea[smallSizeAddress];

											if (areaValue == SIDE_SHAPE_UNINSPECTION_AREA)
											{
												if (label_Image[smallSizeAddress])
												{
													tempLabelN = label_Image[smallSizeAddress];

													LabelImageHighResolution[tempAddress] = 0;

													if (Pixel_N_Of_Label[tempLabelN] > 0)
													{
														Pixel_N_Of_Label[tempLabelN]--;
													}
												}
											}
										}
									}
								}

								for (y = startY; y < endY; ++y)
								{
									for (x = startX; x < endX; ++x)
									{
										tempAddress = tempImageWidth * y + x;
										smallSizeAddress = MAX_IMAGE_WIDTH * (y / 2) + (x / 2);

										if (label_Image[smallSizeAddress])
										{
											if (!LabelImageHighResolution[tempAddress])
											{
												label_Image[smallSizeAddress] = 0;
											}
										}
									}
								}

								tMax = 1;
								maxPixelDefectLabelN = -1;
								for (m = 1; m <= defectGroupN; m++)
								{
									if (Pixel_N_Of_Label[m] > tMax)
									{
										tMax = Pixel_N_Of_Label[m];
										maxPixelDefectLabelN = m;
									}
								}

								if (maxPixelDefectLabelN > 0)
								{
									if (Pixel_N_Of_Label[maxPixelDefectLabelN] > cornerBrightDefectSize)
									{
										DefectSW = 1;
										DefectInformationWrite(DEFECT_SIDE_EDGE_BRIGHT, cameraIndex, StartX_Label[maxPixelDefectLabelN],
															   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);
									}
								}
							}
						}
					}
				}
			}
		}
	}

#ifdef PC_SIM
	memcpy(LabelImage_Virtual, label_Image, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
}
//---------------------------------------------------------------------------
void DefectSearchForSideShapeForSugarCoating(int cameraIndex)
{
	int startX, endX, startY, endY;
	int areaValue;
	int selfPositionValue;
	int x, y, m, r;
	short defectPointData[MAX_DEFECT_POINT_COUNT * 3];
	int defectPointDataCnt;
	int tempAddress;
	int tempAddress2;
	int defectGroupN;
	unsigned char *tempOneColorImage;
	int darkDefectCheckSW = 0;
	int colorDiff;
	int alpha;
	int beta;
	int thresholdDark;
	int tMax;
	int maxPixelDefectLabelN;
	int compareValue;
	short *label_Image;
	int topSW, bottomSW, leftSW, rightSW, topLeftSW, topRightSW, botLeftSW, botRightSW;
	int maxColorDiff;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	label_Image = RotationEdgeImage;

	memset(defectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
	defectPointDataCnt = 0;

	alpha = SIDE_NORMAL_AREA_THRESH + TabletGradeData.side_dirty_Intensity * 2;
	beta = SIDE_NORMAL_AREA_THRESH + TabletGradeData.side_stain_Intensity * 4;

	tempOneColorImage = MeanOneColorImage;

	thresholdDark = alpha;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			areaValue = InspectionArea[tempAddress];
			if (areaValue == NORMAL_INPECTION_AREA)
			{
				selfPositionValue = tempOneColorImage[tempAddress];
				darkDefectCheckSW = 0;
				maxColorDiff = 0;
				topSW = bottomSW = leftSW = rightSW = topLeftSW = topRightSW = botLeftSW = botRightSW = 0;

				for (r = 4; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = compareValue - selfPositionValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							topSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 4; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = compareValue - selfPositionValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							leftSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 4; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = compareValue - selfPositionValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							topLeftSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 4; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = compareValue - selfPositionValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							topRightSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				if (darkDefectCheckSW)
				{
					for (r = 4; r >= 1; --r)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
						if (ShapeBinaryImage[tempAddress2])
						{
							compareValue = tempOneColorImage[tempAddress2];
							colorDiff = compareValue - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
								bottomSW = 1;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
								break;
							}
						}
					}

					for (r = 4; r >= 1; --r)
					{
						tempAddress2 = tempAddress + r * 4;
						if (ShapeBinaryImage[tempAddress2])
						{
							compareValue = tempOneColorImage[tempAddress2];
							colorDiff = compareValue - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
								rightSW = 1;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
								break;
							}
						}
					}

					for (r = 4; r >= 1; --r)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r * 4;
						if (ShapeBinaryImage[tempAddress2])
						{
							compareValue = tempOneColorImage[tempAddress2];
							colorDiff = compareValue - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
								botRightSW = 1;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
								break;
							}
						}
					}

					for (r = 4; r >= 1; --r)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r * 4;
						if (ShapeBinaryImage[tempAddress2])
						{
							compareValue = tempOneColorImage[tempAddress2];
							colorDiff = compareValue - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
								botLeftSW = 1;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
								break;
							}
						}
					}
				}

				if (darkDefectCheckSW >= 3 && defectPointDataCnt < MAX_DEFECT_POINT_COUNT &&
					((topSW && bottomSW) || (leftSW && rightSW) || (topRightSW && botLeftSW) || (topLeftSW && botRightSW)))
				{
					defectPointData[defectPointDataCnt * 3] = x;
					defectPointData[defectPointDataCnt * 3 + 1] = y;
					defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
					defectPointDataCnt++;
				}
			}
		}
	}

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			areaValue = InspectionArea[tempAddress];
			if (areaValue == NORMAL_INPECTION_AREA)
			{
				selfPositionValue = tempOneColorImage[tempAddress];
				darkDefectCheckSW = 0;
				maxColorDiff = 0;
				topSW = bottomSW = leftSW = rightSW = topLeftSW = topRightSW = botLeftSW = botRightSW = 0;

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							topSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							leftSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							topLeftSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							topRightSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							bottomSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							rightSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							botRightSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				for (r = 2; r >= 1; --r)
				{
					tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r * 4;
					if (ShapeBinaryImage[tempAddress2])
					{
						compareValue = tempOneColorImage[tempAddress2];
						colorDiff = selfPositionValue - compareValue;
						if (colorDiff > thresholdDark)
						{
							darkDefectCheckSW++;
							botLeftSW = 1;

							if (maxColorDiff < colorDiff)
							{
								maxColorDiff = colorDiff;
							}
							break;
						}
					}
				}

				if (darkDefectCheckSW >= 5 && defectPointDataCnt < MAX_DEFECT_POINT_COUNT &&
					((topSW && bottomSW) || (leftSW && rightSW) || (topRightSW && botLeftSW) || (topLeftSW && botRightSW)))
				{
					defectPointData[defectPointDataCnt * 3] = x;
					defectPointData[defectPointDataCnt * 3 + 1] = y;
					defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
					defectPointDataCnt++;
				}
			}
		}
	}

	if (ProcessingModeGlobal == INSPECTION_MODE)
	{
		defectGroupN = DefectLabeling(label_Image, defectPointData, defectPointDataCnt, cameraIndex);
		tMax = 1;
		maxPixelDefectLabelN = -1;
		for (m = 1; m <= defectGroupN; m++)
		{
			if (Pixel_N_Of_Label[m] > tMax)
			{
				tMax = Pixel_N_Of_Label[m];
				maxPixelDefectLabelN = m;
			}
		}

		if (maxPixelDefectLabelN > 0)
		{
			if (Pixel_N_Of_Label[maxPixelDefectLabelN] > TabletGradeData.side_dirty_Size)
			{
				DefectSW = 1;
				DefectInformationWrite(DEFECT_SIDE_DIRTY, cameraIndex, StartX_Label[maxPixelDefectLabelN],
									   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);
			}
		}
	}

	if (DefectSW == 0)
	{
		memset(defectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
		defectPointDataCnt = 0;

		thresholdDark = beta;
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				areaValue = InspectionArea[tempAddress];
				if (areaValue == NORMAL_INPECTION_AREA)
				{
					selfPositionValue = tempOneColorImage[tempAddress];
					darkDefectCheckSW = 0;
					maxColorDiff = 0;
					topSW = bottomSW = leftSW = rightSW = topLeftSW = topRightSW = botLeftSW = botRightSW = 0;

					for (r = 4; r >= 1; --r)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH + r * 4;
						if (ShapeBinaryImage[tempAddress2])
						{
							compareValue = tempOneColorImage[tempAddress2];
							colorDiff = compareValue - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
								botRightSW = 1;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
								break;
							}
						}
					}

					for (r = 4; r >= 1; --r)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH - r * 4;
						if (ShapeBinaryImage[tempAddress2])
						{
							compareValue = tempOneColorImage[tempAddress2];
							colorDiff = compareValue - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
								botLeftSW = 1;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
								break;
							}
						}
					}

					for (r = 4; r >= 1; --r)
					{
						tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
						if (ShapeBinaryImage[tempAddress2])
						{
							compareValue = tempOneColorImage[tempAddress2];
							colorDiff = compareValue - selfPositionValue;
							if (colorDiff > thresholdDark)
							{
								darkDefectCheckSW++;
								bottomSW = 1;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
								break;
							}
						}
					}

					if (darkDefectCheckSW)
					{
						darkDefectCheckSW = 0;

						for (r = 4; r >= 1; --r)
						{
							tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
							if (ShapeBinaryImage[tempAddress2])
							{
								compareValue = tempOneColorImage[tempAddress2];
								colorDiff = compareValue - selfPositionValue;
								if (colorDiff > thresholdDark)
								{
									darkDefectCheckSW++;
									topSW = 1;

									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}
									break;
								}
							}
						}

						for (r = 4; r >= 1; --r)
						{
							tempAddress2 = tempAddress - r * 4;
							if (ShapeBinaryImage[tempAddress2])
							{
								compareValue = tempOneColorImage[tempAddress2];
								colorDiff = compareValue - selfPositionValue;
								if (colorDiff > thresholdDark)
								{
									darkDefectCheckSW++;
									leftSW = 1;

									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}
									break;
								}
							}
						}

						for (r = 4; r >= 1; --r)
						{
							tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH - r * 4;
							if (ShapeBinaryImage[tempAddress2])
							{
								compareValue = tempOneColorImage[tempAddress2];
								colorDiff = compareValue - selfPositionValue;
								if (colorDiff > thresholdDark)
								{
									darkDefectCheckSW++;
									topLeftSW = 1;

									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}
									break;
								}
							}
						}

						for (r = 4; r >= 1; --r)
						{
							tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH + r * 4;
							if (ShapeBinaryImage[tempAddress2])
							{
								compareValue = tempOneColorImage[tempAddress2];
								colorDiff = compareValue - selfPositionValue;
								if (colorDiff > thresholdDark)
								{
									darkDefectCheckSW++;
									topRightSW = 1;

									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}
									break;
								}
							}
						}

						for (r = 4; r >= 1; --r)
						{
							tempAddress2 = tempAddress + r * 4;
							if (ShapeBinaryImage[tempAddress2])
							{
								compareValue = tempOneColorImage[tempAddress2];
								colorDiff = compareValue - selfPositionValue;
								if (colorDiff > thresholdDark)
								{
									darkDefectCheckSW++;
									rightSW = 1;

									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}
									break;
								}
							}
						}
					}

					if (darkDefectCheckSW >= 3 && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
					{
						defectPointData[defectPointDataCnt * 3] = x;
						defectPointData[defectPointDataCnt * 3 + 1] = y;
						defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
						defectPointDataCnt++;
					}
				}
			}
		}

		if (ProcessingModeGlobal == INSPECTION_MODE)
		{
			defectGroupN = DefectLabeling(label_Image, defectPointData, defectPointDataCnt, cameraIndex);
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (Pixel_N_Of_Label[m] > tMax)
				{
					tMax = Pixel_N_Of_Label[m];
					maxPixelDefectLabelN = m;
				}
			}

			if (maxPixelDefectLabelN > 0)
			{
				if (Pixel_N_Of_Label[maxPixelDefectLabelN] > TabletGradeData.side_stain_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_STAIN, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);
				}
			}
		}
	}

	/*
	정제 내에서 조명에 의해 밝아지는 부분때문에 불량 검출에 애로사항이 있음
	해당 영역을 마스킹... 하는게 제일 좋아보이기는 하는데

	1. 조명영역 마스킹
	2. 조명영역을 제외하고 검사 영역의 shell 별로 색상정보 학습(histogram)
	3. 불량 판정시 해당 값을 이용
	*/

#ifdef PC_SIM
	memcpy(LabelImage_Virtual, label_Image, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
}
//---------------------------------------------------------------------------
void DefectSearchForSideColorDirty(int cameraIndex)
{
	int startX, endX, startY, endY;
	int thresholdG[6];
	int thresholdB[6];
	int thresholdR[6];
	int thresholdG2[3];
	int thresholdB2[3];
	int thresholdR2[3];
	int thresholdR3;
	int thresholdG3;
	int thresholdB3;
	int thresholdR4;
	int thresholdG4;
	int thresholdB4;
	int thresholdR5;
	int thresholdG5;
	int thresholdB5;

	int selfPositionValueColorR;
	int selfPositionValueColorG;
	int selfPositionValueColorB;
	int normalizedValueR;
	int normalizedValueG;
	int normalizedValueB;
	int m, x, y;
	int tMax;
	int tMaxSideEdge;
	int brightNormalization[256];
	int brightNormalization2[256];
	int defectCheckSW;
	int defectCheckSWSideEdge;
	int tempAddress;
	int inspectionAcceptArea[11];
	int areaValue;
	int selfPositionValue;
	int defectPointDataCnt;
	int defectPointDataCntSideEdge;
	short defectPointData[MAX_DEFECT_POINT_COUNT * 3];
	short defectPointDataSideEdge[MAX_DEFECT_POINT_COUNT * 3];
	int defectGroupN;
	int defectGroupNSideEdge;
	short *label_Image;
	int maxPixelDefectLabelN;
	int maxPixelDefectLabelNSideEdge;
	int targetPositionValueColorB, targetPositionValueColorG, targetPositionValueColorR;
	int defectCount;
	int searchRange;
	int tempAddress2;
	int topDefectSW, botDefectSW, leftDefectSW, rightDefectSW, topLeftDefectSW, topRightDefectSW, botLeftDefectSW, botRightDefectSW;
	int colorHisto[64];
	int value[3];
	int colorDiff;
	int defectIntensity;
	int targetPositionValue;
	int maxColorDiff;
	int i;
	int NoneNormalized;
	int SideOption;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	if (TabletCharacter.kind != SUGARCOATING)
	{
		if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
		{
			if (TabletCharacter.tabletLayerCount == 1)
			{
				MeanColorR = MeanColorRForNormal1;
				MeanColorG = MeanColorGForNormal1;
				MeanColorB = MeanColorBForNormal1;
			}
			else
			{
				// NORMAL_INPECTION_AREA2
				MeanColorR2 = MeanColorRForNormal2;
				MeanColorG2 = MeanColorGForNormal2;
				MeanColorB2 = MeanColorBForNormal2;

				// NORMAL_INPECTION_AREA
				MeanColorR = MeanColorRForNormal1;
				MeanColorG = MeanColorGForNormal1;
				MeanColorB = MeanColorBForNormal1;
			}
		}
		else
		{
			MeanColorR = MeanColorRForNormal1;
			MeanColorG = MeanColorGForNormal1;
			MeanColorB = MeanColorBForNormal1;
		}

		label_Image = RotationEdgeImage;
		defectPointDataCnt = 0;
		defectPointDataCntSideEdge = 0;

		if (TabletCharacter.tabletLayerCount == 1)
		{
			if (selectedRGB == 2)
			{
				thresholdB[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorB / 128;
				thresholdG[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorG / 128;
				thresholdR[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorR / 128;
				thresholdB[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorB / 128;
				thresholdG[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorG / 128;
				thresholdR[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 5 * MeanColorR / 128;
				thresholdB[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorB / 128;
				thresholdG[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorG / 128;
				thresholdR[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 7 * MeanColorR / 128;

				if (TabletGradeData.Side_Edge_Color_NoneInspection_Option)
				{
					thresholdB[3] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 3 * MeanColorB / 128;
					thresholdG[3] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 3 * MeanColorG / 128;
					thresholdR[3] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 4 * MeanColorR / 128;
					thresholdB[4] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 4 * MeanColorB / 128;
					thresholdG[4] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 4 * MeanColorG / 128;
					thresholdR[4] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 5 * MeanColorR / 128;
					thresholdB[5] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 6 * MeanColorB / 128;
					thresholdG[5] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 6 * MeanColorG / 128;
					thresholdR[5] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 7 * MeanColorR / 128;
				}

				for (m = 0; m < 3; m++)
				{
					if (thresholdB[m] < 10)
						thresholdB[m] = 10;
					if (thresholdG[m] < 8)
						thresholdG[m] = 8;
					if (thresholdR[m] < 8)
						thresholdR[m] = 8;
				}

				if (TabletGradeData.Side_Edge_Color_NoneInspection_Option)
				{
					for (m = 3; m < 6; m++)
					{
						if (thresholdB[m] < 10)
							thresholdB[m] = 10;
						if (thresholdG[m] < 8)
							thresholdG[m] = 8;
						if (thresholdR[m] < 8)
							thresholdR[m] = 8;
					}
				}
			}
			else
			{
				thresholdB[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorB / 128;
				thresholdG[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorG / 128;
				thresholdR[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorR / 128;
				thresholdB[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorB / 128;
				thresholdG[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorG / 128;
				thresholdR[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 5 * MeanColorR / 128;
				thresholdB[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorB / 128;
				thresholdG[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorG / 128;
				thresholdR[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 7 * MeanColorR / 128;

				if (TabletGradeData.Side_Edge_Color_NoneInspection_Option)
				{
					thresholdB[3] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 3 * MeanColorB / 128;
					thresholdG[3] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 3 * MeanColorG / 128;
					thresholdR[3] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 4 * MeanColorR / 128;
					thresholdB[4] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 4 * MeanColorB / 128;
					thresholdG[4] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 4 * MeanColorG / 128;
					thresholdR[4] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 5 * MeanColorR / 128;
					thresholdB[5] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 6 * MeanColorB / 128;
					thresholdG[5] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 6 * MeanColorG / 128;
					thresholdR[5] = (TabletGradeData.side_Edge_Color_Dirty_Intensity + 1) * 7 * MeanColorR / 128;
				}

				for (m = 0; m < 3; m++)
				{
					if (thresholdB[m] < 6)
						thresholdB[m] = 6;
					if (thresholdG[m] < 6)
						thresholdG[m] = 6;
					if (thresholdR[m] < 6)
						thresholdR[m] = 6;
				}

				if (TabletGradeData.Side_Edge_Color_NoneInspection_Option)
				{
					for (m = 3; m < 6; m++)
					{
						if (thresholdB[m] < 6)
							thresholdB[m] = 6;
						if (thresholdG[m] < 6)
							thresholdG[m] = 6;
						if (thresholdR[m] < 6)
							thresholdR[m] = 6;
					}
				}
			}

			if (selectedRGB == 0)
			{
				for (m = 1; m < 256; m++)
					brightNormalization[m] = 1024 * MeanColorB / m;
			}
			else if (selectedRGB == 1)
			{
				for (m = 1; m < 256; m++)
					brightNormalization[m] = 1024 * MeanColorG / m;
			}
			else if (selectedRGB == 2)
			{
				for (m = 1; m < 256; m++)
					brightNormalization[m] = 1024 * MeanColorR / m;
			}
		}
		else
		{
			if (selectedRGB == 2)
			{
				thresholdB[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorB / 128;
				thresholdG[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorG / 128;
				thresholdR[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorR / 128;
				thresholdB[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorB / 128;
				thresholdG[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorG / 128;
				thresholdR[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 5 * MeanColorR / 128;
				thresholdB[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorB / 128;
				thresholdG[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorG / 128;
				thresholdR[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 7 * MeanColorR / 128;

				for (m = 0; m < 3; m++)
				{
					if (thresholdB[m] < 10)
						thresholdB[m] = 10;
					if (thresholdG[m] < 8)
						thresholdG[m] = 8;
					if (thresholdR[m] < 8)
						thresholdR[m] = 8;
				}

				thresholdB2[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorB2 / 128;
				thresholdG2[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorG2 / 128;
				thresholdR2[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorR2 / 128;
				thresholdB2[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorB2 / 128;
				thresholdG2[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorG2 / 128;
				thresholdR2[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 5 * MeanColorR2 / 128;
				thresholdB2[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorB2 / 128;
				thresholdG2[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorG2 / 128;
				thresholdR2[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 7 * MeanColorR2 / 128;

				for (m = 0; m < 3; m++)
				{
					if (thresholdB2[m] < 10)
						thresholdB2[m] = 10;
					if (thresholdG2[m] < 8)
						thresholdG2[m] = 8;
					if (thresholdR2[m] < 8)
						thresholdR2[m] = 8;
				}
			}
			else
			{
				thresholdB[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorB / 128;
				thresholdG[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorG / 128;
				thresholdR[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorR / 128;
				thresholdB[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorB / 128;
				thresholdG[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorG / 128;
				thresholdR[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 5 * MeanColorR / 128;
				thresholdB[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorB / 128;
				thresholdG[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorG / 128;
				thresholdR[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 7 * MeanColorR / 128;
				for (m = 0; m < 3; m++)
				{
					if (thresholdB[m] < 6)
						thresholdB[m] = 6;
					if (thresholdG[m] < 6)
						thresholdG[m] = 6;
					if (thresholdR[m] < 6)
						thresholdR[m] = 6;
				}

				thresholdB2[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorB2 / 128;
				thresholdG2[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 3 * MeanColorG2 / 128;
				thresholdR2[0] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorR2 / 128;
				thresholdB2[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorB2 / 128;
				thresholdG2[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 4 * MeanColorG2 / 128;
				thresholdR2[1] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 5 * MeanColorR2 / 128;
				thresholdB2[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorB2 / 128;
				thresholdG2[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 6 * MeanColorG2 / 128;
				thresholdR2[2] = (TabletGradeData.side_Color_Dirty_Intensity + 1) * 7 * MeanColorR2 / 128;
				for (m = 0; m < 3; m++)
				{
					if (thresholdB2[m] < 6)
						thresholdB2[m] = 6;
					if (thresholdG2[m] < 6)
						thresholdG2[m] = 6;
					if (thresholdR2[m] < 6)
						thresholdR2[m] = 6;
				}
			}

			if (selectedRGB == 0)
			{
				for (m = 1; m < 256; m++)
					brightNormalization[m] = 1024 * MeanColorB / m;
			}
			else if (selectedRGB == 1)
			{
				for (m = 1; m < 256; m++)
					brightNormalization[m] = 1024 * MeanColorG / m;
			}
			else if (selectedRGB == 2)
			{
				for (m = 1; m < 256; m++)
					brightNormalization[m] = 1024 * MeanColorR / m;
			}

			if (selectedRGB == 0)
			{
				for (m = 1; m < 256; m++)
					brightNormalization2[m] = 1024 * MeanColorB2 / m;
			}
			else if (selectedRGB == 1)
			{
				for (m = 1; m < 256; m++)
					brightNormalization2[m] = 1024 * MeanColorG2 / m;
			}
			else if (selectedRGB == 2)
			{
				for (m = 1; m < 256; m++)
					brightNormalization2[m] = 1024 * MeanColorR2 / m;
			}
		}

		if (TabletCharacter.kind == UNCOATING)
		{
			for (m = 0; m < 11; m++)
			{
				inspectionAcceptArea[m] = 0;

				if (m == NORMAL_INPECTION_AREA)
					inspectionAcceptArea[m] = 1;
				if (m == NORMAL_INPECTION_AREA2)
					inspectionAcceptArea[m] = 1;
			}
		}
		else
		{
			for (m = 0; m < 11; m++)
			{
				inspectionAcceptArea[m] = 0;

				if (m == NORMAL_INPECTION_AREA)
					inspectionAcceptArea[m] = 1;
				if (m == NORMAL_INPECTION_AREA2)
					inspectionAcceptArea[m] = 1;
				if (m == SIDE_SHAPE_BOTTOM_EDGE_SHORT_NEIGHBOR)
					inspectionAcceptArea[m] = 1;
				if (m == SIDE_SHAPE_BOTTOM_EDGE_LONG_NEIGHBOR)
					inspectionAcceptArea[m] = 1;
				/*
				if (m == SIDE_SHAPE_TOP_EDGE_UPPER_NEIGHBOR)
				inspectionAcceptArea[m] = 1;
				*/
				if (m == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
					inspectionAcceptArea[m] = 1;
			}
		}

		if (TabletGradeData.Side_Edge_Color_NoneInspection_Option)
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					tempAddress2 = MAX_IMAGE_WIDTH * (y - 1) + x;
					areaValue = InspectionArea[tempAddress];

					if (areaValue == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
					{
						if (InspectionArea[tempAddress2] != SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
							for (i = 1; i <= 3; i++)
							{
								InspectionArea[MAX_IMAGE_WIDTH * (y - i) + x] = SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA;
							}
					}
				}
			}
		}

		if (TabletCharacter.tabletLayerCount == 1)
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					defectCheckSW = 0;
					defectCheckSWSideEdge = 0;

					tempAddress = MAX_IMAGE_WIDTH * y + x;
					areaValue = InspectionArea[tempAddress];
					selfPositionValue = OneColorImage[tempAddress];

					if (inspectionAcceptArea[areaValue])
					{
						// 모서리옵션 On
						// 모서리 영역 일 경우
						selfPositionValueColorR = ColorSourceImage[tempAddress * 3 + 2];
						selfPositionValueColorB = ColorSourceImage[tempAddress * 3];
						selfPositionValueColorG = ColorSourceImage[tempAddress * 3 + 1];

						NoneNormalized = 0;

						if ((areaValue == SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA) && (TabletGradeData.Side_Edge_Color_NoneInspection_Option))
						{
							if ((selfPositionValueColorR - MeanColorR >= 80) && (selfPositionValueColorG - MeanColorG >= 80))
							{
								NoneNormalized = 1;
							}
							else if ((selfPositionValueColorG - MeanColorG >= 80) && (selfPositionValueColorB - MeanColorB >= 80))
							{
								NoneNormalized = 1;
							}
							else if ((selfPositionValueColorB - MeanColorB >= 80) && (selfPositionValueColorR - MeanColorR >= 80))
							{
								NoneNormalized = 1;
							}

							if (!NoneNormalized)
							{
								normalizedValueR = selfPositionValueColorR * brightNormalization[selfPositionValue] >> 10;
								normalizedValueG = selfPositionValueColorG * brightNormalization[selfPositionValue] >> 10;
								normalizedValueB = selfPositionValueColorB * brightNormalization[selfPositionValue] >> 10;
							}
							else
							{
								normalizedValueR = selfPositionValueColorR;
								normalizedValueG = selfPositionValueColorG;
								normalizedValueB = selfPositionValueColorB;
							}

							thresholdR3 = thresholdR[3] + 30;
							thresholdG3 = thresholdG[3] + 30;
							thresholdB3 = thresholdB[3] + 30;

							thresholdR4 = thresholdR[3];
							thresholdG4 = thresholdG[3];
							thresholdB4 = thresholdB[3];

							thresholdR5 = thresholdR[4] + 30;
							thresholdG5 = thresholdG[4] + 30;
							thresholdB5 = thresholdB[4] + 30;

							SideOption = 1;
						}
						else
						{
							normalizedValueR = selfPositionValueColorR * brightNormalization[selfPositionValue] >> 10;
							normalizedValueG = selfPositionValueColorG * brightNormalization[selfPositionValue] >> 10;
							normalizedValueB = selfPositionValueColorB * brightNormalization[selfPositionValue] >> 10;

							thresholdR3 = thresholdR[0];
							thresholdG3 = thresholdG[0];
							thresholdB3 = thresholdB[0];

							thresholdR4 = thresholdR[0];
							thresholdG4 = thresholdG[0];
							thresholdB4 = thresholdB[0];

							thresholdR5 = thresholdR[1];
							thresholdG5 = thresholdG[1];
							thresholdB5 = thresholdB[1];

							SideOption = 0;
						}
						if (areaValue == NORMAL_INPECTION_AREA)
						{
							if (!TabletGradeData.DirtyGradeSensitivity)
							{
								if ((normalizedValueR - MeanColorR) > thresholdR3)
								{
									if (SideOption)
										defectCheckSWSideEdge = 1;
									else
										defectCheckSW = 1;
								}
								else if ((normalizedValueG - MeanColorG) > thresholdG3)
								{
									if (SideOption)
										defectCheckSWSideEdge = 1;
									else
										defectCheckSW = 1;
								}
								else if ((normalizedValueB - MeanColorB) > thresholdB3)
								{
									if (SideOption)
										defectCheckSWSideEdge = 1;
									else
										defectCheckSW = 1;
								}
							}
							else
							{
								// 색이물불량 처리 방식2
								// Color Differcence 적용하여 예상군 뽑아내고 meanColor기준으로 색이물 불량 처리(AND)
								defectCount = 0;
								for (searchRange = 12; searchRange >= 4; searchRange -= 4)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB4 ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG4 ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR4)
										{
											defectCount++;
										}
									}

									if (defectCount >= 4)
									{
										if ((selfPositionValueColorR - MeanColorR) > thresholdR4)
										{
											if (SideOption)
												defectCheckSWSideEdge = 1;
											else
												defectCheckSW = 1;
										}
										else if ((selfPositionValueColorG - MeanColorG) > thresholdG4)
										{
											if (SideOption)
												defectCheckSWSideEdge = 1;
											else
												defectCheckSW = 1;
										}
										else if ((selfPositionValueColorB - MeanColorB) > thresholdB4)
										{
											if (SideOption)
												defectCheckSWSideEdge = 1;
											else
												defectCheckSW = 1;
										}
										break;
									}
								}
							}
						}
						else
						{
							if ((normalizedValueR - MeanColorR) > thresholdR5)
							{
								if (SideOption)
									defectCheckSWSideEdge = 1;
								else
									defectCheckSW = 1;
							}
							else if ((normalizedValueG - MeanColorG) > thresholdG5)
							{
								if (SideOption)
									defectCheckSWSideEdge = 1;
								else
									defectCheckSW = 1;
							}
							else if ((normalizedValueB - MeanColorB) > thresholdB5)
							{
								if (SideOption)
									defectCheckSWSideEdge = 1;
								else
									defectCheckSW = 1;
							}
						}

						if (defectCheckSW && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
						{
							defectPointData[defectPointDataCnt * 3] = x;
							defectPointData[defectPointDataCnt * 3 + 1] = y;
							defectPointDataCnt++;
						}

						if (defectCheckSWSideEdge && defectPointDataCntSideEdge < MAX_DEFECT_POINT_COUNT)
						{
							defectPointDataSideEdge[defectPointDataCntSideEdge * 3] = x;
							defectPointDataSideEdge[defectPointDataCntSideEdge * 3 + 1] = y;
							defectPointDataCntSideEdge++;
						}
					}
				}
			}
		}
		else
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					defectCheckSW = 0;
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					areaValue = InspectionArea[tempAddress];

					selfPositionValue = OneColorImage[tempAddress];
					if (inspectionAcceptArea[areaValue])
					{
						selfPositionValueColorR = ColorSourceImage[tempAddress * 3 + 2];
						selfPositionValueColorB = ColorSourceImage[tempAddress * 3];
						selfPositionValueColorG = ColorSourceImage[tempAddress * 3 + 1];

						if (areaValue == NORMAL_INPECTION_AREA)
						{
							normalizedValueR = selfPositionValueColorR * brightNormalization[selfPositionValue] >> 10;
							normalizedValueG = selfPositionValueColorG * brightNormalization[selfPositionValue] >> 10;
							normalizedValueB = selfPositionValueColorB * brightNormalization[selfPositionValue] >> 10;

							defectCount = 0;
							topDefectSW = botDefectSW = leftDefectSW = rightDefectSW = topLeftDefectSW = topRightDefectSW = botLeftDefectSW = botRightDefectSW = 0;
							for (searchRange = 20; searchRange >= 4; searchRange -= 4)
							{
								if (!topDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											topDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!botDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											botDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!leftDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											leftDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!rightDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											rightDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!topLeftDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											topLeftDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!botRightDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											botRightDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!topRightDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											topRightDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!botLeftDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR[0])
										{
											botLeftDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (defectCount > 4 && ((leftDefectSW || topLeftDefectSW || botLeftDefectSW) && (rightDefectSW || topRightDefectSW || botRightDefectSW)))
								{
									/*if ((selfPositionValueColorR - MeanColorR) > thresholdR[0])
									{
									defectCheckSW = 1;
									}
									else if ((selfPositionValueColorG - MeanColorG) > thresholdG[0])
									{
									defectCheckSW = 1;
									}
									else if ((selfPositionValueColorB - MeanColorB) > thresholdB[0])*/
									{
										defectCheckSW = 1;
									}
									break;
								}
							}
						}
						else if (areaValue == NORMAL_INPECTION_AREA2)
						{
							normalizedValueR = selfPositionValueColorR * brightNormalization2[selfPositionValue] >> 10;
							normalizedValueG = selfPositionValueColorG * brightNormalization2[selfPositionValue] >> 10;
							normalizedValueB = selfPositionValueColorB * brightNormalization2[selfPositionValue] >> 10;

							defectCount = 0;
							topDefectSW = botDefectSW = leftDefectSW = rightDefectSW = topLeftDefectSW = topRightDefectSW = botLeftDefectSW = botRightDefectSW = 0;
							for (searchRange = 20; searchRange >= 4; searchRange -= 4)
							{
								if (!topDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											topDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!botDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											botDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!leftDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											leftDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!rightDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											rightDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!topLeftDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											topLeftDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!botRightDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											botRightDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!topRightDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x + searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											topRightDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (!botLeftDefectSW)
								{
									tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x - searchRange);

									areaValue = InspectionArea[tempAddress2];

									if (areaValue == NORMAL_INPECTION_AREA2)
									{
										targetPositionValueColorB = ColorSourceImage[tempAddress2 * 3 + 0];
										targetPositionValueColorG = ColorSourceImage[tempAddress2 * 3 + 1];
										targetPositionValueColorR = ColorSourceImage[tempAddress2 * 3 + 2];

										if (selfPositionValueColorB - targetPositionValueColorB > thresholdB2[0] ||
											selfPositionValueColorG - targetPositionValueColorG > thresholdG2[0] ||
											selfPositionValueColorR - targetPositionValueColorR > thresholdR2[0])
										{
											botLeftDefectSW = 1;
											defectCount++;
										}
									}
								}

								if (defectCount > 4 && ((leftDefectSW || topLeftDefectSW || botLeftDefectSW) && (rightDefectSW || topRightDefectSW || botRightDefectSW)))
								{
									/*if ((selfPositionValueColorR - MeanColorR2) > thresholdR2[0])
									{
									defectCheckSW = 1;
									}
									else if ((selfPositionValueColorG - MeanColorG2) > thresholdG2[0])
									{
									defectCheckSW = 1;
									}
									else if ((selfPositionValueColorB - MeanColorB2) > thresholdB2[0])*/
									{
										defectCheckSW = 1;
									}
									break;
								}
							}
						}
					}
					if (defectCheckSW && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
					{
						defectPointData[defectPointDataCnt * 3] = x;
						defectPointData[defectPointDataCnt * 3 + 1] = y;
						defectPointDataCnt++;
					}
				}
			}
		}

		defectGroupN = DefectLabeling(label_Image, defectPointData, defectPointDataCnt, cameraIndex);
		if (ProcessingModeGlobal == INSPECTION_MODE)
		{
			tMax = 1;
			maxPixelDefectLabelN = -1;

			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideNormal[m] + PixelNInShapeSideEdge[m] > tMax)
				{
					tMax = PixelNInShapeSideNormal[m] + PixelNInShapeSideEdge[m];
					maxPixelDefectLabelN = m;
				}
			}
			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > TabletGradeData.side_Color_Dirty_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_COLOR_DIRTY, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
#ifdef PC_SIM
					memcpy(LabelImage_Virtual, label_Image, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
				}
			}
		}

		if (!DefectSW && TabletGradeData.Side_Edge_Color_NoneInspection_Option)
		{
			defectGroupN = DefectLabeling(label_Image, defectPointDataSideEdge, defectPointDataCntSideEdge, cameraIndex);
			if (ProcessingModeGlobal == INSPECTION_MODE)
			{
				tMax = 1;
				maxPixelDefectLabelN = -1;
				for (m = 1; m <= defectGroupN; m++)
				{
					if (PixelNInShapeSideNormal[m] + PixelNInShapeSideEdge[m] > tMax)
					{
						tMax = PixelNInShapeSideNormal[m] + PixelNInShapeSideEdge[m];
						maxPixelDefectLabelN = m;
					}
				}
				if (maxPixelDefectLabelN > 0)
				{
					if (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > TabletGradeData.side_Color_Dirty_Size)
					{
						DefectSW = 1;
						DefectInformationWrite(DEFECT_SIDE_COLOR_DIRTY, cameraIndex, StartX_Label[maxPixelDefectLabelN],
											   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
#ifdef PC_SIM
						memcpy(LabelImage_Virtual, label_Image, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
					}
				}
			}
		}
	}
	else
	{
		defectIntensity = TabletGradeData.side_Color_Dirty_Intensity * 4;

		label_Image = RotationEdgeImage;
		defectPointDataCnt = 0;

		memset(colorHisto, 0, sizeof(int) * 64);
		memset(TempImage, 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 (ShapeBinaryImage[tempAddress])
				{
					value[0] = ColorSourceImage[tempAddress * 3 + 0];
					value[1] = ColorSourceImage[tempAddress * 3 + 1];
					value[2] = ColorSourceImage[tempAddress * 3 + 2];

					value[selectedRGB] = value[selectedRGB] * 255 / (value[0] + value[1] + value[2]);

					TempImage[tempAddress] = value[selectedRGB];

					if (InspectionArea[tempAddress] == NORMAL_INPECTION_AREA)
						colorHisto[value[selectedRGB] / 4]++;
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				defectCheckSW = 0;
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				areaValue = InspectionArea[tempAddress];
				if (areaValue == NORMAL_INPECTION_AREA)
				{
					selfPositionValue = TempImage[tempAddress];

					maxColorDiff = 0;
					defectCount = 0;
					for (searchRange = 16; searchRange >= 4; searchRange -= 4)
					{
						tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA || ShapeBinaryImage[tempAddress2])
						{
							// 상단 위치 비교시에만 Binary 고려
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA)
						{
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x - searchRange);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA)
						{
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x + searchRange);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA)
						{
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x - searchRange);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA)
						{
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x + searchRange);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA)
						{
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						tempAddress2 = MAX_IMAGE_WIDTH * (y - searchRange) + (x + searchRange);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA)
						{
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						tempAddress2 = MAX_IMAGE_WIDTH * (y + searchRange) + (x - searchRange);

						if (InspectionArea[tempAddress2] == NORMAL_INPECTION_AREA)
						{
							targetPositionValue = TempImage[tempAddress2];

							colorDiff = abs(selfPositionValue - targetPositionValue);

							if (colorDiff > defectIntensity)
							{
								defectCount++;

								if (maxColorDiff < colorDiff)
								{
									maxColorDiff = colorDiff;
								}
							}
						}

						if (defectCount >= 4)
						{
							defectCheckSW = 1;
							break;
						}
					}
				}
				if (defectCheckSW && InspectionArea[tempAddress] == NORMAL_INPECTION_AREA && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
				{
					defectPointData[defectPointDataCnt * 3 + 0] = x;
					defectPointData[defectPointDataCnt * 3 + 1] = y;
					defectPointData[defectPointDataCnt * 3 + 2] = maxColorDiff;
					defectPointDataCnt++;
				}
			}
		}

		/*
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if(InspectionArea[tempAddress] == NORMAL_INPECTION_AREA)
				{
					selfPositionValue = TempImage[tempAddress];

					colorDiff = abs(selfPositionValue - stdThreshold);

					if(colorDiff > defectIntensity && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
					{
						defectPointData[defectPointDataCnt * 3 + 0] = x;
						defectPointData[defectPointDataCnt * 3 + 1] = y;
						defectPointData[defectPointDataCnt * 3 + 2] = colorDiff;
						defectPointDataCnt++;
					}
				}
			}
		}
		*/

		defectGroupN = DefectLabeling(label_Image, defectPointData, defectPointDataCnt, cameraIndex);

		if (ProcessingModeGlobal == INSPECTION_MODE)
		{
			tMax = 1;
			maxPixelDefectLabelN = -1;
			for (m = 1; m <= defectGroupN; m++)
			{
				if (PixelNInShapeSideNormal[m] + PixelNInShapeSideEdge[m] > tMax)
				{
					tMax = PixelNInShapeSideNormal[m] + PixelNInShapeSideEdge[m];
					maxPixelDefectLabelN = m;
				}
			}
			if (maxPixelDefectLabelN > 0)
			{
				if (PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN] > TabletGradeData.side_Color_Dirty_Size)
				{
					DefectSW = 1;
					DefectInformationWrite(DEFECT_SIDE_COLOR_DIRTY, cameraIndex, StartX_Label[maxPixelDefectLabelN],
										   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], PixelNInShapeSideNormal[maxPixelDefectLabelN] + PixelNInShapeSideEdge[maxPixelDefectLabelN]);
#ifdef PC_SIM
					memcpy(LabelImage_Virtual, label_Image, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
				}
			}
		}
	}
}
//---------------------------------------------------------------------------
void DefectSearhForUninsArea(int cameraIndex, int option)
{
	int x, y;
	int startX, endX, startY, endY;
	int minPos[2], maxPos[2];
	int centerpos[2];
	int startPos[2];
	int m;
	int tempX, tempY;
	int boundary[MAX_IMAGE_WIDTH];
	int tempAddress;
	int tempCount;
	int selfValue;
	int r;
	int colorDiff;
	int topSW, sideSW;
	short defectPointData[MAX_DEFECT_POINT_COUNT * 3];
	int defectPointDataCnt;
	short *label_Image;
	int defectGroupN;
	int maxPixelDefectLabelN;
	int tMax;
	float d1, d2;
	int SelectedX, SelectedY;
	int CheckPointX1, CheckPointY1;
	int CheckPointX2, CheckPointY2;
	long long id1, id2;
	long long cX, cY;
	int distance;
	int minDistance;
	int roundMinPos[2];
	int roundMaxPos[2];

	label_Image = RotationEdgeImage;

	memset(defectPointData, 0, MAX_DEFECT_POINT_COUNT * 3 * 2);
	defectPointDataCnt = 0;

	startX = TabletSetupData.ImageCutStartX[cameraIndex - 1];
	endX = TabletSetupData.ImageCutEndX[cameraIndex - 1];
	startY = TabletSetupData.ImageCutStartY[cameraIndex - 1];
	endY = TabletSetupData.ImageCutEndY[cameraIndex - 1];

	centerpos[0] = tempCount = 0;
	for (y = startY; y < endY; y += 2)
	{
		for (x = startX; x < endX; x += 2)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (InspectionArea[tempAddress] == NORMAL_INPECTION_AREA || InspectionArea[tempAddress] == NORMAL_INPECTION_AREA2)
			{
				centerpos[0] += x;
				tempCount++;
			}
		}
	}

	if (tempCount)
	{
		centerpos[0] /= tempCount;
	}
	centerpos[1] = tempCount = 0;

	minPos[0] = roundMinPos[0] = MAX_IMAGE_WIDTH;
	maxPos[0] = roundMaxPos[0] = 0;

	if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
	{
		for (m = 0; m < finalMatchingShapeData.SideShapeEdgePointCountBottom; m++)
		{
			tempX = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2] + TabletMatchingResult.TabletSideShapeShiftX;
			tempY = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2 + 1] + TabletMatchingResult.TabletSideShapeShiftY;

			if (minPos[0] > tempX)
			{
				minPos[0] = tempX;
				minPos[1] = tempY;
			}

			if (maxPos[0] < tempX)
			{
				maxPos[0] = tempX;
				maxPos[1] = tempY;
			}

			if (tempX > centerpos[0] - 10 && tempX < centerpos[0] + 10)
			{
				centerpos[1] += tempY;
				tempCount++;
			}

			if (!SideEdgeMaskingArea[MAX_IMAGE_WIDTH * tempY + tempX])
			{
				if (roundMinPos[0] > tempX)
				{
					roundMinPos[0] = tempX;
					roundMinPos[1] = tempY;
				}

				if (roundMaxPos[0] < tempX)
				{
					roundMaxPos[0] = tempX;
					roundMaxPos[1] = tempY;
				}
			}
		}
	}
	else
	{
		for (m = 0; m < TabletETCMatchingResult.tabletShapeBottomLineCount; m++)
		{
			tempX = TabletETCMatchingResult.tabletShapeBottomLine[m * 2 + 0];
			tempY = TabletETCMatchingResult.tabletShapeBottomLine[m * 2 + 1];

			if (minPos[0] > tempX)
			{
				minPos[0] = tempX;
				minPos[1] = tempY;
			}

			if (maxPos[0] < tempX)
			{
				maxPos[0] = tempX;
				maxPos[1] = tempY;
			}

			if (tempX > centerpos[0] - 10 && tempX < centerpos[0] + 10)
			{
				centerpos[1] += tempY;
				tempCount++;
			}

			if (!SideEdgeMaskingArea[MAX_IMAGE_WIDTH * tempY + tempX])
			{
				if (roundMinPos[0] > tempX)
				{
					roundMinPos[0] = tempX;
					roundMinPos[1] = tempY;
				}

				if (roundMaxPos[0] < tempX)
				{
					roundMaxPos[0] = tempX;
					roundMaxPos[1] = tempY;
				}
			}
		}
	}

	if (tempCount)
	{
		centerpos[1] /= tempCount;
	}
	else
	{
		DefectSW = 3;
		return;
	}

	for (m = 0; m < MAX_IMAGE_WIDTH; m++)
	{
		boundary[m] = 0xFFFF;
	}

	SelectedX = centerpos[0];
	SelectedY = centerpos[1];

	CheckPointX1 = roundMinPos[0];
	CheckPointY1 = roundMinPos[1];

	CheckPointX2 = roundMaxPos[0];
	CheckPointY2 = roundMaxPos[1];

#ifdef PC_SIM
	memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	for (y = SelectedY - 2; y <= SelectedY + 2; y++)
	{
		for (x = SelectedX - 2; x <= SelectedX + 2; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			TempImage[tempAddress] = 255;
		}
	}

	for (y = CheckPointY1 - 2; y <= CheckPointY1 + 2; y++)
	{
		for (x = CheckPointX1 - 2; x <= CheckPointX1 + 2; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			TempImage[tempAddress] = 255;
		}
	}

	for (y = CheckPointY2 - 2; y <= CheckPointY2 + 2; y++)
	{
		for (x = CheckPointX2 - 2; x <= CheckPointX2 + 2; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;
			TempImage[tempAddress] = 255;
		}
	}
#endif

	if (SelectedY - CheckPointY1)
	{
		id1 = ((SelectedX - CheckPointX1) * 100000) / (SelectedY - CheckPointY1);
	}
	else
	{
		id1 = ((SelectedX - CheckPointX1) * 100000);
	}

	if (CheckPointY2 - SelectedY)
	{
		id2 = ((CheckPointX2 - SelectedX) * 100000) / (CheckPointY2 - SelectedY);
	}
	else
	{
		id2 = ((CheckPointX2 - SelectedX) * 100000);
	}

	if (id2 - id1)
	{
		cX = ((CheckPointY2 - CheckPointY1) * 100000 + (SelectedX + CheckPointX2) * id2 - (SelectedX + CheckPointX1) * id1) * 100 / (2 * (id2 - id1));
		cY = (-id1 * (cX - ((CheckPointX1 + SelectedX) / 2) * 100)) / 10000000 + (SelectedY + CheckPointY1) / 2;

		cX /= 100;

		if (option == SIDE_FACE_M45)
		{
			distance = (CheckPointX1 - cX) * (CheckPointX1 - cX) + (CheckPointY1 - cY) * (CheckPointY1 - cY);
			minDistance = (CheckPointX1 - SelectedX) * (CheckPointX1 - SelectedX) + (CheckPointY1 - SelectedY) * (CheckPointY1 - SelectedY);
		}
		else
		{
			distance = (CheckPointX2 - cX) * (CheckPointX2 - cX) + (CheckPointY2 - cY) * (CheckPointY2 - cY);
			minDistance = (CheckPointX2 - SelectedX) * (CheckPointX2 - SelectedX) + (CheckPointY2 - SelectedY) * (CheckPointY2 - SelectedY);
		}

		if (distance < MAX_SHAPE_RADIAL * MAX_SHAPE_RADIAL && distance > minDistance)
		{
			r = sqrtTable[distance] / 1000 - 4;

			for (x = startX; x < endX; x++)
			{
				if (r * r >= (x - cX) * (x - cX))
				{
					distance = r * r - (x - cX) * (x - cX);

					y = sqrtTable[distance] / 1000 + cY;

					if (y > startY && y < endY)
					{
						if (boundary[x] > y)
						{
							boundary[x] = y;
						}

#ifdef PC_SIM
						TempImage[MAX_IMAGE_WIDTH * y + x] = 255;
#endif
					}
				}
			}
		}
	}

	if (option == SIDE_FACE_M45)
	{
		startPos[0] = minPos[0];
		startPos[1] = minPos[1];
	}
	else
	{
		startPos[0] = maxPos[0];
		startPos[1] = maxPos[1];
	}

	if (startPos[0] - centerpos[0])
	{
		for (tempX = startX; tempX < endX; tempX++)
		{
			tempY = (tempX - startPos[0]) * (startPos[1] - centerpos[1]) / (startPos[0] - centerpos[0]) + startPos[1];

			if (tempY)
			{
				if (tempX > startX && tempX < endX && tempY > startY && tempY < endY)
				{
					if (boundary[tempX] > tempY)
					{
						boundary[tempX] = tempY;
					}

#ifdef PC_SIM
					TempImage[MAX_IMAGE_WIDTH * tempY + tempX] = 255;
#endif
				}
			}
		}
	}
	else
	{
		DefectSW = 3;
		return;
	}

#ifdef PC_SIM
	for (x = startX; x < endX; x++)
	{
		if (boundary[x] && boundary[x] != 0xFFFF)
		{
			y = boundary[x];

			TempImage[MAX_IMAGE_WIDTH * y + x] = 128;
		}
	}
#endif

	for (x = startX; x < endX; x++)
	{
		if (boundary[x] && boundary[x] != 0xFFFF)
		{
			for (y = startY; y < boundary[x]; y++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (SideEdgeMaskingArea[tempAddress])
				{
					selfValue = OneColorImage[tempAddress];

					topSW = sideSW = 0;
					for (r = 24; r >= 4; r -= 4)
					{
						if (ShapeBinaryImage[tempAddress - r * MAX_IMAGE_WIDTH])
						{
							colorDiff = OneColorImage[tempAddress - r * MAX_IMAGE_WIDTH] - selfValue;

							if (colorDiff > TabletGradeData.ETC_SideEdgeDefectIntensity)
							{
								topSW = 1;
								break;
							}
						}
					}

					if (topSW)
					{
						tempCount = 0;
						if (option == SIDE_FACE_M45)
						{
							for (r = 24; r >= 12; r -= 4)
							{
								tempCount++;
								colorDiff = OneColorImage[tempAddress + r] - selfValue;

								if (colorDiff > TabletGradeData.ETC_SideEdgeDefectIntensity)
								{
									sideSW++;
								}
							}
						}
						else
						{
							for (r = 24; r >= 12; r -= 4)
							{
								tempCount++;
								colorDiff = OneColorImage[tempAddress - r] - selfValue;

								if (colorDiff > TabletGradeData.ETC_SideEdgeDefectIntensity)
								{
									sideSW++;
								}
							}
						}

						if (tempCount == sideSW && defectPointDataCnt < MAX_DEFECT_POINT_COUNT)
						{
							defectPointData[defectPointDataCnt * 3 + 0] = x;
							defectPointData[defectPointDataCnt * 3 + 1] = y;
							defectPointData[defectPointDataCnt * 3 + 2] = 1;
							defectPointDataCnt++;
						}
					}
				}
			}
		}
	}

	if (defectPointDataCnt)
	{
		defectGroupN = DefectLabeling(label_Image, defectPointData, defectPointDataCnt, cameraIndex);

		tMax = 1;
		maxPixelDefectLabelN = -1;
		for (m = 1; m <= defectGroupN; m++)
		{
			if (Pixel_N_Of_Label[m] > tMax)
			{
				tMax = Pixel_N_Of_Label[m];
				maxPixelDefectLabelN = m;
			}
		}

		if (maxPixelDefectLabelN > 0)
		{
			if (Pixel_N_Of_Label[maxPixelDefectLabelN] > TabletGradeData.ETC_SideEdgeDefectSize)
			{
				DefectSW = 1;
				DefectInformationWrite(DEFECT_SIDE_EDGE_DIRTY_OPTION, cameraIndex, StartX_Label[maxPixelDefectLabelN],
									   EndX_Label[maxPixelDefectLabelN], StartY_Label[maxPixelDefectLabelN], EndY_Label[maxPixelDefectLabelN], Pixel_N_Of_Label[maxPixelDefectLabelN]);

#ifdef PC_SIM
				for (y = startY; y < endY; y++)
				{
					for (x = startX; x < endX; x++)
					{
						tempAddress = MAX_IMAGE_WIDTH * y + x;

						if (label_Image[tempAddress] != maxPixelDefectLabelN)
						{
							label_Image[tempAddress] = 0;
						}
					}
				}
#endif
			}
		}
	}

#ifdef PC_SIM
	memcpy(LabelImage_Virtual, label_Image, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
#endif
}
//---------------------------------------------------------------------------
void DefectCheckForEdgeBreak(int cameraIndex)
{
	int x, y;
	int tempAddress;
	int startX, endX, startY, endY;
	int searchRange;
	int alpha;
	int selfValue;
	int defectSize;
	int defectBreakDepth;
	short *label_Image;
	int bottomSW;
	int r;
	int tempAddress2;
	int colorDiff;
	int maxColorDiff;
	int defectcheckCount;
	int defectGroupN;
	int tMax;
	int maxPixelDefectLabelN;
	int m;
	int areaValue;
	int LabelTopPostionX[MAX_LABEL_COUNT];
	int LabelTopPostionY[MAX_LABEL_COUNT];
	int maxBreakDepth[MAX_LABEL_COUNT];
	int labelNum;
	int tempX, tempY;
	int tempX2, tempY2;
	unsigned char *defectPoint;
	int shapeShell;
	int i, j;
	int labelFinded;
	short SideTopEdgeInfo[480 * 2];
	short SideBottomEdgeInfo[480 * 2];
	int edgeCount;

	defectPoint = TempImage2;
	label_Image = RotationEdgeImage;
	alpha = 4 + TabletGradeData.Side_Edge_Neighbor_Break_Intensity * 2;

	searchRange = 24;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	defectSize = TabletGradeData.Side_Edge_Neighbor_Break_Size;
	defectBreakDepth = TabletGradeData.Side_Edge_Neighbor_Min_Break_Depth_Size;

	memset(defectPoint, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

	// 모서리 정보 데이터화
	if (TabletCharacter.shape == ROUND || TabletCharacter.shape == OBLONG || TabletCharacter.shape == OVAL)
	{
		edgeCount = finalMatchingShapeData.SideShapeEdgePointCountBottom;
		for (m = 0; m < finalMatchingShapeData.SideShapeEdgePointCountBottom; m++)
		{
			tempX = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2 + 0] + TabletMatchingResult.TabletSideShapeShiftX + TabletMatchingResult.TabletSideShapeTopLineShiftX;
			tempY = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2 + 1] + TabletMatchingResult.TabletSideShapeShiftY + TabletMatchingResult.TabletSideShapeTopLineShiftY + tempShiftTopLine[m];

			tempX2 = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2 + 0] + TabletMatchingResult.TabletSideShapeShiftX + TabletMatchingResult.TabletSideShapeTopLineShiftX / 2;
			tempY2 = finalMatchingShapeData.SideShapeEdgePointBottom[m * 2 + 1] + TabletMatchingResult.TabletSideShapeShiftY + TabletMatchingResult.TabletSideShapeTopLineShiftY / 2 + tempShiftTopLine[m];

			SideTopEdgeInfo[m * 2 + 0] = tempX;
			SideTopEdgeInfo[m * 2 + 1] = tempY;

			SideBottomEdgeInfo[m * 2 + 0] = tempX2;
			SideBottomEdgeInfo[m * 2 + 1] = tempY2;
		}
	}
	else
	{
		edgeCount = TabletETCMatchingResult.tabletShapeBottomLineCount;
		for (m = 0; m < TabletETCMatchingResult.tabletShapeBottomLineCount; m++)
		{
			tempX2 = TabletETCMatchingResult.tabletShapeTopLine[m * 2 + 0];
			tempY2 = TabletETCMatchingResult.tabletShapeTopLine[m * 2 + 1];

			tempX = TabletETCMatchingResult.tabletShapeBottomLine[m * 2 + 0];
			tempY = TabletETCMatchingResult.tabletShapeBottomLine[m * 2 + 1];

			SideTopEdgeInfo[m * 2 + 0] = tempX2;
			SideTopEdgeInfo[m * 2 + 1] = tempY2;

			SideBottomEdgeInfo[m * 2 + 0] = (tempX + tempX2) / 2;
			SideBottomEdgeInfo[m * 2 + 1] = (tempY + tempY2) / 2;
		}
	}

	// 모서리 영역 파손 불량 검사를 위한 영역 설정
	memset(SideFaceBreakCheckArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	for (m = 0; m < edgeCount; m++)
	{
		tempX = SideTopEdgeInfo[m * 2 + 0];
		tempY = SideTopEdgeInfo[m * 2 + 1];

		if (tempX >= startX && tempX <= endX)
		{
			tempX2 = SideBottomEdgeInfo[m * 2 + 0];
			tempY2 = SideBottomEdgeInfo[m * 2 + 1];

			makeEdgeBreakCheckArea(tempX, tempY, tempX2, tempY2);
		}
	}

	// 모서리 상단 영역을 기준으로 불량 영역을 확인한다.
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			areaValue = InspectionArea[tempAddress];
			if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
			{
				if (SideFaceBreakCheckArea[tempAddress])
				{
					selfValue = MeanOneColorImage[tempAddress];

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

						areaValue = InspectionArea[tempAddress2];
						if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
						{
							if (SideFaceBreakCheckArea[tempAddress2])
							{
								colorDiff = selfValue - MeanOneColorImage[tempAddress2];
								if (colorDiff > alpha)
								{
									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}

									bottomSW = 1;
									break;
								}
							}
						}
					}

					if (!bottomSW)
						continue;

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

						areaValue = InspectionArea[tempAddress2];
						if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
						{
							if (SideFaceBreakCheckArea[tempAddress2])
							{
								colorDiff = selfValue - MeanOneColorImage[tempAddress2];
								if (colorDiff > alpha)
								{
									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}

									defectcheckCount++;
								}
							}
						}

						tempAddress2 = tempAddress + r;

						areaValue = InspectionArea[tempAddress2];
						if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
						{
							if (SideFaceBreakCheckArea[tempAddress2])
							{
								colorDiff = selfValue - MeanOneColorImage[tempAddress2];
								if (colorDiff > alpha)
								{
									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}

									defectcheckCount++;
								}
							}
						}

						tempAddress2 = tempAddress - r + r * MAX_IMAGE_WIDTH;

						areaValue = InspectionArea[tempAddress2];
						if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
						{
							if (SideFaceBreakCheckArea[tempAddress2])
							{
								colorDiff = selfValue - MeanOneColorImage[tempAddress2];
								if (colorDiff > alpha)
								{
									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}

									defectcheckCount++;
								}
							}
						}

						tempAddress2 = tempAddress + r + r * MAX_IMAGE_WIDTH;

						areaValue = InspectionArea[tempAddress2];
						if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
						{
							if (SideFaceBreakCheckArea[tempAddress2])
							{
								colorDiff = selfValue - MeanOneColorImage[tempAddress2];
								if (colorDiff > alpha)
								{
									if (maxColorDiff < colorDiff)
									{
										maxColorDiff = colorDiff;
									}

									defectcheckCount++;
								}
							}
						}

						if (defectcheckCount >= 6)
						{
							defectPoint[MAX_IMAGE_WIDTH * y + x] = 1;
							break;
						}
					}
				}
			}
		}
	}

	memset(label_Image, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	defectGroupN = SmallSizePixelLabeling(defectPoint, label_Image, startX, endX, startY, endY, MAX_IMAGE_WIDTH);

	// 각 라벨별로 최상단의 위치를 구함
	for (m = 0; m < MAX_LABEL_COUNT; m++)
	{
		LabelTopPostionX[m] = 640;
		LabelTopPostionY[m] = 480;
	}

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			areaValue = InspectionArea[tempAddress];
			if (areaValue == NORMAL_INPECTION_AREA || areaValue == NORMAL_INPECTION_AREA2)
			{
				if (SideFaceBreakCheckArea[tempAddress])
				{
					if (label_Image[tempAddress])
					{
						labelNum = label_Image[tempAddress];

						if (LabelTopPostionY[labelNum] >= y)
						{
							LabelTopPostionX[labelNum] = x;
							LabelTopPostionY[labelNum] = y;
						}
					}
				}
			}
		}
	}

	// 라벨 끝단의 바로 위 픽셀의 위치 정보를 확인
	for (m = 1; m <= defectGroupN; m++)
	{
		tempX = LabelTopPostionX[m];
		tempY = LabelTopPostionY[m];

		tempAddress = MAX_IMAGE_WIDTH * (tempY - 2) + tempX;

		areaValue = InspectionArea[tempAddress];
		if (areaValue != SIDE_SHAPE_TOP_NORMAL_BOUNDARY_AREA)
		{
			labelingPxCount[m] = 0;
		}
	}

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (label_Image[tempAddress])
			{
				labelNum = label_Image[tempAddress];
				if (labelingPxCount[labelNum] == 0 || labelingPxCount[labelNum] <= defectSize)
				{
					label_Image[tempAddress] = 0;
				}
			}
		}
	}

	memset(maxBreakDepth, 0, sizeof(int) * MAX_LABEL_COUNT);

	for (m = 0; m < edgeCount; m++)
	{
		tempX = SideTopEdgeInfo[m * 2 + 0];
		tempY = SideTopEdgeInfo[m * 2 + 1];

		tempX2 = SideBottomEdgeInfo[m * 2 + 0];
		tempY2 = SideBottomEdgeInfo[m * 2 + 1];

		shapeShell = 0;
		for (y = tempY; y <= tempY2; y++)
		{
			if (tempY - tempY2)
			{
				x = (tempX - tempX2) * (y - tempY) / (tempY - tempY2) + tempX;

				labelFinded = 0;
				if (x > startX && x < endX && y > startY && y < endY)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					if (SideFaceBreakCheckArea[tempAddress] && label_Image[tempAddress])
					{
						shapeShell++;
						labelFinded = 1;
					}
				}

				if (labelFinded)
				{
					for (j = y - 2; j <= y + 2; j++)
					{
						for (i = x - 2; i <= x + 2; i++)
						{
							if (i > startX && i < endX && j > startY && j < endY)
							{
								tempAddress = MAX_IMAGE_WIDTH * j + i;

								if (SideFaceBreakCheckArea[tempAddress] && label_Image[tempAddress])
								{
									labelNum = label_Image[tempAddress];
									if (maxBreakDepth[labelNum] < shapeShell)
									{
										maxBreakDepth[labelNum] = shapeShell;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	tMax = 1;
	maxPixelDefectLabelN = -1;
	for (m = 1; m <= defectGroupN; m++)
	{
		if (maxBreakDepth[m] > defectBreakDepth)
		{
			if (labelingPxCount[m] > tMax)
			{
				tMax = labelingPxCount[m];
				maxPixelDefectLabelN = m;
			}
		}
	}
	if (maxPixelDefectLabelN > 0)
	{
		if (labelingPxCount[maxPixelDefectLabelN] > defectSize)
		{
			DefectSW = 1;
			DefectInformationWrite(DEFECT_SIDE_EDGE_NEIGHBOR_BREAK, cameraIndex, LabelStX[maxPixelDefectLabelN],
								   LabelEdX[maxPixelDefectLabelN], LabelStY[maxPixelDefectLabelN], LabelEdY[maxPixelDefectLabelN], labelingPxCount[maxPixelDefectLabelN]);
		}
	}

#ifdef PC_SIM
	if (DefectSW == 1)
	{
		memset(LabelImage_Virtual, 0, sizeof(short) * 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 (label_Image[tempAddress] == maxPixelDefectLabelN)
				{
					LabelImage_Virtual[tempAddress] = maxPixelDefectLabelN;
				}
			}
		}
	}
#endif
}
//---------------------------------------------------------------------------
void makeEdgeBreakCheckArea(int stX, int stY, int endX, int endY)
{
	int x, y, i, j;
	int tempAddress;
	int stStartX, stEndX, stStartY, stEndY;

	stStartX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	stEndX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	stStartY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	stEndY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

	for (y = stY; y <= endY; y++)
	{
		if (stY - endY)
		{
			x = (stX - endX) * (y - stY) / (stY - endY) + stX;

			for (j = y - 2; j <= y + 2; j++)
			{
				for (i = x - 2; i <= x + 2; i++)
				{
					if (j > stY && j < endY)
					{
						if (i > stStartX && i < stEndX && j > stStartY && j < stEndY)
						{
							tempAddress = MAX_IMAGE_WIDTH * j + i;

							if (SideFaceBreakCheckArea[tempAddress] == 0 && InspectionArea[tempAddress] && InspectionArea[tempAddress] != SIDE_SHAPE_UNINSPECTION_AREA)
							{
								SideFaceBreakCheckArea[tempAddress] = 1;
							}
						}
					}
				}
			}
		}
	}
}
//---------------------------------------------------------------------------
