BUG: 4.25 BulkData LockReadOnly() returns nullptr in release build

Hi,

we’re doing a texture color lookup in our project by using Bulkdata’s LockReadOnly() function and this used to work without a problem in release builds up to UE 4.25. Note that this only occurs in release builds, all works fine in editor and standalone.

I have attached two sample projects, one in 4.22 (didn’t have 4.24 installed anymore) and one in 4.25 with the exact same source code. They both display the red color value of different texture coordinates on a TextRenderActor in a test level. Note that when packaging the 4.25 project the correct color values are not displayed (we’re displaying a “1” instead). It works in editor and standalone, though. The 4.22 project works in all cases.

Our texture asset has the required settings (no mipmaps, compression settings are TextureCompressionSettings::TC_VectorDisplacementmap, SRGB= false)

Here’s a code snippet of what we are doing:

FByteBulkData& BulkData = LookupTexture->PlatformData->Mips[0].BulkData;  

int32 SizeX = LookupTexture->GetSizeX();
int32 SizeY = LookupTexture->GetSizeY();

const FColor* LookupColors = reinterpret_cast<const FColor*>(BulkData.LockReadOnly());

if (LookupColors == nullptr){
    UE_LOG(LogTexture, Error, TEXT("LockReadOnly() returns nullptr!"));
    BulkData.Unlock();
    return 1;
} 
else
{
    FColor PixelColor = LookupColors[Coordinate.Y * SizeX + Coordinate.X];
    BulkData.Unlock();
    return PixelColor.R;
}

Sample Project 4.22

Sample Project 4.25

Hey! I’m having the exact same bug :cry: Did you find a workaround? Thanks!

Update, I resolved this issue by putting this code at begin play.

	if (InfluenceTexture != nullptr)
	{
		InfluenceTexture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
#if WITH_EDITOR
		InfluenceTexture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
#endif
		InfluenceTexture->SRGB = false;
		InfluenceTexture->UpdateResource();
	}

but it changes original image data… So if you need to read image data only once I would recommend using BulkData.GetCopy()

FWIW: I came across this because I was using LockReadOnly() and I was having problems. I read an example somewhere and it used LockReadOnly(). After looking at the implementation of LockReadOnly(), it is very dangerous. I don’t know when one would want to use it, but I highly recommend against using LockReadOnly(). Instead, use: Lock(LOCK_READ_ONLY)

FColor* TileImageData = reinterpret_cast(TileRawImageData->Lock(LOCK_READ_ONLY));

Using the LockReadOnly caused issues in builds, so Lock(LOCK_READ_ONLY) was the fix.

FTexture2DMipMap* TileMipMap = &TileMapTexture->PlatformData->Mips[0];
FByteBulkData* TileRawImageData = &TileMipMap->BulkData;
FColor* TileImageData = reinterpret_cast(TileRawImageData->Lock(LOCK_READ_ONLY));