278 lines
8.1 KiB
C++
278 lines
8.1 KiB
C++
//======= Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose: Image Byte Swapping. Isolate routines to own module to allow librarian
|
|
// to ignore xbox 360 dependenices in non-applicable win32 projects.
|
|
//
|
|
//=============================================================================//
|
|
|
|
#if defined( _WIN32 ) && !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION )
|
|
#include <windows.h>
|
|
#endif
|
|
#include "tier0/platform.h"
|
|
#include "tier0/dbg.h"
|
|
#include "bitmap/imageformat.h"
|
|
|
|
// Should be last include
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#if defined( _WIN32 ) && !defined( _X360 ) && !defined( NO_X360_XDK ) && !defined( DX_TO_GL_ABSTRACTION )
|
|
#if defined( XDK_INSTALLED )
|
|
// the x86 version of the 360 (used by win32 tools)
|
|
// It would have been nice to use the 360 D3DFORMAT bit encodings, but the codes
|
|
// are different for WIN32, and this routine is used by a WIN32 library to
|
|
// manipulate 360 data, so there can be no reliance on WIN32 D3DFORMAT bits
|
|
#include "d3d9.h"
|
|
#include "XGraphics.h"
|
|
#endif
|
|
#endif
|
|
|
|
namespace ImageLoader
|
|
{
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Known formats that can be converted. Used as a trap for 360 formats
|
|
// that may occur but have not been validated yet.
|
|
//-----------------------------------------------------------------------------
|
|
bool IsFormatValidForConversion( ImageFormat fmt )
|
|
{
|
|
switch ( fmt )
|
|
{
|
|
case IMAGE_FORMAT_RGBA8888:
|
|
case IMAGE_FORMAT_ABGR8888:
|
|
case IMAGE_FORMAT_RGB888:
|
|
case IMAGE_FORMAT_BGR888:
|
|
case IMAGE_FORMAT_ARGB8888:
|
|
case IMAGE_FORMAT_BGRA8888:
|
|
case IMAGE_FORMAT_BGRX8888:
|
|
case IMAGE_FORMAT_UVWQ8888:
|
|
case IMAGE_FORMAT_RGBA16161616F:
|
|
case IMAGE_FORMAT_RGBA16161616:
|
|
case IMAGE_FORMAT_UVLX8888:
|
|
case IMAGE_FORMAT_DXT1:
|
|
case IMAGE_FORMAT_DXT1_ONEBITALPHA:
|
|
case IMAGE_FORMAT_DXT3:
|
|
case IMAGE_FORMAT_DXT5:
|
|
case IMAGE_FORMAT_UV88:
|
|
return true;
|
|
|
|
// untested formats
|
|
default:
|
|
case IMAGE_FORMAT_RGB565:
|
|
case IMAGE_FORMAT_I8:
|
|
case IMAGE_FORMAT_IA88:
|
|
case IMAGE_FORMAT_A8:
|
|
case IMAGE_FORMAT_RGB888_BLUESCREEN:
|
|
case IMAGE_FORMAT_BGR888_BLUESCREEN:
|
|
case IMAGE_FORMAT_BGR565:
|
|
case IMAGE_FORMAT_BGRX5551:
|
|
case IMAGE_FORMAT_BGRA4444:
|
|
case IMAGE_FORMAT_BGRA5551:
|
|
case IMAGE_FORMAT_ATI1N:
|
|
case IMAGE_FORMAT_ATI2N:
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Swaps the image element type within the format.
|
|
// This is to ensure that >8 bit channels are in the correct endian format
|
|
// as expected by the conversion process, which varies according to format,
|
|
// input, and output.
|
|
//-----------------------------------------------------------------------------
|
|
void PreConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width, int stride )
|
|
{
|
|
Assert( IsFormatValidForConversion( imageFormat ) );
|
|
|
|
#ifndef DX_TO_GL_ABSTRACTION
|
|
if ( IsPC() )
|
|
{
|
|
// running as a win32 tool, data is in expected order
|
|
// for conversion code
|
|
return;
|
|
}
|
|
|
|
// If licensees don't have the XDK installed they are not going to be able to do image conversion and shouldn't need to
|
|
#if defined (XDK_INSTALLED)
|
|
|
|
// running on 360 and converting, input data must be x86 order
|
|
// swap to ensure conversion code gets valid data
|
|
XGENDIANTYPE xEndian;
|
|
switch ( imageFormat )
|
|
{
|
|
default:
|
|
return;
|
|
|
|
case IMAGE_FORMAT_RGBA16161616F:
|
|
case IMAGE_FORMAT_RGBA16161616:
|
|
xEndian = XGENDIAN_8IN16;
|
|
break;
|
|
}
|
|
|
|
int count;
|
|
if ( !stride )
|
|
{
|
|
stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
|
|
count = nImageSize / stride;
|
|
XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
|
|
}
|
|
else
|
|
{
|
|
int nRows = nImageSize/stride;
|
|
for ( int i=0; i<nRows; i++ )
|
|
{
|
|
XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
|
|
pImageData += stride;
|
|
}
|
|
}
|
|
#endif // XDK_INSTALLED
|
|
#endif // COMPILER_MSVC32
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Swaps image bytes for use on a big endian platform. This is used after the conversion
|
|
// process to match the 360 d3dformats.
|
|
//-----------------------------------------------------------------------------
|
|
void PostConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, VtfConsoleFormatType_t targetConsole, int width, int stride )
|
|
{
|
|
Assert( IsFormatValidForConversion( imageFormat ) );
|
|
|
|
#ifndef DX_TO_GL_ABSTRACTION
|
|
|
|
// If licensees don't have the XDK installed they are not going to be able to do image conversion and shouldn't need to
|
|
#if defined (XDK_INSTALLED)
|
|
|
|
// It would have been nice to use the 360 D3DFORMAT bit encodings, but the codes
|
|
// are different for win32, and this routine is used by a win32 library to
|
|
// manipulate 360 data, so there can be no reliance on D3DFORMAT bits
|
|
XGENDIANTYPE xEndian;
|
|
switch ( imageFormat )
|
|
{
|
|
default:
|
|
return;
|
|
|
|
case IMAGE_FORMAT_RGBA16161616F:
|
|
case IMAGE_FORMAT_RGBA16161616:
|
|
if ( IsGameConsole() )
|
|
{
|
|
// running on 360 the conversion output is correct
|
|
return;
|
|
}
|
|
// running on the pc, the output needs to be in 360 order
|
|
xEndian = XGENDIAN_8IN16;
|
|
break;
|
|
|
|
case IMAGE_FORMAT_DXT1:
|
|
case IMAGE_FORMAT_DXT1_ONEBITALPHA:
|
|
case IMAGE_FORMAT_DXT3:
|
|
case IMAGE_FORMAT_DXT5:
|
|
case IMAGE_FORMAT_UV88:
|
|
case IMAGE_FORMAT_ATI1N:
|
|
case IMAGE_FORMAT_ATI2N:
|
|
|
|
// Don't endian swap compressed textures for PS3, but swap everything else just like Xbox360
|
|
if ( targetConsole == VTF_CONSOLE_PS3 )
|
|
return;
|
|
xEndian = XGENDIAN_8IN16;
|
|
break;
|
|
|
|
case IMAGE_FORMAT_BGRA8888:
|
|
case IMAGE_FORMAT_BGRX8888:
|
|
case IMAGE_FORMAT_UVWQ8888:
|
|
case IMAGE_FORMAT_UVLX8888:
|
|
xEndian = XGENDIAN_8IN32;
|
|
break;
|
|
}
|
|
|
|
int count;
|
|
if ( !stride )
|
|
{
|
|
stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
|
|
count = nImageSize / stride;
|
|
XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
|
|
}
|
|
else
|
|
{
|
|
int nRows = nImageSize/stride;
|
|
for ( int i=0; i<nRows; i++ )
|
|
{
|
|
XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
|
|
pImageData += stride;
|
|
}
|
|
}
|
|
#endif // XDK_INSTALLED
|
|
|
|
#endif // COMPILER_MSVC32
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Swaps image bytes.
|
|
//-----------------------------------------------------------------------------
|
|
void ByteSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width, int stride )
|
|
{
|
|
Assert( IsFormatValidForConversion( imageFormat ) );
|
|
|
|
#ifndef DX_TO_GL_ABSTRACTION
|
|
// If licensees don't have the XDK installed they are not going to be able to do image conversion and shouldn't need to
|
|
#if defined (XDK_INSTALLED)
|
|
|
|
XGENDIANTYPE xEndian;
|
|
switch ( imageFormat )
|
|
{
|
|
case IMAGE_FORMAT_BGR888:
|
|
case IMAGE_FORMAT_I8:
|
|
case IMAGE_FORMAT_A8:
|
|
default:
|
|
return;
|
|
|
|
case IMAGE_FORMAT_BGRA8888:
|
|
case IMAGE_FORMAT_BGRX8888:
|
|
case IMAGE_FORMAT_UVWQ8888:
|
|
case IMAGE_FORMAT_UVLX8888:
|
|
case IMAGE_FORMAT_R32F:
|
|
case IMAGE_FORMAT_RGBA32323232F:
|
|
xEndian = XGENDIAN_8IN32;
|
|
break;
|
|
|
|
case IMAGE_FORMAT_BGR565:
|
|
case IMAGE_FORMAT_BGRX5551:
|
|
case IMAGE_FORMAT_BGRA5551:
|
|
case IMAGE_FORMAT_BGRA4444:
|
|
case IMAGE_FORMAT_IA88:
|
|
case IMAGE_FORMAT_DXT1:
|
|
case IMAGE_FORMAT_DXT1_ONEBITALPHA:
|
|
case IMAGE_FORMAT_DXT3:
|
|
case IMAGE_FORMAT_DXT5:
|
|
case IMAGE_FORMAT_ATI1N:
|
|
case IMAGE_FORMAT_ATI2N:
|
|
case IMAGE_FORMAT_UV88:
|
|
case IMAGE_FORMAT_RGBA16161616F:
|
|
case IMAGE_FORMAT_RGBA16161616:
|
|
xEndian = XGENDIAN_8IN16;
|
|
break;
|
|
}
|
|
|
|
int count;
|
|
if ( !stride )
|
|
{
|
|
stride = XGENDIANTYPE_GET_DATA_SIZE( xEndian );
|
|
count = nImageSize / stride;
|
|
XGEndianSwapMemory( pImageData, pImageData, xEndian, stride, count );
|
|
}
|
|
else
|
|
{
|
|
int nRows = nImageSize/stride;
|
|
for ( int i=0; i<nRows; i++ )
|
|
{
|
|
XGEndianSwapMemory( pImageData, pImageData, xEndian, XGENDIANTYPE_GET_DATA_SIZE( xEndian ), width );
|
|
pImageData += stride;
|
|
}
|
|
}
|
|
#endif // XDK_INSTALLED
|
|
|
|
#endif // COMPILER_MSVC32
|
|
}
|
|
}
|