//---------------------------------------------------------------------------
// For SELMA200, 20180223, moon, 변경사항 없음
//---------------------------------------------------------------------------


#pragma hdrstop

#include "Bayer.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

//byte Conv_ColorRef[65536];
void __fastcall InitBayerConstant(byte *Conv_ColorRef)
{
    for (int i = 0; i < 65536; i++)
    {
		if (i > 255)
        {
        	Conv_ColorRef[i] = 255;
        }
        else
        {
			Conv_ColorRef[i] = i;
        }
    }
}

//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode1_GRBG(byte *pColorLine, byte *pUpperLine,
	byte *pLine, byte *pLowerLine, int bitmapWidth, int y)
{
	pColorLine[0] = pColorLine[1] = pColorLine[2] = 0xFF;
    for(int x = 1; x < bitmapWidth - 1; x++)
    {
    	if ((y & 1) == 0)			//	even number line
        {
        	if ((x & 1) == 0)		// Green
            {
            	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
                pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
            }
            else				// Red
            {
            	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = pLine[x];
            }
        }
        else					// odd number line
        {
        	if ((x & 1) == 0)		// Blue
            {
            	pColorLine[3*x]   = pLine[x];
                pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            }
            else				// Green
            {
            	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
                pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
            }
        }
    }
    pColorLine[3 * (bitmapWidth - 1) + 0] = pColorLine[3 * (bitmapWidth - 1) + 1] = pColorLine[3 * (bitmapWidth - 1) + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode1_GBRG(byte *pColorLine, byte *pUpperLine,
	byte *pLine, byte *pLowerLine, int bitmapWidth, int y)
{
	pColorLine[0] = pColorLine[1] = pColorLine[2] = 0xFF;
    for(int x = 1; x < bitmapWidth - 1; x++)
    {
    	if ((y & 1) == 0)			//	even number line
        {
        	if ((x & 1) == 0)		// Green
            {
            	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
                pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
            }
            else				// Blue
            {
            	pColorLine[3*x]   = pLine[x];
                pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            }
        }
        else					// odd number line
        {
        	if ((x & 1) == 0)		// Red
            {
            	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
				pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = pLine[x];
            }
            else				// Green
            {
            	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
                pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
            }
        }
    }
    pColorLine[3 * (bitmapWidth - 1) + 0] = pColorLine[3 * (bitmapWidth - 1) + 1] = pColorLine[3 * (bitmapWidth - 1) + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode1_RGGB(byte *pColorLine, byte *pUpperLine,
	byte *pLine, byte *pLowerLine, int bitmapWidth, int y)
{
	pColorLine[0] = pColorLine[1] = pColorLine[2] = 0xFF;
    for(int x = 1; x < bitmapWidth - 1; x++)
    {
    	if ((y & 1) == 0)			//	even number line
        {
        	if ((x & 1) == 0)		// Red
            {
            	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = pLine[x];
            }
            else				// Green
            {
            	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
                pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
            }
        }
        else					// odd number line
        {
        	if ((x & 1) == 0)		// Green
            {
            	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
				pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
            }
            else				// Blue
            {
            	pColorLine[3*x]   = pLine[x];
                pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            }
        }
	}
    pColorLine[3 * (bitmapWidth - 1) + 0] = pColorLine[3 * (bitmapWidth - 1) + 1] = pColorLine[3 * (bitmapWidth - 1) + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode1_BGGR(byte *pColorLine, byte *pUpperLine,
	byte *pLine, byte *pLowerLine, int bitmapWidth, int y)
{
	pColorLine[0] = pColorLine[1] = pColorLine[2] = 0xFF;
    for(int x = 1; x < bitmapWidth - 1; x++)
	{
    	if ((y & 1) == 0)			//	even number line
		{
        	if ((x & 1) == 0)		// Blue
            {
            	pColorLine[3*x]   = pLine[x];
				pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            }
            else				// Green
			{
            	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
				pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
            }
        }
		else					// odd number line
        {
			if ((x & 1) == 0)		// Green
            {
            	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
				pColorLine[3*x+1] = (4*pLine[x]+pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/8;
                pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
            }
			else				// Red
			{
            	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                pColorLine[3*x+2] = pLine[x];
            }
        }
    }
    pColorLine[3 * (bitmapWidth - 1) + 0] = pColorLine[3 * (bitmapWidth - 1) + 1] = pColorLine[3 * (bitmapWidth - 1) + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode2(byte *pColorLine, byte *pUpperLine2,
	byte *pUpperLine, byte *pLine, byte *pLowerLine, byte *pLowerLine2, int bitmapWidth, int y,
    byte *Conv_ColorRef)
{
	int x;
	x = 0;
	pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;

	x = 1;
	if ((y & 1) == 0)			//	even number line
	{
		if ((x & 1) == 0)		// Green
		{
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
		}
        else				// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
			pColorLine[3*x+2] = pLine[x];
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
		}
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }

    byte blue, green, red;
    byte expectedBlue, expectedGreen, expectedRed;
	for (x = 2; x < bitmapWidth - 2; x++)
    {
		if ((y & 1) == 0)			//	even number line
	    {
	       	if ((x & 1) == 0)		// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue  = (pUpperLine[x]+pLowerLine[x])/2;
                expectedRed   = (pLine[x-1]+pLine[x+1]) / 2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[expectedBlue * green / expectedGreen];
	                red  = Conv_ColorRef[expectedRed * green / expectedGreen];
				}
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Red
	        {
            	red = pLine[x];
                expectedRed   = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedBlue  = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedRed != 0)
                {
					green = Conv_ColorRef[expectedGreen * red / expectedRed];
	                blue  = Conv_ColorRef[expectedBlue * red / expectedRed];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                blue  = Conv_ColorRef[expectedBlue];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
	    else					// odd number line
		{
	       	if ((x & 1) == 0)		// Blue
			{
            	blue = pLine[x];
                expectedBlue  = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
				expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedRed = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedBlue != 0)
                {
	                green = Conv_ColorRef[expectedGreen * blue / expectedBlue];
	                red   = Conv_ColorRef[expectedRed * blue / expectedBlue];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                red   = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue = (pLine[x-1]+pLine[x+1])/2;
                expectedRed = (pUpperLine[x]+pLowerLine[x])/2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[expectedBlue * green / expectedGreen];
	                red  = Conv_ColorRef[expectedRed * green / expectedGreen];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
    }

    x = bitmapWidth - 2;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
        else				// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }

    x = bitmapWidth - 1;
    pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode3_GRBG(byte *pColorLine, byte *pUpperLine2,
	byte *pUpperLine, byte *pLine, byte *pLowerLine, byte *pLowerLine2, int bitmapWidth, int y,
    byte *Conv_ColorRef)
{
	int x;
	x = 0;
	pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;

    x = 1;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
        else				// Red
		{
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
		}
    }

    byte blue, green, red;
    byte expectedBlue, expectedGreen, expectedRed;
	for (x = 2; x < bitmapWidth - 2; x++)
    {
	   	if ((y & 1) == 0)			//	even number line
	    {
	       	if ((x & 1) == 0)		// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue  = (pUpperLine[x]+pLowerLine[x])/2;
                expectedRed   = (pLine[x-1]+pLine[x+1]) / 2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Red
	        {
            	red = pLine[x];
                expectedRed   = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedBlue  = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedRed != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * red / expectedRed) / 2];
	                blue  = Conv_ColorRef[(expectedBlue + expectedBlue * red / expectedRed) / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                blue  = Conv_ColorRef[expectedBlue];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
			}
		}
		else					// odd number line
		{
			if ((x & 1) == 0)		// Blue
			{
				blue = pLine[x];
				expectedBlue  = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
				expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
				expectedRed = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedBlue != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * blue / expectedBlue) / 2];
	                red   = Conv_ColorRef[(expectedRed + expectedRed * blue / expectedBlue) / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                red   = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue = (pLine[x-1]+pLine[x+1])/2;
                expectedRed = (pUpperLine[x]+pLowerLine[x])/2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
    }

    x = bitmapWidth - 2;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
        else				// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }

    x = bitmapWidth - 1;
    pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode3_BGGR(byte *pColorLine, byte *pUpperLine2,
	byte *pUpperLine, byte *pLine, byte *pLowerLine, byte *pLowerLine2, int bitmapWidth, int y,
    byte *Conv_ColorRef)
{
	int x;
	x = 0;
	pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;

    x = 1;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
        else				// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
    }

    byte blue, green, red;
    byte expectedBlue, expectedGreen, expectedRed;
	for (x = 2; x < bitmapWidth - 2; x++)
    {
	   	if ((y & 1) == 0)			//	even number line
	    {
	       	if ((x & 1) == 0)		// Blue
	        {
            	blue = pLine[x];
                expectedBlue  = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedRed = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedBlue != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * blue / expectedBlue) / 2];
	                red   = Conv_ColorRef[(expectedRed + expectedRed * blue / expectedBlue) / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                red   = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue = (pLine[x-1]+pLine[x+1])/2;
                expectedRed = (pUpperLine[x]+pLowerLine[x])/2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
	    else					// odd number line
	    {
	       	if ((x & 1) == 0)		// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue  = (pUpperLine[x]+pLowerLine[x])/2;
                expectedRed   = (pLine[x-1]+pLine[x+1]) / 2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Red
	        {
            	red = pLine[x];
                expectedRed   = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedBlue  = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedRed != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * red / expectedRed) / 2];
	                blue  = Conv_ColorRef[(expectedBlue + expectedBlue * red / expectedRed) / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
					blue  = Conv_ColorRef[expectedBlue];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
    }

	x = bitmapWidth - 2;
	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
			pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
        else				// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
    }

    x = bitmapWidth - 1;
    pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode3_GBRG(byte *pColorLine, byte *pUpperLine2,
	byte *pUpperLine, byte *pLine, byte *pLowerLine, byte *pLowerLine2, int bitmapWidth, int y,
    byte *Conv_ColorRef)
{
	int x;
	x = 0;
	pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;

    x = 1;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
        else				// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }

    byte blue, green, red;
    byte expectedBlue, expectedGreen, expectedRed;
	for (x = 2; x < bitmapWidth - 2; x++)
    {
	   	if ((y & 1) == 0)			//	even number line
	    {
	       	if ((x & 1) == 0)		// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue  = (pLine[x-1]+pLine[x+1]) / 2;
                expectedRed   = (pUpperLine[x]+pLowerLine[x])/2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Blue
	        {
            	blue = pLine[x];
                expectedBlue  = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedRed   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedBlue != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * blue / expectedBlue) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * blue / expectedBlue) / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
	    else					// odd number line
	    {
	       	if ((x & 1) == 0)		// Red
	        {
            	red = pLine[x];
                expectedRed = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedBlue  = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedRed != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * red / expectedRed) / 2];
	                blue   = Conv_ColorRef[(expectedBlue + expectedBlue * red / expectedRed) / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                blue   = Conv_ColorRef[expectedBlue];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue = (pUpperLine[x]+pLowerLine[x])/2;
                expectedRed = (pLine[x-1]+pLine[x+1])/2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
    }

    x = bitmapWidth - 2;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
        else				// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }

    x = bitmapWidth - 1;
    pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall ConvertBayerBitmapLine_Mode3_RGGB(byte *pColorLine, byte *pUpperLine2,
	byte *pUpperLine, byte *pLine, byte *pLowerLine, byte *pLowerLine2, int bitmapWidth, int y,
    byte *Conv_ColorRef)
{
	int x;
	x = 0;
	pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;

    x = 1;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;        
        }
        else				// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
    }

    byte blue, green, red;
    byte expectedBlue, expectedGreen, expectedRed;
	for (x = 2; x < bitmapWidth - 2; x++)
    {
	   	if ((y & 1) == 0)			//	even number line
	    {
	       	if ((x & 1) == 0)		// Red
	        {
            	red = pLine[x];
                expectedRed = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedBlue  = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedRed != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * red / expectedRed) / 2];
	                blue   = Conv_ColorRef[(expectedBlue + expectedBlue * red / expectedRed) / 2 * 3 / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                blue   = Conv_ColorRef[expectedBlue * 3 / 2];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
	        }
	        else				// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue = (pUpperLine[x]+pLowerLine[x])/2;
                expectedRed = (pLine[x-1]+pLine[x+1])/2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2 * 3 / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue * 3 / 2];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
	    else					// odd number line
	    {
	       	if ((x & 1) == 0)		// Green
	        {
            	green = pLine[x];
                expectedGreen = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                expectedBlue  = (pLine[x-1]+pLine[x+1]) / 2;
                expectedRed   = (pUpperLine[x]+pLowerLine[x])/2;
                if (expectedGreen != 0)
                {
	                blue = Conv_ColorRef[(expectedBlue + expectedBlue * green / expectedGreen) / 2 * 3 / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * green / expectedGreen) / 2];
                }
                else
                {
	                blue = Conv_ColorRef[expectedBlue * 3 / 2];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = blue;
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;

	        }
	        else				// Blue
	        {
            	blue = pLine[x];
                expectedBlue  = (pUpperLine2[x]+pLowerLine2[x]+pLine[x-2]+pLine[x+2])/4;
                expectedGreen = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
                expectedRed   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
                if (expectedBlue != 0)
                {
	                green = Conv_ColorRef[(expectedGreen + expectedGreen * blue / expectedBlue) / 2];
	                red  = Conv_ColorRef[(expectedRed + expectedRed * blue / expectedBlue) / 2];
                }
                else
                {
	                green = Conv_ColorRef[expectedGreen];
	                red  = Conv_ColorRef[expectedRed];
                }
                pColorLine[3*x]   = Conv_ColorRef[blue * 3 / 2];
                pColorLine[3*x+1] = green;
                pColorLine[3*x+2] = red;
            }
        }
    }

    x = bitmapWidth - 2;
   	if ((y & 1) == 0)			//	even number line
    {
       	if ((x & 1) == 0)		// Green
        {
           	pColorLine[3*x]   = (pUpperLine[x]+pLowerLine[x])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pLine[x-1]+pLine[x+1])/2;
        }
		else				// Blue
        {
           	pColorLine[3*x]   = pLine[x];
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
        }
    }
    else					// odd number line
    {
       	if ((x & 1) == 0)		// Red
        {
           	pColorLine[3*x]   = (pUpperLine[x-1]+pUpperLine[x+1]+pLowerLine[x-1]+pLowerLine[x+1])/4;
            pColorLine[3*x+1] = (pLine[x-1]+pLine[x+1]+pUpperLine[x]+pLowerLine[x])/4;
            pColorLine[3*x+2] = pLine[x];
        }
        else				// Green
        {
           	pColorLine[3*x]   = (pLine[x-1]+pLine[x+1])/2;
            pColorLine[3*x+1] = pLine[x];
            pColorLine[3*x+2] = (pUpperLine[x]+pLowerLine[x])/2;
        }
    }

    x = bitmapWidth - 1;
    pColorLine[x * 3] = pColorLine[x * 3 + 1] = pColorLine[x * 3 + 2] = 0xFF;
}
//---------------------------------------------------------------------------
void __fastcall Bayer_Conversion_GRBG(Graphics::TBitmap *ColorTBitmap, byte *bayerBitmap,
	int bitmapWidth, int bitmapHeight, int conversionMode)
{
	unsigned char *upperLine2, *upperLine, *line, *lowerLine, *lowerLine2;      // 참고 이미지의 pointor
    byte Conv_ColorRef[65536];
    InitBayerConstant(Conv_ColorRef);
    ColorTBitmap->Width = bitmapWidth;
    ColorTBitmap->Height = bitmapHeight;
    if (conversionMode == 0)
	{
		// first line
	   	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
	    memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
	    upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    pColorLine = (byte *)ColorTBitmap->ScanLine[1];
	    ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
        {
			pColorLine = (byte *)ColorTBitmap->ScanLine[y];
			ConvertBayerBitmapLine_Mode3_GRBG(pColorLine, upperLine2, upperLine,
            	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
	        line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
            lowerLine2 += bitmapWidth;
        }

        // before last line
        pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 2];
        ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
    	pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 1)
    {
		// first line
    	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

        pColorLine = (byte *)ColorTBitmap->ScanLine[1];
        ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
   	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
   	    {
			pColorLine = (byte *)ColorTBitmap->ScanLine[y];
			ConvertBayerBitmapLine_Mode2(pColorLine, upperLine2, upperLine,
       	    	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
    	    line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
   	        lowerLine2 += bitmapWidth;
       	}

        // before last line
   	    pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 2];
       	ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
   		pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
       	memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 2)
    {
    	// first line
    	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    	line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    for(int y = 1; y < bitmapHeight - 1; y++)                      // 보정
	    {
        	pColorLine = (byte *)ColorTBitmap->ScanLine[y];
            ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, y);

	        upperLine += bitmapWidth;
    	    line      += bitmapWidth;
	        lowerLine += bitmapWidth;
	    }

        // last line
   		pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
	}
}
//---------------------------------------------------------------------------
void __fastcall Bayer_Conversion_Merge(Graphics::TBitmap *ColorTBitmap, byte *bayerBitmap,
	int bitmapWidth, int bitmapHeight, int conversionMode)
{
	unsigned char *line, *lowerLine;      // 참고 이미지의 pointor
    ColorTBitmap->Width = bitmapWidth / 2;
    ColorTBitmap->Height = bitmapHeight / 2;

    line       = bayerBitmap;
    lowerLine  = line + bitmapWidth;
    for (int y = 0; y < bitmapHeight; y+= 2)
    {
        byte *pColorLine = (byte *)ColorTBitmap->ScanLine[y / 2];
        for(int x = 0; x < bitmapWidth; x+= 2)
        {
            pColorLine[0] = lowerLine[x];
            pColorLine[1] = (line[x] + lowerLine[x + 1]) / 2;
            pColorLine[2] = line[x + 1];
            pColorLine += 3;
        }
        line       += 2 * bitmapWidth;
        lowerLine  += 2 * bitmapWidth;
    }
}
//---------------------------------------------------------------------------
void __fastcall Bayer_Conversion_GBRG(Graphics::TBitmap *ColorTBitmap, byte *bayerBitmap,
	int bitmapWidth, int bitmapHeight, int conversionMode)
{
	unsigned char *upperLine2, *upperLine, *line, *lowerLine, *lowerLine2;      // 참고 이미지의 pointor
    byte Conv_ColorRef[65536];
    InitBayerConstant(Conv_ColorRef);
    ColorTBitmap->Width = bitmapWidth;
    ColorTBitmap->Height = bitmapHeight;
    if (conversionMode == 0)
	{
		// first line
	   	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
	    memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
	    upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    pColorLine = (byte *)ColorTBitmap->ScanLine[1];
	    ConvertBayerBitmapLine_Mode1_GBRG(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
        {
			pColorLine = (byte *)ColorTBitmap->ScanLine[y];
			ConvertBayerBitmapLine_Mode3_GBRG(pColorLine, upperLine2, upperLine,
            	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
	        line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
            lowerLine2 += bitmapWidth;
        }

        // before last line
        pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 2];
        ConvertBayerBitmapLine_Mode1_GBRG(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
    	pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 1)
    {
		// first line
    	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

        pColorLine = (byte *)ColorTBitmap->ScanLine[1];
        ConvertBayerBitmapLine_Mode1_GBRG(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
   	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
   	    {
			pColorLine = (byte *)ColorTBitmap->ScanLine[y];
			ConvertBayerBitmapLine_Mode2(pColorLine, upperLine2, upperLine,
       	    	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
    	    line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
   	        lowerLine2 += bitmapWidth;
       	}

        // before last line
   	    pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 2];
       	ConvertBayerBitmapLine_Mode1_GBRG(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
   		pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
       	memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 2)
    {
    	// first line
    	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    	line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    for(int y = 1; y < bitmapHeight - 1; y++)                      // 보정
	    {
        	pColorLine = (byte *)ColorTBitmap->ScanLine[y];
            ConvertBayerBitmapLine_Mode1_GBRG(pColorLine, upperLine, line, lowerLine, bitmapWidth, y);

	        upperLine += bitmapWidth;
    	    line      += bitmapWidth;
	        lowerLine += bitmapWidth;
	    }

        // last line
   		pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
	}
}
//---------------------------------------------------------------------------
void __fastcall Bayer_Conversion_RGGB(Graphics::TBitmap *ColorTBitmap, byte *bayerBitmap,
	int bitmapWidth, int bitmapHeight, int conversionMode)
{
	unsigned char *upperLine2, *upperLine, *line, *lowerLine, *lowerLine2;      // 참고 이미지의 pointor
    byte Conv_ColorRef[65536];
    InitBayerConstant(Conv_ColorRef);
    ColorTBitmap->Width = bitmapWidth;
    ColorTBitmap->Height = bitmapHeight;
    if (conversionMode == 0)
	{
		// first line
	   	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
	    memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
	    upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    pColorLine = (byte *)ColorTBitmap->ScanLine[1];
	    ConvertBayerBitmapLine_Mode1_RGGB(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
        {
			pColorLine = (byte *)ColorTBitmap->ScanLine[y];
			ConvertBayerBitmapLine_Mode3_RGGB(pColorLine, upperLine2, upperLine,
            	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
	        line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
            lowerLine2 += bitmapWidth;
        }

        // before last line
        pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 2];
        ConvertBayerBitmapLine_Mode1_RGGB(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
    	pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
}
//---------------------------------------------------------------------------
void __fastcall Bayer_Conversion_BGGR(Graphics::TBitmap *ColorTBitmap, byte *bayerBitmap,
	int bitmapWidth, int bitmapHeight, int conversionMode)
{
	unsigned char *upperLine2, *upperLine, *line, *lowerLine, *lowerLine2;      // 참고 이미지의 pointor
    byte Conv_ColorRef[65536];
    InitBayerConstant(Conv_ColorRef);
    ColorTBitmap->Width = bitmapWidth;
    ColorTBitmap->Height = bitmapHeight;
    if (conversionMode == 0)
	{
		// first line
	   	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
	    memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
	    upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    pColorLine = (byte *)ColorTBitmap->ScanLine[1];
	    ConvertBayerBitmapLine_Mode1_BGGR(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
        {
			pColorLine = (byte *)ColorTBitmap->ScanLine[y];
			ConvertBayerBitmapLine_Mode3_BGGR(pColorLine, upperLine2, upperLine,
            	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
	        line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
            lowerLine2 += bitmapWidth;
        }

        // before last line
        pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 2];
        ConvertBayerBitmapLine_Mode1_BGGR(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
    	pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 1)
    {
		// first line
    	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

        pColorLine = (byte *)ColorTBitmap->ScanLine[1];
        ConvertBayerBitmapLine_Mode1_BGGR(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
   	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
   	    {
			pColorLine = (byte *)ColorTBitmap->ScanLine[y];
			ConvertBayerBitmapLine_Mode2(pColorLine, upperLine2, upperLine,
       	    	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
    	    line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
   	        lowerLine2 += bitmapWidth;
       	}

        // before last line
   	    pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 2];
       	ConvertBayerBitmapLine_Mode1_BGGR(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
   		pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
       	memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 2)
    {
    	// first line
    	byte *pColorLine = (byte *)ColorTBitmap->ScanLine[0];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    	line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    for(int y = 1; y < bitmapHeight - 1; y++)                      // 보정
	    {
        	pColorLine = (byte *)ColorTBitmap->ScanLine[y];
            ConvertBayerBitmapLine_Mode1_BGGR(pColorLine, upperLine, line, lowerLine, bitmapWidth, y);

	        upperLine += bitmapWidth;
    	    line      += bitmapWidth;
	        lowerLine += bitmapWidth;
	    }

        // last line
   		pColorLine = (byte *)ColorTBitmap->ScanLine[bitmapHeight - 1];
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
	}
}
//---------------------------------------------------------------------------
void __fastcall Bayer_Conversion_To_ByteData(byte *colorBitmap, byte *bayerBitmap,
	int bitmapWidth, int bitmapHeight, int conversionMode)
{
	unsigned char *upperLine2, *upperLine, *line, *lowerLine, *lowerLine2;      // 참고 이미지의 pointor
    byte Conv_ColorRef[65536];
    InitBayerConstant(Conv_ColorRef);
    if (conversionMode == 0)
	{
		// first line
	   	byte *pColorLine = colorBitmap;
	    memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
	    upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    pColorLine = colorBitmap + bitmapWidth * 3;
	    ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
        {
			pColorLine = colorBitmap + y * bitmapWidth * 3;
			ConvertBayerBitmapLine_Mode3_GRBG(pColorLine, upperLine2, upperLine,
            	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
	        line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
            lowerLine2 += bitmapWidth;
        }

        // before last line
        pColorLine = colorBitmap + (bitmapHeight - 2) * bitmapWidth * 3;
        ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
    	pColorLine = colorBitmap + (bitmapHeight - 1) * bitmapWidth * 3;
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 1)
    {
		// first line
    	byte *pColorLine = colorBitmap;
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
		// second line
	    line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

        pColorLine = colorBitmap + bitmapWidth * 3;
        ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, 1);

	    line       = bayerBitmap + 2 * bitmapWidth;
	    upperLine  = line - bitmapWidth;
   	    upperLine2 = upperLine - bitmapWidth;
	    lowerLine  = line + bitmapWidth;
        lowerLine2 = lowerLine + bitmapWidth;

        for (int y = 2; y < bitmapHeight - 2; y++)
   	    {
			pColorLine = colorBitmap + y * bitmapWidth * 3;
			ConvertBayerBitmapLine_Mode2(pColorLine, upperLine2, upperLine,
       	    	line, lowerLine, lowerLine2, bitmapWidth, y, Conv_ColorRef);

            upperLine2 += bitmapWidth;
	        upperLine  += bitmapWidth;
    	    line       += bitmapWidth;
	        lowerLine  += bitmapWidth;
   	        lowerLine2 += bitmapWidth;
       	}

        // before last line
   	    pColorLine = colorBitmap + (bitmapHeight - 2) * bitmapWidth * 3;
       	ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, bitmapHeight - 2);
        // last line
   		pColorLine = colorBitmap + (bitmapHeight - 1) * bitmapWidth * 3;
       	memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    }
    else if (conversionMode == 2)
    {
    	// first line
    	byte *pColorLine = colorBitmap;
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
    	line        = bayerBitmap + bitmapWidth;
        upperLine   = line - bitmapWidth;
	    lowerLine   = line + bitmapWidth;

	    for(int y = 1; y < bitmapHeight - 1; y++)                      // 보정
	    {
        	pColorLine = colorBitmap + y * bitmapWidth * 3;
            ConvertBayerBitmapLine_Mode1_GRBG(pColorLine, upperLine, line, lowerLine, bitmapWidth, y);

	        upperLine += bitmapWidth;
    	    line      += bitmapWidth;
	        lowerLine += bitmapWidth;
	    }

        // last line
   		pColorLine = colorBitmap + (bitmapHeight - 1) * bitmapWidth * 3;
        memset(pColorLine, 0xFF, bitmapWidth * 3); // fill white
	}
}
//---------------------------------------------------------------------------
