예제 #1
0
bool GetFormatMSE(const D3DXIMAGE_INFO& info, LPDIRECT3DSURFACE8 pSrcSurf, D3DFORMAT fmt, double& CMSE, double& AMSE)
{
	LPDIRECT3DSURFACE8 pCompSurf = 0, pDstSurf = 0;
	HRESULT hr;

	// Compress
	int Width = PadPow2(info.Width), Height = PadPow2(info.Height);
	hr = pD3DDevice->CreateImageSurface(Width, Height, fmt, &pCompSurf);
	CheckHR(hr);

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

	// Decompress
	hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pDstSurf);
	CheckHR(hr);

	hr = D3DXLoadSurfaceFromSurface(pDstSurf, NULL, NULL, pCompSurf, NULL, NULL, D3DX_FILTER_NONE, 0);
	CheckHR(hr);

	pCompSurf->Release(); pCompSurf = 0;

	// calculate mean square error
	D3DLOCKED_RECT slr, dlr;
	hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
	CheckHR(hr);
	hr = pDstSurf->LockRect(&dlr, NULL, D3DLOCK_READONLY);
	CheckHR(hr);

	double CTSE = 0.0; // total colour square error
	double ATSE = 0.0; // total alpha square error

	RGBCOLOUR* src = (RGBCOLOUR*)slr.pBits;
	RGBCOLOUR* dst = (RGBCOLOUR*)dlr.pBits;
	for (UINT y = 0; y < info.Height; ++y)
	{
		for (UINT x = 0; x < info.Width; ++x)
		{
			CTSE += (src->b - dst->b) * (src->b - dst->b);
			CTSE += (src->g - dst->g) * (src->g - dst->g);
			CTSE += (src->r - dst->r) * (src->r - dst->r);
			ATSE += (src->a - dst->a) * (src->a - dst->a);
			++src; ++dst;
		}
		src += (slr.Pitch - info.Width*sizeof(RGBCOLOUR)) / sizeof(RGBCOLOUR);
		dst += (dlr.Pitch - info.Width*sizeof(RGBCOLOUR)) / sizeof(RGBCOLOUR);
	}
	CMSE = CTSE / double(info.Width * info.Height * 3);
	AMSE = ATSE / double(info.Width * info.Height);

	pSrcSurf->UnlockRect();
	pDstSurf->UnlockRect();
	pDstSurf->Release(); pDstSurf = 0;

	return true;
}
예제 #2
0
int LoadBitmapToSurface(char* PathName, LPDIRECT3DSURFACE8* ppSurface, LPDIRECT3DDEVICE8 pDevice){
	HRESULT r;
	HBITMAP hBitmap;
	BITMAP Bitmap;

	hBitmap = (HBITMAP)LoadImage(NULL, PathName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
	if(hBitmap == NULL){
		SetError("Unable to load bitmap");
		return E_FAIL;
	}

	GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
	DeleteObject(hBitmap);//we only needed it for the header info to create a D3D surface

	//create surface for bitmap
	r=pDevice->CreateImageSurface(Bitmap.bmWidth, Bitmap.bmHeight, D3DFMT_X8R8G8B8, ppSurface);
	if(FAILED(r)){
		SetError("Unable to create surface for bitmap load");
		return E_FAIL;
	}

	//load bitmap onto surface
	r = D3DXLoadSurfaceFromFile(*ppSurface, NULL, NULL, PathName, NULL, D3DX_FILTER_NONE, 0, NULL);
	if(FAILED(r)){
		SetError("Unable to laod file to surface");
		return E_FAIL;
	}

	return S_OK;
}
예제 #3
0
RageSurface* RageDisplay_D3D::CreateScreenshot()
{
#if defined(XBOX)
	return NULL;
#else
	/* Get the back buffer. */
	IDirect3DSurface8* pSurface;
	g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pSurface );

	/* Get the back buffer description. */
	D3DSURFACE_DESC desc;
	pSurface->GetDesc( &desc );

	/* Copy the back buffer into a surface of a type we support. */
	IDirect3DSurface8* pCopy;
	g_pd3dDevice->CreateImageSurface( desc.Width, desc.Height, D3DFMT_A8R8G8B8, &pCopy );

	D3DXLoadSurfaceFromSurface( pCopy, NULL, NULL, pSurface, NULL, NULL, D3DX_DEFAULT, 0 );

	pSurface->Release();

	/* Update desc from the copy. */
	pCopy->GetDesc( &desc );

	D3DLOCKED_RECT lr;

	{
		RECT rect; 
		rect.left = 0;
		rect.top = 0;
		rect.right = desc.Width;
		rect.bottom = desc.Height;
		pCopy->LockRect( &lr, &rect, D3DLOCK_READONLY );
	}

	RageSurface *surface = CreateSurfaceFromPixfmt( FMT_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch);
	ASSERT( surface );

	/* We need to make a copy, since lr.pBits will go away when we call UnlockRect(). */
	RageSurface *SurfaceCopy = 
		CreateSurface( surface->w, surface->h,
			surface->format->BitsPerPixel,
			surface->format->Rmask, surface->format->Gmask,
			surface->format->Bmask, surface->format->Amask );
	RageSurfaceUtils::CopySurface( surface, SurfaceCopy );
	delete surface;

	pCopy->UnlockRect();
	pCopy->Release();

	return SurfaceCopy;
#endif
}
RageSurface* RageDisplay_D3D::CreateScreenshot()
{
	// Get the back buffer.
	IDirect3DSurface8* pSurface;
	g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pSurface );

	// Get the back buffer description.
	D3DSURFACE_DESC desc;
	pSurface->GetDesc( &desc );

	// Copy the back buffer into a surface of a type we support.
	IDirect3DSurface8* pCopy;
	g_pd3dDevice->CreateImageSurface( desc.Width, desc.Height, D3DFMT_A8R8G8B8, &pCopy );
	
	// Aldo_MX: D3DXLoadSurfaceFromSurface requires d3dx8core.h, I replaced it with CopyRects to
	// remove this dependency so its possible to compile SM with any DirectX SDK up to Aug 2007
	D3DXLoadSurfaceFromSurface( pCopy, NULL, NULL, pSurface, NULL, NULL, D3DX_DEFAULT, 0 );
	//g_pd3dDevice->CopyRects( pSurface, NULL, 0, pCopy, NULL );

	pSurface->Release();

	// Update desc from the copy.
	pCopy->GetDesc( &desc );

	D3DLOCKED_RECT lr;

	{
		RECT rect; 
		rect.left = 0;
		rect.top = 0;
		rect.right = desc.Width;
		rect.bottom = desc.Height;
		pCopy->LockRect( &lr, &rect, D3DLOCK_READONLY );
	}

	RageSurface *surface = CreateSurfaceFromPixfmt( PixelFormat_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch);
	ASSERT( surface );

	// We need to make a copy, since lr.pBits will go away when we call UnlockRect().
	RageSurface *SurfaceCopy = 
		CreateSurface( surface->w, surface->h,
			surface->format->BitsPerPixel,
			surface->format->Rmask, surface->format->Gmask,
			surface->format->Bmask, surface->format->Amask );
	RageSurfaceUtils::CopySurface( surface, SurfaceCopy );
	delete surface;

	pCopy->UnlockRect();
	pCopy->Release();

	return SurfaceCopy;
}
예제 #5
0
// only works for gifs or other 256-colour anims
void ConvertAnim(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, ' ');

	// Load up the file
	CAnimatedGifSet Anim;
	int nImages = Anim.LoadGIF(Filename);
	if (!nImages)
	{
		puts("ERROR: Unable to load gif (file corrupt?)");
		return;
	}
	if (nImages > 65535)
	{
		printf("ERROR: Too many frames in gif (%d > 65535)\n", nImages);
		return;
	}

	PrintAnimInfo(Anim);

	UINT Width = PadPow2(Anim.FrameWidth);
	UINT Height = PadPow2(Anim.FrameHeight);

	D3DXIMAGE_INFO info;
	info.Width = Anim.FrameWidth;
	info.Height = Anim.FrameHeight;
	info.MipLevels = 1;
	info.Depth = 0;
	info.ResourceType = D3DRTYPE_SURFACE;
	info.Format = D3DFMT_P8;
	info.ImageFileFormat = D3DXIFF_PNG;

	PALETTEENTRY pal[256];
	memcpy(pal, Anim.m_vecimg[0]->Palette, 256 * sizeof(PALETTEENTRY));
	for (int i = 0; i < 256; i++)
		pal[i].peFlags = 0xff; // alpha
	if (Anim.m_vecimg[0]->Transparency && Anim.m_vecimg[0]->Transparent >= 0)
		memset(&pal[Anim.m_vecimg[0]->Transparent], 0, sizeof(PALETTEENTRY));

	// setup xpr header
	WriteXPRHeader((DWORD*)pal, nImages);
	if (nImages > 1)
	{
		XPRFile.AnimInfo->RealSize = (info.Width & 0xffff) | ((info.Height & 0xffff) << 16);
		XPRFile.AnimInfo->nLoops = Anim.nLoops;
	}

	int nActualImages = 0;

	TotalSrcPixels += info.Width * info.Height * nImages;
	TotalDstPixels += Width * Height * nImages;
	float Waste = 100.f * (float)(Width * Height - info.Width * info.Height) / (float)(Width * Height);

	// alloc hash buffer
	BYTE (*HashBuf)[20] = new BYTE[nImages][20];

	for (int i = 0; i < nImages; ++i)
	{
		if (pSrcSurf)
			pSrcSurf->Release();
		pSrcSurf = NULL;

		printf("%3d%%\b\b\b\b", 100 * i / nImages);

		UncompressedSize += Width * Height;
		CAnimatedGif* pGif = Anim.m_vecimg[i];

		if (nImages > 1)
			XPRFile.Texture[i].RealSize = pGif->Delay;

		// generate sha1 hash
		SHA1((BYTE*)pGif->Raster, pGif->BytesPerRow * pGif->Height, HashBuf[i]);

		// duplicate scan
		int j;
		for (j = 0; j < i; ++j)
		{
			if (!memcmp(HashBuf[j], HashBuf[i], 20))
			{
				// duplicate image!
				TRACE2(" %03d: Duplicate of %03d\n", i, j);
				AppendXPRImageLink(j);
				break;
			}
		}
		if (j < i)
			continue;

		++nActualImages;

		// DXT1 for P8s if lossless
		hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pSrcSurf);
		CheckHR(hr);

		D3DLOCKED_RECT slr;
		hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
		CheckHR(hr);

		BYTE* src = (BYTE*)pGif->Raster;
		DWORD* dst = (DWORD*)slr.pBits;
		DWORD* dwPal = (DWORD*)pal;
		for (int y = 0; y < pGif->Height; ++y)
		{
			for (UINT x = 0; x < Width; ++x)
				*dst++ = dwPal[*src++];
		}
		memset(dst, 0, (Height - pGif->Height) * slr.Pitch);

		pSrcSurf->UnlockRect();

		double CMSE, AMSE;
		TRACE1(" %03d: Checking DXT1: ", i);
		if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT1, CMSE, AMSE))
			return;
		TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE);
		
		if (CMSE <= 1e-6 && AMSE <= 1e-6)
		{
			TRACE1(" %03d: Selected Format: DXT1\n", i);
			AppendXPRImage(info, pSrcSurf, XB_D3DFMT_DXT1);
		}
		else
		{	
			pSrcSurf->Release();

			hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_P8, &pSrcSurf);
			CheckHR(hr);

			hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
			CheckHR(hr);

			memcpy((BYTE*)slr.pBits, pGif->Raster, pGif->Height * slr.Pitch);
			memset((BYTE*)slr.pBits + pGif->Height * slr.Pitch, pGif->Transparent, (Height - pGif->Height) * slr.Pitch);

			pSrcSurf->UnlockRect();

			TRACE1(" %03d: Selected Format: P8\n", i);
			AppendXPRImage(info, pSrcSurf, XB_D3DFMT_P8);
		}
	}

	delete [] HashBuf;
	
	printf("(%5df) %4dx%-4d (%5.2f%% waste)\n", nActualImages, Width, Height, Waste);

	CommitXPR(OutFilename);
	if (pSrcSurf)
		pSrcSurf->Release();
}
예제 #6
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();
}
예제 #7
0
// Converts to P8 format is colours <= 256
bool ConvertP8(LPDIRECT3DSURFACE8 pSrcSurf, LPDIRECT3DSURFACE8& pDstSurf, DWORD* pal, D3DXIMAGE_INFO &info)
{
	pDstSurf = 0;

	D3DSURFACE_DESC desc;
	pSrcSurf->GetDesc(&desc);

	// convert to p8
  UINT Width = PadPow2(desc.Width);
  UINT Height = PadPow2(desc.Height);
	HRESULT hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pDstSurf);
	CheckHR(hr);

	D3DLOCKED_RECT slr, dlr;
	hr = pDstSurf->LockRect(&dlr, NULL, 0);
	CheckHR(hr);
	hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
	CheckHR(hr);

	DWORD* src = (DWORD*)slr.pBits;
	BYTE* dst = (BYTE*)dlr.pBits;
	int n = 0, i;
	for (UINT y = 0; y < info.Height; ++y)
	{
		for (UINT x = 0; x < info.Width; ++x)
		{
			for (i = 0; i < n; ++i)
			{
				if (pal[i] == *src)
					break;
			}
			if (i == n)
			{
				if (n >= 256)
				{
					TRACE0(" Too many colours for P8\n");
					pSrcSurf->UnlockRect();
					pDstSurf->UnlockRect();
					pDstSurf->Release();
					return false;
				}
				pal[n++] = *src;
			}
			*dst++ = i;
			++src;
		}
		for (UINT x = info.Width; x < Width; ++x)
		{
			*dst++ = 0; // we don't care about the colour outside of our real image
			++src;
    }
	}
  for (UINT y = info.Height; y < Height; ++y)
  {
		for (UINT x = 0; x < Width; ++x)
		{
			*dst++ = 0; // we don't care about the colour outside of our real image
			++src;
    }
  }
	TRACE1(" Colours Used: %d\n", n);

	pDstSurf->UnlockRect();
	pSrcSurf->UnlockRect();

	return true;
}