You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
FImage is now the standard preferred type for a bag of pixels FImageView can point at pixels without owning an allocation ERawImageFormat (FImage) converts to ETextureSourceFormat FImageUtils provides generic load/save and get/set from FImage major cleanup in the ImageWrappers new preferred API is through ImageWrapperModule Compress/Decompress SetRaw/GetRaw functions cleaned up to not have undefined behavior on unexpected formats ImageWrapper output added for HDR,BMP,TGA RGBA32F format added and supported throughout import/export EditorFactories import/export made more generic, most image types handled the same way using FImage now Deprecate old TSF RGBA order pixel formats Fix many crashes or bad handling of unusual pixel formats Pixel access functions should be used instead of switches on pixel type #preflight 6230ade7e65a7e65d68a187c #rb julien.stjean,martins.mozeiko,dan.thompson,fabian.giesen [CL 19397199 by charles bloom in ue5-main branch]
138 lines
3.8 KiB
C++
138 lines
3.8 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "TgaImageWrapper.h"
|
|
#include "ImageWrapperPrivate.h"
|
|
|
|
#include "TgaImageSupport.h"
|
|
|
|
|
|
|
|
// CanSetRawFormat returns true if SetRaw will accept this format
|
|
bool FTgaImageWrapper::CanSetRawFormat(const ERGBFormat InFormat, const int32 InBitDepth) const
|
|
{
|
|
return ( InFormat == ERGBFormat::BGRA ) && ( InBitDepth == 8 );
|
|
}
|
|
|
|
// returns InFormat if supported, else maps to something supported
|
|
ERawImageFormat::Type FTgaImageWrapper::GetSupportedRawFormat(const ERawImageFormat::Type InFormat) const
|
|
{
|
|
return ERawImageFormat::BGRA8;
|
|
}
|
|
|
|
void FTgaImageWrapper::Compress(int32 Quality)
|
|
{
|
|
CompressedData.Reset();
|
|
|
|
int64 SurfaceBytes = Width * Height * 4;
|
|
check( RawData.Num() == SurfaceBytes );
|
|
|
|
int64 CompresedSize = sizeof(FTGAFileHeader) + SurfaceBytes;
|
|
CompressedData.SetNum(CompresedSize);
|
|
|
|
uint8 * CompressedPtr = CompressedData.GetData();
|
|
|
|
// super lazy TGA writer here :
|
|
// always writes 32 bit BGRA
|
|
|
|
FTGAFileHeader header = { };
|
|
|
|
header.Width = INTEL_ORDER16( (uint16) Width );
|
|
header.Height = INTEL_ORDER16( (uint16) Height );
|
|
header.ImageTypeCode = 2;
|
|
header.BitsPerPixel = 32;
|
|
header.ImageDescriptor = 8;
|
|
|
|
memcpy(CompressedPtr,&header,sizeof(header));
|
|
CompressedPtr += sizeof(header);
|
|
|
|
// write rows BGRA , bottom up :
|
|
for(int y = Height-1; y>= 0;y--)
|
|
{
|
|
int64 RowBytes = Width * 4;
|
|
const void * From = &RawData[y * RowBytes];
|
|
memcpy(CompressedPtr,From,RowBytes);
|
|
CompressedPtr += RowBytes;
|
|
}
|
|
|
|
check( CompressedPtr == CompressedData.GetData() + CompressedData.Num() );
|
|
}
|
|
|
|
bool FTgaImageWrapper::SetCompressed(const void* InCompressedData, int64 InCompressedSize)
|
|
{
|
|
bool bResult = FImageWrapperBase::SetCompressed(InCompressedData, InCompressedSize);
|
|
|
|
return bResult && LoadTGAHeader();
|
|
}
|
|
|
|
void FTgaImageWrapper::Uncompress(const ERGBFormat InFormat, const int32 InBitDepth)
|
|
{
|
|
const int32 BytesPerPixel = ( InFormat == ERGBFormat::Gray ? 1 : 4 );
|
|
int64 TextureDataSize = (int64)Width * Height * BytesPerPixel;
|
|
RawData.Empty(TextureDataSize);
|
|
RawData.AddUninitialized(TextureDataSize);
|
|
|
|
uint32* TextureData = reinterpret_cast< uint32* >( RawData.GetData() );
|
|
|
|
FTGAFileHeader* TgaHeader = reinterpret_cast< FTGAFileHeader* >( CompressedData.GetData() );
|
|
if ( !DecompressTGA_helper( TgaHeader, CompressedData.Num(), TextureData, TextureDataSize ) )
|
|
{
|
|
SetError(TEXT("Error while decompressing a TGA"));
|
|
RawData.Reset();
|
|
}
|
|
}
|
|
|
|
bool FTgaImageWrapper::IsTGAHeader(const void * CompressedData,int64 CompressedDataLength)
|
|
{
|
|
const FTGAFileHeader* TgaHeader = (FTGAFileHeader*)CompressedData;
|
|
|
|
if ( CompressedDataLength >= sizeof( FTGAFileHeader ) &&
|
|
( (TgaHeader->ColorMapType == 0 && TgaHeader->ImageTypeCode == 2) ||
|
|
( TgaHeader->ColorMapType == 0 && TgaHeader->ImageTypeCode == 3 ) || // ImageTypeCode 3 is greyscale
|
|
( TgaHeader->ColorMapType == 0 && TgaHeader->ImageTypeCode == 10 ) ||
|
|
( TgaHeader->ColorMapType == 1 && TgaHeader->ImageTypeCode == 1 && TgaHeader->BitsPerPixel == 8 ) ) )
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool FTgaImageWrapper::LoadTGAHeader()
|
|
{
|
|
check( CompressedData.Num() );
|
|
|
|
if( ! IsTGAHeader(CompressedData.GetData(),CompressedData.Num()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const FTGAFileHeader* TgaHeader = (FTGAFileHeader*)CompressedData.GetData();
|
|
|
|
Width = TgaHeader->Width;
|
|
Height = TgaHeader->Height;
|
|
BitDepth = 8;
|
|
|
|
// must exactly match the logic in DecompressTGA_helper
|
|
if(TgaHeader->ColorMapType == 1 && TgaHeader->ImageTypeCode == 1 && TgaHeader->BitsPerPixel == 8)
|
|
{
|
|
Format = ERGBFormat::Gray;
|
|
}
|
|
else if(TgaHeader->ColorMapType == 0 && TgaHeader->ImageTypeCode == 3 && TgaHeader->BitsPerPixel == 8)
|
|
{
|
|
Format = ERGBFormat::Gray;
|
|
}
|
|
else
|
|
{
|
|
Format = ERGBFormat::BGRA;
|
|
}
|
|
|
|
ColorMapType = TgaHeader->ColorMapType;
|
|
ImageTypeCode = TgaHeader->ImageTypeCode;
|
|
|
|
// TgaHeader->BitsPerPixel is bits per *color*
|
|
|
|
return true;
|
|
}
|