void TestImageColourStruct(void)
{
	SImageColour	sColour;
	int				i;

	sColour.Full();

	sColour.c[0] = 0;
	AssertBool(TRUE, sColour.IsZero(1));

	sColour.c[0] = 3;
	AssertBool(FALSE, sColour.IsZero(1));

	sColour.c[0] = 0xff;

	for (i = 0; i < MAX_IMAGE_COLOUR_BYTES; i++)
	{
		sColour.c[i] = 0;
		AssertBool(TRUE, sColour.IsZero(i+1));
	}

	for (i = MAX_IMAGE_COLOUR_BYTES-1; i >= 0; i--)
	{
		sColour.c[i] = 0xff;
		AssertBool(FALSE, sColour.IsZero(i+1));
	}

	sColour.Zero();
	AssertBool(TRUE, sColour.IsZero(8));

}
void TestIndexesSomething(void)
{
	CIndexes		cIndexes;
	char			szOne[] = "One";
	char			szTwo[] = "Two";
	char			szThree[] = "Three";
	char			szFour[] = "Four";
	char*			szTemp;
	BOOL			bResult;

	cIndexes.Init(512);

	AssertInt(0, cIndexes.TestNumLevels());

	cIndexes.Add(17LL, szOne);
	szTemp = (char*)cIndexes.Get(17LL);
	AssertString(szOne, szTemp);
	AssertInt(7, cIndexes.TestNumLevels());

	szTemp = (char*)cIndexes.Get(268472648234LL);
	AssertNull(szTemp);

	cIndexes.Add(268472648234LL, szTwo);
	szTemp = (char*)cIndexes.Get(268472648234LL);
	AssertString(szTwo, szTemp);
	AssertInt(11, cIndexes.TestNumLevels());

	szTemp = (char*)cIndexes.Get(268472648233LL);
	AssertNull(szTemp);

	cIndexes.Add(268472648233LL, szThree);
	szTemp = (char*)cIndexes.Get(268472648233LL);
	AssertString(szThree, szTemp);
	AssertInt(11, cIndexes.TestNumLevels());
	szTemp = (char*)cIndexes.Get(268472648234LL);
	AssertString(szTwo, szTemp);

	bResult = cIndexes.Add(17LL, szFour);
	AssertFalse(bResult);
	szTemp = (char*)cIndexes.Get(17LL);
	AssertString(szOne, szTemp);
	AssertInt(11, cIndexes.TestNumLevels());

	bResult = cIndexes.Remove(17LL);
	AssertBool(TRUE, bResult)
	szTemp = (char*)cIndexes.Get(17LL);
	AssertNull(szTemp);
	AssertInt(7, cIndexes.TestNumLevels());

	bResult = cIndexes.Remove(268472648233LL);
	AssertBool(TRUE, bResult);
	AssertInt(7, cIndexes.TestNumLevels());
	bResult = cIndexes.Remove(268472648234LL);
	AssertBool(TRUE, bResult);
	AssertInt(0, cIndexes.TestNumLevels());
}
void TestImageColourAccessorBytes(void)
{
	CImageColourRGB		cRGB; 
	CImageColourOpacity	cAlpha;
	CImageColourCombo2	cColour;
	CChannels*			pcChannels;
	CImageAccessor*		pcAccessor;
	CImage				cImage;
	SImageColour		sDest;
	BOOL				bResult;
	char*				pvData;

	cRGB.Init(1.0f, 0.5f, 0.25f);
	cAlpha.Init(0.333f);
	cColour.Init(&cRGB, &cAlpha);

	cImage.Init(10, 10, PT_uchar,	IMAGE_DIFFUSE_GREEN,	//0x7f
									IMAGE_NORMAL_Y,		
									IMAGE_DIFFUSE_BLUE,	//0x3f
									IMAGE_OPACITY,		//0x54
									IMAGE_DIFFUSE_RED,	//0xff
									IMAGE_MASK, 
									CHANNEL_ZERO);
	cImage.Clear();

	pcAccessor = CImageAccessorCreator::Create(&cImage, PT_uchar, IMAGE_OPACITY, IMAGE_DIFFUSE_RED, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_BLUE, CHANNEL_ZERO);

	sDest.Full();
	bResult = pcAccessor->MakeColour(&sDest, &cColour);
	AssertBool(TRUE, bResult);

	//Remember ints have reverse endiannes which is why the test number below looks backwarsd.
	AssertIntHex(0x3f7fff54, *(int*)((void*)sDest.c));

	pcAccessor->Set(1, 0, &sDest);
	pcAccessor->Kill();

	pcChannels = &cImage.mcChannels;

	pvData = pcChannels->GetData();

	//First pixel.  Didn't touch it.
	AssertChar(0x00, pvData[0x0]);
	AssertChar(0x00, pvData[0x1]);
	AssertChar(0x00, pvData[0x2]);
	AssertChar(0x00, pvData[0x3]);
	AssertChar(0x00, pvData[0x4]);
	AssertChar(0x00, pvData[0x5]);

	//Second pixel.
	AssertChar(0x7f, pvData[0x6]);
	AssertChar(0x00, pvData[0x7]);
	AssertChar(0x3f, pvData[0x8]);
	AssertChar(0x54, pvData[0x9]);
	AssertChar((char)0xff, pvData[0xa]);
	AssertChar(0x00, pvData[0xb]);
}
void TestImageReaderRAD(void)
{
	CImage			cImage;
	BOOL			bResult;

	bResult = ReadImage(&cImage, "Input\\readrad.rad");
	AssertBool(TRUE, bResult);
	WriteImage(&cImage, "Output\\readrad.raw");
	AssertFileMemory("input\\readrad.raw", cImage.GetData(), cImage.GetByteSize());
	cImage.Kill();

	//Read raw is a special case.  Because the size and the channels aren't known the image must be initialised before hand.
	cImage.Init(32, 48, PT_uchar, IMAGE_DIFFUSE_RED, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_BLUE, CHANNEL_ZERO);
	bResult = ReadImage(&cImage, "Input\\readrad.raw");
	AssertBool(TRUE, bResult);
	WriteImage(&cImage, "Output\\readraw.raw");
	AssertFileMemory("input\\readraw.raw", cImage.GetData(), cImage.GetByteSize());
	cImage.Kill();
}
void TestImageModifierStack(void)
{
	BeginTests();

	CImage					cImage;
	CImageModifierStack		cStack;
	BOOL					bResult;
	CImageRGBToGrey*		pcGrey;
	CImageHeightToNormals*	pcNormals;
	CImageResampler*		pcSmall;
	CImage					cBak;

	bResult = ReadImage(&cBak, "Input/Adelle.png");
	AssertBool(TRUE, bResult);

	cImage.Copy(&cBak);
	cStack.Init(&cImage);

	pcGrey = cStack.AddModifier<CImageRGBToGrey>();
	pcGrey->Init(RGBTGS_UseRed);
	cStack.ApplyAll();

	WriteImage(&cImage, "Output/AdelleGrey.raw");
	AssertFileMemory("Input/AdelleGrey.raw", cImage.GetData(), cImage.GetByteSize());
	cImage.Kill();

	pcNormals = cStack.AddModifier<CImageHeightToNormals>();
	pcNormals->Init(IMAGE_DIFFUSE_GREY);
	cImage.Copy(&cBak);
	cStack.ApplyAll();

	WriteImage(&cImage, "Output/AdelleNormal.raw");
	AssertFileMemory("Input/AdelleNormal.raw", cImage.GetData(), cImage.GetByteSize());
	cImage.Kill();

	pcSmall = cStack.AddModifier<CImageResampler>();
	pcSmall->Init(IR_NearestNeighbour, 21, 16);
	cImage.Copy(&cBak);
	cStack.ApplyAll();

	WriteImage(&cImage, "Output/AdelleSmall.raw");
	AssertFileMemory("Input/AdelleSmall.raw", cImage.GetData(), cImage.GetByteSize());
	AssertInt(3, cStack.NumModifiers());

	cStack.Kill();
	cImage.Kill();

	cBak.Kill();

	TestStatistics();
}
void TestImageColourMultiAccessor(void)
{
	CImageColourNormal		cNormal;
	CImageColourOpacity		cAlpha;
	CImageColourCombo2		cColour;
	CChannels*				pcChannels;
	CImageAccessor*			pcAccessor;
	CImage					cImage;
	SImageColour			sDest;
	BOOL					bResult;

	cNormal.Init(0.7f, -0.6f, -0.5f);
	cAlpha.Init(0.333f);
	cColour.Init(&cNormal, &cAlpha);

	cImage.Init();
	cImage.BeginChange();
	cImage.AddChannel(IMAGE_DIFFUSE_GREEN, PT_uchar);
	cImage.AddChannel(IMAGE_NORMAL_Y, PT_float);
	cImage.AddChannel(IMAGE_DIFFUSE_BLUE, PT_uchar);
	cImage.AddChannel(IMAGE_OPACITY, PT_ushort);
	cImage.AddChannel(IMAGE_DIFFUSE_RED, PT_uchar);
	cImage.AddChannel(IMAGE_MASK, PT_int);
	cImage.AddChannel(IMAGE_NORMAL_Z, PT_float);
	cImage.AddChannel(IMAGE_NORMAL_X, PT_float);
	cImage.SetSize(1, 2);
	cImage.EndChange();
	cImage.Clear();

	pcAccessor = CImageAccessorCreator::Create(&cImage, IMAGE_NORMAL_X, IMAGE_NORMAL_Y, IMAGE_NORMAL_Z, IMAGE_OPACITY, CHANNEL_ZERO);

	sDest.Full();
	bResult = pcAccessor->MakeColour(&sDest, &cColour);
	AssertBool(TRUE, bResult);

	AssertFloat(0.7f, *((float*)&((sDest).c)[0x0]), 3);
	AssertFloat(-0.6f, *((float*)&((sDest).c)[0x4]), 3);
	AssertFloat(-0.5f, *((float*)&((sDest).c)[0x8]), 3);
	AssertShortHex(0x553f, *((unsigned short*)&((sDest).c)[0xc]));

	pcAccessor->Set(0, 1, &sDest);
	pcAccessor->Kill();

	pcChannels = &cImage.mcChannels;
	AssertFloat(-0.6f, *(float*)&(pcChannels->GetData()[22]), 3);
	AssertFloat( 0.7f, *(float*)&(pcChannels->GetData()[38]), 3);
	AssertFloat(-0.5f, *(float*)&(pcChannels->GetData()[34]), 3);
	AssertShortHex(0x553f, *(unsigned short*)&(pcChannels->GetData()[27]));
}
void TestImageColourAccessorFloats(void)
{
	CImageColourNormal	cNormal;
	CChannels*			pcChannels;
	CImageAccessor*		pcAccessor;
	CImage				cImage;
	SImageColour		sDest;
	BOOL				bResult;

	cNormal.Init(0.7f, 0.6f, 0.5f);
	cImage.Init();
	cImage.BeginChange();
	cImage.AddChannel(IMAGE_DIFFUSE_GREEN, PT_uchar);
	cImage.AddChannel(IMAGE_NORMAL_Y, PT_float);
	cImage.AddChannel(IMAGE_DIFFUSE_BLUE, PT_uchar);
	cImage.AddChannel(IMAGE_OPACITY, PT_short);
	cImage.AddChannel(IMAGE_DIFFUSE_RED, PT_uchar);
	cImage.AddChannel(IMAGE_MASK, PT_int);
	cImage.AddChannel(IMAGE_NORMAL_Z, PT_float);
	cImage.AddChannel(IMAGE_NORMAL_X, PT_float);
	cImage.SetSize(1, 2);
	cImage.EndChange();
	cImage.Clear();

	pcAccessor = CImageAccessorCreator::Create(&cImage, PT_float, IMAGE_NORMAL_X, IMAGE_NORMAL_Y, IMAGE_NORMAL_Z, CHANNEL_ZERO);

	sDest.Full();
	bResult = pcAccessor->MakeColour(&sDest, &cNormal);
	AssertBool(TRUE, bResult);

	AssertFloat(0.7f, *((float*)&((sDest).c)[0x0]), 3);
	AssertFloat(0.6f, *((float*)&((sDest).c)[0x4]), 3);
	AssertFloat(0.5f, *((float*)&((sDest).c)[0x8]), 3);

	pcAccessor->Set(0, 1, &sDest);
	pcAccessor->Kill();

	pcChannels = &cImage.mcChannels;
	
	AssertFloat(0.6f, *(float*)&(pcChannels->GetData()[22]), 3);
	AssertFloat(0.7f, *(float*)&(pcChannels->GetData()[38]), 3);
	AssertFloat(0.5f, *(float*)&(pcChannels->GetData()[34]), 3);
}
void TestImageCelCropBorders(void)
{
	CImageCel	cCel;
	CImage		cImage;

	ReadImage(&cImage, "Input\\cel1.png");
	cCel.Init(&cImage);
	cCel.CropTransparentBorders();

	AssertInt(24, cCel.GetSubImage()->GetFullWidth());
	AssertInt(24, cCel.GetSubImage()->GetImageWidth());
	AssertInt(24, cCel.GetSubImage()->GetFullHeight());
	AssertInt(24, cCel.GetSubImage()->GetImageHeight());

	cCel.Kill();
	cImage.Kill();

	ReadImage(&cImage, "Input\\cel2.png");
	cCel.Init(&cImage);
	cCel.CropTransparentBorders();

	AssertInt(24, cCel.GetSubImage()->GetFullWidth());
	AssertInt(21, cCel.GetSubImage()->GetImageWidth());
	AssertInt(24, cCel.GetSubImage()->GetFullHeight());
	AssertInt(18, cCel.GetSubImage()->GetImageHeight());
	AssertInt(1, cCel.GetSubImage()->mcImageRect.miLeft);
	AssertInt(3, cCel.GetSubImage()->mcImageRect.miTop);

	ReadImage(&cImage, "Input\\cel3.png");
	cCel.Init(&cImage);
	cCel.CropTransparentBorders();

	AssertInt(24, cCel.GetSubImage()->GetFullWidth());
	AssertInt(0, cCel.GetSubImage()->GetImageWidth());
	AssertInt(24, cCel.GetSubImage()->GetFullHeight());
	AssertInt(0, cCel.GetSubImage()->GetImageHeight());
	AssertBool(TRUE, cCel.GetSubImage()->IsImageEmpty());

	cCel.Kill();
	cImage.Kill();
}