FinalImage

FinalImage

#Overview

name: FinalImage

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 10 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of FinalImage is to represent the processed and finalized image data in various image processing and rendering contexts within Unreal Engine 5. This variable is used in different subsystems and plugins, primarily related to image handling, texture processing, and rendering pipelines.

FinalImage is utilized in the following Unreal Engine subsystems, plugins, or modules:

  1. DatasmithRuntime plugin: Used for loading, processing, and converting image data from various file formats.
  2. MovieRenderPipeline: Used in the context of movie rendering and output management.
  3. ImageWrapper module: Specifically in the TiffImageWrapper for unpacking and processing TIFF image data.

The value of FinalImage is typically set after processing the original image data. It often represents the result of operations such as loading, rescaling, format conversion, or color space adjustments.

FinalImage interacts with several other variables and data structures, including:

Developers should be aware of the following when using FinalImage:

  1. It may represent different stages of image processing depending on the context.
  2. The format and data type of FinalImage can vary (e.g., 8-bit, 16-bit, float).
  3. Memory management is crucial, as FinalImage often needs to be properly freed after use.

Best practices when using FinalImage include:

  1. Ensure proper memory management by unloading or freeing the image data when no longer needed.
  2. Verify the image type and format before processing to avoid errors.
  3. Use appropriate data types and conversion methods when working with different image formats.
  4. Consider performance implications when processing large images, and use parallel processing when appropriate.
  5. Handle error cases and edge conditions, such as failed image loading or unsupported formats.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:2905, section: [Engine.BufferVisualizationMaterials]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/ImageReader.cpp:708

Scope (from outer to inner):

file
namespace    DatasmithRuntime
function     bool GetTextureDataFromFile

Source code excerpt:

		}

		//FinalImage format
		FREE_IMAGE_FORMAT FileType = FIF_UNKNOWN;

		//check the file signature and deduce its format
		FileType = FreeImage_GetFileType(TCHAR_TO_FICHAR(Filename), 0);

		//if still unknown, try to guess the file format from the file extension

#Loc: <Workspace>/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/ImageReader.cpp:732

Scope (from outer to inner):

file
namespace    DatasmithRuntime
function     bool GetTextureDataFromFile

Source code excerpt:

		}

		//pointer to the FinalImage, once loaded
		FIBITMAP* Bitmap = FreeImage_Load(FileType, TCHAR_TO_FICHAR(Filename), 0);

		//if the FinalImage failed to load, return failure
		if (!Bitmap)
		{
			return false;
		}

		return GetTextureDataInternal(Bitmap, FileType, Mode, MaxSize, bGenerateNormalMap, TextureData);

#Loc: <Workspace>/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/ImageReader.cpp:761

Scope (from outer to inner):

file
namespace    DatasmithRuntime
function     bool GetTextureDataFromBuffer

Source code excerpt:

		}

		// FinalImage format
		FREE_IMAGE_FORMAT FileType = Format == EDatasmithTextureFormat::JPEG ? FIF_JPEG : FIF_PNG;

		// check that the plugin has reading capabilities and load the file
		if (!FreeImage_FIFSupportsReading(FileType))
		{
			return false;

#Loc: <Workspace>/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/ImageReader.cpp:775

Scope (from outer to inner):

file
namespace    DatasmithRuntime
function     bool GetTextureDataFromBuffer

Source code excerpt:

		ensure(FreeImage_GetFileTypeFromMemory(MemoryBuffer, 0) == FileType);

		// pointer to the FinalImage, once loaded
		FIBITMAP *Bitmap = FreeImage_LoadFromMemory(FileType, MemoryBuffer, 0);

		// Close the memory stream
		FreeImage_CloseMemory(MemoryBuffer);

		// Safe to free array now

#Loc: <Workspace>/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/ImageReader.cpp:791

Scope (from outer to inner):

file
namespace    DatasmithRuntime
function     bool GetTextureDataInternal

Source code excerpt:

		TRACE_CPUPROFILER_EVENT_SCOPE(DatasmithRuntime::GetTextureData);

		//if the FinalImage failed to load, return failure
		if (!Bitmap)
		{
			return false;
		}

		//get the FinalImage Width and Height
		const uint32 OriginalWidth = FreeImage_GetWidth(Bitmap);
		const uint32 OriginalHeight = FreeImage_GetHeight(Bitmap);

		{
			//retrieve the FinalImage data
			BYTE* Bits = FreeImage_GetBits(Bitmap);

			//if this somehow one of these failed (they shouldn't), return failure
			if ((Bits == 0) || (OriginalWidth == 0) || (OriginalHeight == 0))
			{
				return false;

#Loc: <Workspace>/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/ImageReader.cpp:849

Scope (from outer to inner):

file
namespace    DatasmithRuntime
function     bool GetTextureDataInternal

Source code excerpt:

		}

		FIBITMAP* FinalImage = RescaledImage;

		if (bGenerateNormalMap == true)
		{
			FinalImage = FreeImage_ConvertTo32Bits(RescaledImage);
			check(FreeImage_GetImageType(FinalImage) == FIT_BITMAP);
		}

		bool bResult = true;
		TextureData.Width = NewWidth;
		TextureData.Height = NewHeight;
		TextureData.Pitch = FreeImage_GetPitch(FinalImage);
		const int32 BitsPerPixel = FreeImage_GetBPP(FinalImage);
		TextureData.BytesPerPixel = FMath::Max(1, BitsPerPixel / 8);

		check(TextureData.Width && TextureData.Height);

		switch(FreeImage_GetImageType(FinalImage))
		{
			case FIT_BITMAP:
			{
				CopyData<BYTE>(FinalImage, TextureData);
				break;
			}

			case FIT_UINT16:
			case FIT_INT16:
			{
				CopyData<uint16>(FinalImage, TextureData);
				break;
			}

			case FIT_UINT32:
			case FIT_INT32:
			{
				CopyData<uint32>(FinalImage, TextureData);
				break;
			}

			case FIT_FLOAT:
			case FIT_DOUBLE:
			{
				CopyData<float>(FinalImage, TextureData);
				break;
			}

			case FIT_RGB16:
			case FIT_RGBA16:
			{
				CopyData<FIRGB16>(FinalImage, TextureData);
				break;
			}

			case FIT_RGBAF:
			case FIT_RGBF:
			{
				CopyData<FIRGBF>(FinalImage, TextureData);
				break;
			}

			case FIT_COMPLEX:
			default:
			{

#Loc: <Workspace>/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/ImageReader.cpp:918

Scope (from outer to inner):

file
namespace    DatasmithRuntime
function     bool GetTextureDataInternal

Source code excerpt:

		}

		if (FinalImage != RescaledImage)
		{
			FreeImage_Unload(FinalImage);
		}

		// Free rescaled FinalImage data if applicable
		if (RescaledImage != Bitmap)
		{
			FreeImage_Unload(RescaledImage);
		}

		//Free FreeImage's copy of the data

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Public/MovieRenderPipelineDataTypes.h:121

Scope: file

Source code excerpt:


public:
	// The name of the pass such as "FinalImage" or "ObjectId", etc.
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movie Pipeline")
	FString Name;

	// The name of the camera that this pass is for. Stored here so we can differentiate between 
	// multiple cameras within a single pass.
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movie Pipeline")

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Public/MovieRenderPipelineDataTypes.h:1258

Scope: file

Source code excerpt:


	/** 
	* A mapping between render passes (such as 'FinalImage') and an array containing the files written for that shot.
	* Will be multiple files if using image sequences.
	*/
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Movie Pipeline")
	TMap<FMoviePipelinePassIdentifier, FMoviePipelineRenderPassOutputData> RenderPassData;
};

namespace MoviePipeline
{
	struct FMoviePipelineOutputFutureData

#Loc: <Workspace>/Engine/Source/Runtime/ImageWrapper/Private/Formats/TiffImageWrapper.cpp:912

Scope (from outer to inner):

file
namespace    UE::ImageWrapper::Private
function     void FTiffImageWrapper::UnpackIntoRawBuffer

Source code excerpt:

				UE_LOG(LogImageWrapper, Warning, TEXT("Tiff MINISWHITE floating point?  This is probably wrong."));

				TArrayView64<DataTypeDest> FinalImage(static_cast<DataTypeDest*>(static_cast<void*>(RawData.GetData())), RawData.Num());
				ParallelFor(Width * Height, [&FinalImage](int32 Index)
					{
						DataTypeDest& FinalValue = FinalImage[Index];
						FinalValue = 1.f - FinalValue; // uses implicit operator float() on FFloat16
					},  IsInGameThread() ? EParallelForFlags::None : EParallelForFlags::BackgroundPriority);
			}
			else
			{
				TArrayView64<DataTypeDest> FinalImage(static_cast<DataTypeDest*>(static_cast<void*>(RawData.GetData())), RawData.Num());
				ParallelFor(Width * Height, [&FinalImage](int32 Index)
					{
						DataTypeDest& FinalValue = FinalImage[Index];
						FinalValue = TNumericLimits<DataTypeDest>::Max() - FinalValue;
					},  IsInGameThread() ? EParallelForFlags::None : EParallelForFlags::BackgroundPriority);
			}
		}
	}