Example #1
0
int main(int argc, char* argv[])
{
//  imFormatRegisterJP2();
//  imFormatRegisterAVI();
//  imFormatRegisterWMV();   

  if (argc < 2)
  {
    printf("Invalid number of arguments.\n");
    return 0;
  }

  PrintImageInfo(argv[1]);

  return 1;
}
Example #2
0
void ConvertFile(const char* Dir, const char* Filename, double MaxMSE)
{
	HRESULT hr;
	LPDIRECT3DSURFACE8 pSrcSurf = NULL;
	char OutFilename[52];
	if (Dir)
		_snprintf(OutFilename, 52, "%s\\%s", Dir, Filename);
	else
		_snprintf(OutFilename, 52, "%s", Filename);
	OutFilename[51] = 0;

	printf("%s: ", OutFilename);
	TRACE1("%s:\n", OutFilename);
	int n = strlen(OutFilename);
	if (n < 40)
		printf("%*c", 40-n, ' ');

	if (pSrcSurf)
		pSrcSurf->Release();
	pSrcSurf = NULL;

	// Load up the file
	D3DXIMAGE_INFO info;
	hr = D3DXGetImageInfoFromFile(Filename, &info);
	CheckHR(hr);

	PrintImageInfo(info);

	UINT Width = PadPow2(info.Width);
	UINT Height = PadPow2(info.Height);

	float Waste = 100.f * (float)(Width * Height - info.Width * info.Height) / (float)(Width * Height);

	UncompressedSize += Width * Height * 4;
	TotalSrcPixels += info.Width * info.Height;
	TotalDstPixels += Width * Height;

  // Special case for 256-colour files - just directly drop into a P8 xpr
	if (info.Format == D3DFMT_P8)
	{
		hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pSrcSurf);
		CheckHR(hr);

		hr = D3DXLoadSurfaceFromFile(pSrcSurf, NULL, NULL, Filename, NULL, D3DX_FILTER_NONE, 0, NULL);
		CheckHR(hr);

		FixTransparency(pSrcSurf);

		if (Width * Height > 4096)
		{
			// DXT1 for P8s if lossless and more than 4k image
			LPDIRECT3DSURFACE8 pTempSurf;
			hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pTempSurf);
			CheckHR(hr);

			hr = D3DXLoadSurfaceFromSurface(pTempSurf, NULL, NULL, pSrcSurf, NULL, NULL, D3DX_FILTER_NONE, 0);
			CheckHR(hr);

			double CMSE, AMSE;
			TRACE0(" Checking     DXT1: ");
			if (!GetFormatMSE(info, pTempSurf, D3DFMT_DXT1, CMSE, AMSE))
			{
				pTempSurf->Release();
				return;
			}
			TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE);
			if (CMSE <= 1e-6 && AMSE <= 1e-6)
			{
				printf("DXT1     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
				TRACE0(" Selected Format: DXT1\n");
				WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_DXT1, NULL);

				pTempSurf->Release();
				return;
			}
			pTempSurf->Release();
		}

		printf("P8       %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: P8\n");

		LPDIRECT3DSURFACE8 pTempSurf;
		DWORD pal[256];
		ConvertP8(pSrcSurf, pTempSurf, pal, info);

		WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_P8, pal);
		pTempSurf->Release();
		return;
	}

  // test linear format versus non-linear format
  // Linear format requires 64 pixel aligned width, whereas
  // Non-linear format requires power of 2 width and height
  bool useLinearFormat(false);
  UINT linearWidth = (info.Width + 0x3f) & ~0x3f;
  if (AllowLinear && linearWidth * info.Height < Width * Height)
    useLinearFormat = true;

	hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pSrcSurf);
	CheckHR(hr);
  
	hr = D3DXLoadSurfaceFromFile(pSrcSurf, NULL, NULL, Filename, NULL, D3DX_FILTER_NONE, 0, NULL);
	CheckHR(hr);

  // create the linear version as well
	LPDIRECT3DSURFACE8 pLinearSrcSurf = NULL;
  if (useLinearFormat)
  {
	  hr = pD3DDevice->CreateImageSurface(linearWidth, info.Height, D3DFMT_A8R8G8B8, &pLinearSrcSurf);
	  CheckHR(hr);
	  hr = D3DXLoadSurfaceFromFile(pLinearSrcSurf, NULL, NULL, Filename, NULL, D3DX_FILTER_NONE, 0, NULL);
	  CheckHR(hr);
  }


	// special case for small files - all textures are alloced on page granularity so just output uncompressed
	// dxt is crap on small files anyway
	if (Width * Height <= 1024)
	{
    if (useLinearFormat)
    {
      // correct sizing amounts
	    UncompressedSize -= Width * Height * 4;
      UncompressedSize += linearWidth * info.Height * 4;
	    TotalDstPixels -= Width * Height;
      TotalDstPixels += linearWidth * info.Height;

	    Waste = 100.f * (float)(linearWidth * info.Height - info.Width * info.Height) / (float)(linearWidth * info.Height);
		  printf("LIN_A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", linearWidth, info.Height, Waste);
		  TRACE0(" Selected Format: LIN_A8R8G8B8\n");
      WriteXPR(OutFilename, info, pLinearSrcSurf, XB_D3DFMT_LIN_A8R8G8B8, NULL);
    }
    else
    {
		  printf("A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		  TRACE0(" Selected Format: A8R8G8B8\n");
      WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_A8R8G8B8, NULL);
    }
		return;
	}

	FixTransparency(pSrcSurf);

	// Find the best format within specified tolerance
	double CMSE, AMSE[2];

	// DXT1 is the preferred format as it's smallest
	TRACE0(" Checking     DXT1: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT1, CMSE, AMSE[0]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[0]);
	if (CMSE <= MaxMSE && AMSE[0] <= MaxMSE)
	{
		printf("DXT1     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: DXT1\n");

		WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_DXT1, NULL);
		return;
	}

	// Use P8 is possible as it's lossless
	LPDIRECT3DSURFACE8 pTempSurf;
	DWORD pal[256];
	if (ConvertP8(pSrcSurf, pTempSurf, pal, info))
	{
		printf("P8       %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: P8\n");

		WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_P8, pal);
		pTempSurf->Release();
		return;
	}

	// DXT3/5 are the same size so use whichever is better if good enough
	// CMSE will be equal for both
	TRACE0(" Checking     DXT3: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT3, CMSE, AMSE[0]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[0]);

	TRACE0(" Checking     DXT5: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT5, CMSE, AMSE[1]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[1]);

	if (AMSE[0] <= AMSE[1])
	{
		if (CMSE <= MaxMSE && AMSE[0] <= MaxMSE)
		{
			printf("DXT3     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
			TRACE0(" Selected Format: DXT3\n");

			WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_DXT3, NULL);
			return;
		}
	}
	else
	{
		if (CMSE <= MaxMSE && AMSE[1] <= MaxMSE)
		{
			printf("DXT5     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
			TRACE0(" Selected Format: DXT5\n");

			WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_DXT5, NULL);
			return;
		}
	}

	// No good compressed format so use uncompressed

	// A1R5G5B5 is worth a try I guess...
	TRACE0(" Checking A1R5G5B5: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_A1R5G5B5, CMSE, AMSE[0]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[0]);
	if (CMSE <= MaxMSE && AMSE[0] <= MaxMSE)
	{
		printf("A1R5G5B5 %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: A1R5G5B5\n");

		LPDIRECT3DSURFACE8 pTempSurf;
		hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A1R5G5B5, &pTempSurf);
		CheckHR(hr);

		hr = D3DXLoadSurfaceFromSurface(pTempSurf, NULL, NULL, pSrcSurf, NULL, NULL, D3DX_FILTER_NONE, 0);
		CheckHR(hr);

		WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_A1R5G5B5, NULL);

		pTempSurf->Release();
		return;
	}

	// Use A8R8G8B8
  if (useLinearFormat)
  {
    // correct sizing information
	  UncompressedSize -= Width * Height * 4;
    UncompressedSize += linearWidth * info.Height * 4;
	  TotalDstPixels -= Width * Height;
    TotalDstPixels += linearWidth * info.Height;
	  Waste = 100.f * (float)(linearWidth * info.Height - info.Width * info.Height) / (float)(linearWidth * info.Height);
		printf("LIN_A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", linearWidth, info.Height, Waste);
		TRACE0(" Selected Format: LIN_A8R8G8B8\n");
    WriteXPR(OutFilename, info, pLinearSrcSurf, XB_D3DFMT_LIN_A8R8G8B8, NULL);
  }
  else
  {
		printf("A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: A8R8G8B8\n");
    WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_A8R8G8B8, NULL);
  }

	if (pSrcSurf)
		pSrcSurf->Release();
}