Skip to content

Commit

Permalink
feat: added support for ATI source branch difference fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
Trico-Everfire committed Aug 1, 2023
1 parent b351891 commit ac2401d
Show file tree
Hide file tree
Showing 3 changed files with 492 additions and 436 deletions.
44 changes: 39 additions & 5 deletions VTFLib/VTFFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1426,6 +1426,25 @@ vlBool CVTFFile::Load( IO::Readers::IReader *Reader, vlBool bHeaderOnly )
return vlTrue;
}

// Between different branches of Source Engine games
// the ATI formats are shifted in the ImageFormats enum
// and will crash VTFLib if a old branch ATI were to
// try and load, given they are the same identical format
// we can just set it to VTFLib's ATI enum to load it correctly.
// The numbers we change from are source internal formats
// and can be safely changed. If a problem ever does arise...
// Blame valve and pray to the rat gods for salvation.
if ( this->Header->ImageFormat == IMAGE_FORMAT_ATI2N_OLD )
{
this->Header->ImageFormat = IMAGE_FORMAT_ATI2N;
this->OldATIFormat = true;
}
if ( this->Header->ImageFormat == IMAGE_FORMAT_ATI1N_OLD )
{
this->Header->ImageFormat = IMAGE_FORMAT_ATI1N;
this->OldATIFormat = true;
}

// work out how big out buffers need to be
this->uiImageBufferSize = this->ComputeImageSize( this->Header->Width, this->Header->Height, this->Header->Depth, this->Header->MipCount, this->Header->ImageFormat ) * this->GetFaceCount() * this->GetFrameCount();

Expand Down Expand Up @@ -1722,11 +1741,26 @@ vlBool CVTFFile::Save( IO::Writers::IWriter *Writer ) const
throw 0;

// Write the header.

auto format = this->Header->ImageFormat;

if ( format == IMAGE_FORMAT_ATI2N && OldATIFormat )
{
this->Header->ImageFormat = IMAGE_FORMAT_ATI2N_OLD;
}

if ( format == IMAGE_FORMAT_ATI1N && OldATIFormat )
{
this->Header->ImageFormat = IMAGE_FORMAT_ATI1N_OLD;
}

if ( Writer->Write( this->Header, this->Header->HeaderSize ) != this->Header->HeaderSize )
{
throw 0;
}

this->Header->ImageFormat = format;

if ( this->GetSupportsResources() )
{
for ( vlUInt i = 0; i < this->Header->ResourceCount; i++ )
Expand Down Expand Up @@ -3840,7 +3874,7 @@ inline vlSingle CVTFFile::FP16ToFP32( vlUInt16 input )

if ( fp16.uiExponent == 31 )
{
if ( fp16.uiMantissa == 0 ) // Check for Infinity
if ( fp16.uiMantissa == 0 ) // Check for Infinity
return sMaxFloat16Bits * ( ( fp16.uiSign == 1 ) ? -1.0f : 1.0f );
else if ( fp16.uiMantissa != 0 ) // Check for NaN
return 0.0f;
Expand Down Expand Up @@ -4126,7 +4160,7 @@ vlBool ConvertTemplated( vlByte *lpSource, vlByte *lpDest, vlUInt uiWidth, vlUIn
// default value transform
if ( uiSourceRMask && uiDestRMask )
{
if ( DestInfo.uiRBitsPerPixel < SourceInfo.uiRBitsPerPixel ) // downsample
if ( DestInfo.uiRBitsPerPixel < SourceInfo.uiRBitsPerPixel ) // downsample
DR = Shrink<vlUInt16>( SR, SourceInfo.uiRBitsPerPixel, DestInfo.uiRBitsPerPixel );
else if ( DestInfo.uiRBitsPerPixel > SourceInfo.uiRBitsPerPixel ) // upsample
DR = Expand<vlUInt16>( SR, SourceInfo.uiRBitsPerPixel, DestInfo.uiRBitsPerPixel );
Expand All @@ -4136,7 +4170,7 @@ vlBool ConvertTemplated( vlByte *lpSource, vlByte *lpDest, vlUInt uiWidth, vlUIn

if ( uiSourceGMask && uiDestGMask )
{
if ( DestInfo.uiGBitsPerPixel < SourceInfo.uiGBitsPerPixel ) // downsample
if ( DestInfo.uiGBitsPerPixel < SourceInfo.uiGBitsPerPixel ) // downsample
DG = Shrink<vlUInt16>( SG, SourceInfo.uiGBitsPerPixel, DestInfo.uiGBitsPerPixel );
else if ( DestInfo.uiGBitsPerPixel > SourceInfo.uiGBitsPerPixel ) // upsample
DG = Expand<vlUInt16>( SG, SourceInfo.uiGBitsPerPixel, DestInfo.uiGBitsPerPixel );
Expand All @@ -4146,7 +4180,7 @@ vlBool ConvertTemplated( vlByte *lpSource, vlByte *lpDest, vlUInt uiWidth, vlUIn

if ( uiSourceBMask && uiDestBMask )
{
if ( DestInfo.uiBBitsPerPixel < SourceInfo.uiBBitsPerPixel ) // downsample
if ( DestInfo.uiBBitsPerPixel < SourceInfo.uiBBitsPerPixel ) // downsample
DB = Shrink<vlUInt16>( SB, SourceInfo.uiBBitsPerPixel, DestInfo.uiBBitsPerPixel );
else if ( DestInfo.uiBBitsPerPixel > SourceInfo.uiBBitsPerPixel ) // upsample
DB = Expand<vlUInt16>( SB, SourceInfo.uiBBitsPerPixel, DestInfo.uiBBitsPerPixel );
Expand All @@ -4156,7 +4190,7 @@ vlBool ConvertTemplated( vlByte *lpSource, vlByte *lpDest, vlUInt uiWidth, vlUIn

if ( uiSourceAMask && uiDestAMask )
{
if ( DestInfo.uiABitsPerPixel < SourceInfo.uiABitsPerPixel ) // downsample
if ( DestInfo.uiABitsPerPixel < SourceInfo.uiABitsPerPixel ) // downsample
DA = Shrink<vlUInt16>( SA, SourceInfo.uiABitsPerPixel, DestInfo.uiABitsPerPixel );
else if ( DestInfo.uiABitsPerPixel > SourceInfo.uiABitsPerPixel ) // upsample
DA = Expand<vlUInt16>( SA, SourceInfo.uiABitsPerPixel, DestInfo.uiABitsPerPixel );
Expand Down
68 changes: 37 additions & 31 deletions VTFLib/VTFFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,35 +82,35 @@ extern "C"
#pragma pack( 1 )
typedef struct tagSVTFCreateOptions
{
vlUInt uiVersion[2]; //!< Output image version.
VTFImageFormat ImageFormat; //!< Output image output storage format.
vlUInt uiVersion[2]; //!< Output image version.
VTFImageFormat ImageFormat; //!< Output image output storage format.

vlUInt uiFlags; //!< Output image header flags.
vlUInt uiStartFrame; //!< Output image start frame.
vlSingle sBumpScale; //!< Output image bump scale.
vlSingle sReflectivity[3]; //!< Output image reflectivity. (Only used if bReflectivity is false.)
vlUInt uiFlags; //!< Output image header flags.
vlUInt uiStartFrame; //!< Output image start frame.
vlSingle sBumpScale; //!< Output image bump scale.
vlSingle sReflectivity[3]; //!< Output image reflectivity. (Only used if bReflectivity is false.)

vlBool bMipmaps; //!< Generate MIPmaps. (Space is always allocated.)
VTFMipmapFilter MipmapFilter; //!< MIP map re-size filter.

vlBool bThumbnail; //!< Generate thumbnail image.
vlBool bReflectivity; //!< Compute image reflectivity.
vlBool bThumbnail; //!< Generate thumbnail image.
vlBool bReflectivity; //!< Compute image reflectivity.

vlBool bResize; //!< Resize the input image.
VTFResizeMethod ResizeMethod; //!< New size compution method.
VTFMipmapFilter ResizeFilter; //!< Re-size filter.
vlUInt uiResizeWidth; //!< New width after re-size if method is RESIZE_SET.
vlUInt uiResizeHeight; //!< New height after re-size if method is RESIZE_SET.

vlBool bResizeClamp; //!< Clamp re-size size.
vlUInt uiResizeClampWidth; //!< Maximum width to re-size to.
vlUInt uiResizeClampHeight; //!< Maximum height to re-size to.
vlBool bResizeClamp; //!< Clamp re-size size.
vlUInt uiResizeClampWidth; //!< Maximum width to re-size to.
vlUInt uiResizeClampHeight; //!< Maximum height to re-size to.

vlBool bGammaCorrection; //!< Gamma correct input image.
vlSingle sGammaCorrection; //!< Gamma correction to apply.
vlBool bGammaCorrection; //!< Gamma correct input image.
vlSingle sGammaCorrection; //!< Gamma correction to apply.

vlBool bSphereMap; //!< Generate a sphere map for six faced environment maps.
vlBool bSRGB; //!< Texture is in the SRGB color space.
vlBool bSphereMap; //!< Generate a sphere map for six faced environment maps.
vlBool bSRGB; //!< Texture is in the SRGB color space.
} SVTFCreateOptions;
#pragma pack()

Expand Down Expand Up @@ -165,14 +165,16 @@ namespace VTFLib
class VTFLIB_API CVTFFile
{
private:
SVTFHeader *Header; // VTF header
SVTFHeader *Header; // VTF header

vlUInt uiImageBufferSize; // Size of VTF image data buffer
vlByte *lpImageData; // VTF image buffer
vlUInt uiImageBufferSize; // Size of VTF image data buffer
vlByte *lpImageData; // VTF image buffer

vlUInt uiThumbnailBufferSize; // Size of VTF thumbnail image data buffer
vlByte *lpThumbnailImageData; // VTF thumbnail image buffer

bool OldATIFormat = false;

public:
CVTFFile(); //!< Default constructor

Expand Down Expand Up @@ -381,21 +383,21 @@ namespace VTFLib
vlUInt GetMinorVersion() const; //!< Returns the VTF file minor version number.
bool SetVersion( vlUInt major, vlUInt minor );

vlUInt GetSize() const; //!< Returns the VTF file size in bytes.
vlUInt GetSize() const; //!< Returns the VTF file size in bytes.

vlUInt GetWidth() const; //!< Returns the width of the image in pixels from the VTF header.
vlUInt GetHeight() const; //!< Returns the height of the image in pixels from the VTF header.
vlUInt GetDepth() const; //!< Returns the depth of the image in pixels from the VTF header.
vlUInt GetWidth() const; //!< Returns the width of the image in pixels from the VTF header.
vlUInt GetHeight() const; //!< Returns the height of the image in pixels from the VTF header.
vlUInt GetDepth() const; //!< Returns the depth of the image in pixels from the VTF header.

vlUInt GetFrameCount() const; //!< Returns the frame count from the VTF header.
vlUInt GetFaceCount() const; //!< Returns the face count from the VTF header.
vlUInt GetMipmapCount() const; //!< Returns the number of MIP levels in the image from the VTF header.
vlUInt GetFrameCount() const; //!< Returns the frame count from the VTF header.
vlUInt GetFaceCount() const; //!< Returns the face count from the VTF header.
vlUInt GetMipmapCount() const; //!< Returns the number of MIP levels in the image from the VTF header.

vlUInt GetStartFrame() const; //!< Returns the start frame from the VTF header.
vlVoid SetStartFrame( vlUInt uiStartFrame ); //!< Sets the start frame in the VTF header.

vlUInt GetFlags() const; //!< Returns the image flags from the VTF header.
vlVoid SetFlags( vlUInt uiFlags ); //!< Sets the image flags in the VTF header.
vlUInt GetFlags() const; //!< Returns the image flags from the VTF header.
vlVoid SetFlags( vlUInt uiFlags ); //!< Sets the image flags in the VTF header.

//! Check if a specific flag is set in the VTF header.
/*!
Expand Down Expand Up @@ -476,10 +478,10 @@ namespace VTFLib
vlVoid SetData( vlUInt uiFrame, vlUInt uiFace, vlUInt uiSlice, vlUInt uiMipmapLevel, vlByte *lpData );

public:
vlBool GetHasThumbnail() const; //!< Returns if a the current VTF image image contains a thumbnail version.
vlBool GetHasThumbnail() const; //!< Returns if a the current VTF image image contains a thumbnail version.

vlUInt GetThumbnailWidth() const; //!< Returns the width in pixels of the current images thumbnail.
vlUInt GetThumbnailHeight() const; //!< Returns the heught in pixels of the current images thumbnail.
vlUInt GetThumbnailWidth() const; //!< Returns the width in pixels of the current images thumbnail.
vlUInt GetThumbnailHeight() const; //!< Returns the heught in pixels of the current images thumbnail.

VTFImageFormat GetThumbnailFormat() const; //!< Returns the image format of the current images thumbnail.

Expand All @@ -503,7 +505,7 @@ namespace VTFLib
vlVoid SetThumbnailData( vlByte *lpData );

public:
vlBool GetSupportsResources() const; //!< Returns true if the current VTF file version supports resources.
vlBool GetSupportsResources() const; //!< Returns true if the current VTF file version supports resources.

vlUInt GetResourceCount() const; //!< Returns the number of resources contained within the VTF file.
vlUInt GetResourceType( vlUInt uiIndex ) const; //!< Returns the resource type;
Expand Down Expand Up @@ -620,6 +622,10 @@ namespace VTFLib

vlBool SetVTFAlpha( unsigned char alpha );

vlVoid UseOldATIFormat( bool has ) { this->OldATIFormat = has; }

vlBool HasOldATIFormat() { return this->OldATIFormat; }

public:
//! Get VTFImageFormat info.
/*!
Expand Down
Loading

0 comments on commit ac2401d

Please sign in to comment.