Files
UnrealEngineUWP/Engine/Source/Runtime/ImageWrapper/Private/Formats/DdsImageWrapper.cpp
bryan sefcik 07894f4a07 Removed redundant private include paths from build.cs files.
Fixed include paths to be relative to the private or public folders.
Hid or removed includes that reached into other private module folders.
Updated PublicInclude paths when necessary.

#jira
#preflight 631a717cec45fbf3d74d4ba7

[CL 21916033 by bryan sefcik in ue5-main branch]
2022-09-09 00:53:22 -04:00

210 lines
5.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Formats/DdsImageWrapper.h"
#include "ImageWrapperPrivate.h"
void FDdsImageWrapper::Reset()
{
Super::Reset();
FreeDDS();
}
void FDdsImageWrapper::Compress(int32 Quality)
{
CompressedData.Reset();
FreeDDS();
bool bIsExactMatch;
ERawImageFormat::Type RawImageFormat = GetClosestRawImageFormat(&bIsExactMatch);
if ( RawImageFormat == ERawImageFormat::Invalid )
{
// should not get here if caller checked CanSetRawFormat() like they're supposed to
SetError(TEXT("Format not supported"));
check( CompressedData.IsEmpty() ); // signals error
return;
}
// we are not passed SRGB/Gamma info, just assume it is Default for now :
EGammaSpace GammaSpace = ERawImageFormat::GetDefaultGammaSpace(RawImageFormat);
// some code dupe with IImageWrapper::GetRawImage
// @todo Oodle : refactor so this can be shared
// after someone does SetRaw() , I should be able to get an FImage view of Raw bits
// for my own writers to use
// (can't just use GetRawImage because that's like a GetRaw after SetCompressed)
FImageView RawImage(RawData.GetData(),Width,Height,1,RawImageFormat,GammaSpace);
FImage TempImage;
if ( ! bIsExactMatch )
{
// handle non-mapped cases :
switch(Format)
{
case ERGBFormat::RGBA:
{
// RGBA8 -> BGRA8
check( BitDepth == 8 );
check( RawImageFormat == ERawImageFormat::BGRA8 );
FImageCore::CopyImageRGBABGRA(RawImage, RawImage );
break;
}
case ERGBFormat::BGRA:
{
// BGRA16 -> RGBA16
check( BitDepth == 16 );
check( RawImageFormat == ERawImageFormat::RGBA16 );
FImageCore::CopyImageRGBABGRA(RawImage, RawImage );
break;
}
case ERGBFormat::GrayF:
{
// 1 channel F32 -> 4xF32 :
check( BitDepth == 32 );
check( RawImageFormat == ERawImageFormat::RGBA32F );
const float * Src = (const float *)RawImage.RawData;
FLinearColor * Dst = (FLinearColor *)TempImage.RawData.GetData();
int64 NumPixels = RawImage.GetNumPixels();
for(int64 i=0;i<NumPixels;i++)
{
Dst[i] = FLinearColor( Src[i],Src[i],Src[i],1.f );
}
RawImage = TempImage;
break;
}
default:
check(0);
break;
}
}
// RawImage is ready to write to a DDS
UE::DDS::EDXGIFormat DXGIFormat = UE::DDS::DXGIFormatFromRawFormat(RawImage.Format,RawImage.GammaSpace);
DDS = UE::DDS::FDDSFile::CreateEmpty2D(Width,Height,1,DXGIFormat,0);
DDS->FillMip(RawImage,0);
UE::DDS::EDDSError Error = DDS->WriteDDS(CompressedData);
FreeDDS();
if ( Error != UE::DDS::EDDSError::OK )
{
SetError(TEXT("WriteDDS failed"));
CompressedData.Empty(); // signals error
return;
}
return;
}
bool FDdsImageWrapper::SetCompressed(const void* InCompressedData, int64 InCompressedSize)
{
Super::SetCompressed(InCompressedData,InCompressedSize);
FreeDDS();
UE::DDS::EDDSError Error;
DDS = UE::DDS::FDDSFile::CreateFromDDSInMemory((const uint8 *)InCompressedData,InCompressedSize,&Error);
if ( DDS == nullptr || Error != UE::DDS::EDDSError::OK )
{
SetError(TEXT("CreateFromDDSInMemory failed"));
RawData.Empty();
FreeDDS();
return false;
}
// populate header info :
// change X8 formats to A8 :
DDS->ConvertRGBXtoRGBA();
// change RGBA8 to BGRA8 before DXGIFormatGetClosestRawFormat :
DDS->ConvertChannelOrder(UE::DDS::EChannelOrder::BGRA);
// map format to RawImageFormat and ETextureSourceFormat
ERawImageFormat::Type RawImageFormat = UE::DDS::DXGIFormatGetClosestRawFormat(DDS->DXGIFormat);
if ( RawImageFormat == ERawImageFormat::Invalid )
{
//Warn->Logf(ELogVerbosity::Error, TEXT("DDS DXGIFormat not supported : %d : %s"), (int)DDS->DXGIFormat, UE::DDS::DXGIFormatGetName(DDS->DXGIFormat) );
SetError(TEXT("DDS DXGIFormat not supported"));
RawData.Empty();
FreeDDS();
return false;
}
if ( ! DDS->IsValidTexture2D() )
{
UE_LOG(LogImageWrapper, Warning, TEXT("DDS is a complex 3d/cube/array image, DdsImageWrapper will just import the first 2d surface"));
}
// SRGB/Gamma : in some cases we can get SRGB info from the DDS file, so we could report that out
// see EditorFactories
// not doing for now
ConvertRawImageFormat(RawImageFormat, Format,BitDepth);
Width = DDS->Width;
Height = DDS->Height;
return true;
}
void FDdsImageWrapper::Uncompress(const ERGBFormat InFormat, int32 InBitDepth)
{
RawData.Reset();
// SetCompressed made the DDS
check( DDS != nullptr );
// new style, only support decoding to own format :
check( InFormat == GetFormat() );
check( InBitDepth == GetBitDepth() );
ERawImageFormat::Type RawImageFormat = UE::DDS::DXGIFormatGetClosestRawFormat(DDS->DXGIFormat);
// not setting SRGB/Gamma, just assume it is Default for now :
FImage RawImage(Width,Height,RawImageFormat);
if ( ! DDS->GetMipImage(RawImage,0) )
{
SetError(TEXT("DDS GetMipImage failed"));
FreeDDS();
check( RawData.IsEmpty() ); // indicates failure
return;
}
RawData = MoveTemp(RawImage.RawData);
}
bool FDdsImageWrapper::CanSetRawFormat(const ERGBFormat InFormat, const int32 InBitDepth) const
{
// accept any format that can roundtrip through ERawImageFormat :
// ! exact match is okay, that's an RB swap
ERawImageFormat::Type RawImageFormat = ConvertRGBFormat(InFormat,InBitDepth,nullptr);
ERGBFormat OutFormat;
int OutBitDepth;
ConvertRawImageFormat(RawImageFormat, OutFormat,OutBitDepth);
if ( InFormat == OutFormat && InBitDepth == OutBitDepth )
{
return true;
}
else
{
return false;
}
}
ERawImageFormat::Type FDdsImageWrapper::GetSupportedRawFormat(const ERawImageFormat::Type InFormat) const
{
// all raw formats supported
return InFormat;
}