Files
Test/Library/PackageCache/com.unity.collab-proxy@4628d2ba6ea4/Editor/Diff/Image/TextureLoader.cs
T
2026-11-01 23:39:55 +02:00

124 lines
3.7 KiB
C#

using System;
using System.IO;
using System.Reflection;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace Unity.PlasticSCM.Editor.Diff.Texture
{
internal static class TextureLoader
{
internal static Texture2D LoadFromFile(string filePath)
{
Texture2D texture = TryLoadWithImageConversion(filePath);
if (texture != null)
return texture;
return LoadWithUnityDecoder(filePath);
}
static Texture2D TryLoadWithImageConversion(string filePath)
{
MethodInfo method = GetLoadImageDataAtPathMethod();
if (method == null)
return null;
object[] args = new object[]
{
filePath, 0, 0, 0, GraphicsFormat.None
};
NativeArray<byte> pixelData = (NativeArray<byte>)method.Invoke(null, args);
try
{
int width = (int)args[1];
int height = (int)args[2];
int rowBytes = (int)args[3];
GraphicsFormat format = (GraphicsFormat)args[4];
if (width <= 0 || height <= 0)
return null;
Texture2D texture = new Texture2D(
width, height, format, TextureCreationFlags.None);
texture.filterMode = FilterMode.Bilinear;
texture.hideFlags = HideFlags.HideAndDontSave;
int bytesPerPixel = rowBytes / width;
int tightRowBytes = width * bytesPerPixel;
if (rowBytes == tightRowBytes)
{
texture.SetPixelData(pixelData, 0);
}
else
{
NativeArray<byte> tightData = new NativeArray<byte>(
tightRowBytes * height, Allocator.Temp);
for (int y = 0; y < height; y++)
{
NativeArray<byte>.Copy(
pixelData, y * rowBytes,
tightData, y * tightRowBytes,
tightRowBytes);
}
texture.SetPixelData(tightData, 0);
tightData.Dispose();
}
texture.Apply();
return texture;
}
finally
{
pixelData.Dispose();
}
}
static Texture2D LoadWithUnityDecoder(string filePath)
{
byte[] bytes = File.ReadAllBytes(filePath);
Texture2D texture = new Texture2D(2, 2, TextureFormat.RGBA32, false);
texture.filterMode = FilterMode.Bilinear;
texture.hideFlags = HideFlags.HideAndDontSave;
if (!texture.LoadImage(bytes))
{
UnityEngine.Object.DestroyImmediate(texture);
throw new InvalidOperationException(
"Failed to load image. The format may not be supported.");
}
return texture;
}
static MethodInfo GetLoadImageDataAtPathMethod()
{
if (mbIsMethodCached)
return mCachedMethod;
// we cannot access the internal ImageConversion.LoadImageDataAtPath
// in the UnityEngine.ImageConversionModule assembly,
// so we use reflection to try to get it
mCachedMethod = typeof(ImageConversion).GetMethod(
"LoadImageDataAtPath",
BindingFlags.Static | BindingFlags.NonPublic);
mbIsMethodCached = true;
return mCachedMethod;
}
static MethodInfo mCachedMethod;
static bool mbIsMethodCached;
}
}