Files
Hasebe/Library/PackageCache/com.unity.bindings.openimageio@94e2abc0bc65/Tests/Editor/OIIOBindingsTests.cs
T
2026-09-24 20:49:06 +03:00

187 lines
7.7 KiB
C#

#define RECORDER_TESTS_DELETE_FILES
using System;
using System.IO;
using NUnit.Framework;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEditor;
using UnityEditor.Bindings.OpenImageIO;
namespace UnityEngine.Bindings.OpenImageIO.Tests
{
class OIIOBindingsTests
{
string m_OutputFilePath;
NativeArray<OiioWrapper.ImageHeader> m_Headers;
NativeArray<OiioWrapper.Attribute> m_Attributes;
NativeArray<ushort> m_ImageBuffer;
private OiioWrapper.SubImagesList? allocatedMemoryForAOVs;
unsafe OiioWrapper.ImageHeader GenerateImageHeader(uint width, uint height, uint channelsCount, NativeArray<ushort> imageBuffer, string extension, int compressionLevel = 100)
{
m_Attributes = new NativeArray<OiioWrapper.Attribute>(extension == "jpg" ? 2 : 1, Allocator.Persistent);
m_Attributes[0] = new OiioWrapper.Attribute()
{
key = "oiio:imageName",
value = "One"
};
if (extension == "jpg")
{
m_Attributes[1] = new OiioWrapper.Attribute()
{
key = "compression",
value = $"jpeg:{compressionLevel}"
};
}
return new OiioWrapper.ImageHeader
{
width = width,
height = height,
channelsCount = channelsCount,
data = new IntPtr(imageBuffer.GetUnsafeReadOnlyPtr()),
attributesCount = (uint)m_Attributes.Length,
attributes = new IntPtr(m_Attributes.GetUnsafeReadOnlyPtr())
};
}
Texture2D LoadImageFromPath(string path)
{
Texture2D outImg = new Texture2D(0, 0);
outImg.LoadImage(File.ReadAllBytes(path));
return outImg;
}
void AssertImagesAreTheSame(Texture2D refImage, Texture2D actualImage)
{
Assert.AreEqual(refImage.width, actualImage.width, $"Expected width to be {refImage.width} but got {actualImage.width}.");
Assert.AreEqual(refImage.height, actualImage.height, $"Expected height to be {refImage.height} but got {actualImage.height}.");
Assert.AreEqual(refImage.GetPixels(), actualImage.GetPixels(), $"Image content is different from expected result.");
}
[TearDown]
public void DeleteGeneratedFiles()
{
if (m_Headers.IsCreated)
m_Headers.Dispose();
if (m_Attributes.IsCreated)
m_Attributes.Dispose();
if (m_ImageBuffer.IsCreated)
m_ImageBuffer.Dispose();
if (allocatedMemoryForAOVs.HasValue)
{
OiioWrapper.FreeAllocatedMemory(allocatedMemoryForAOVs.Value);
allocatedMemoryForAOVs = null;
}
# if RECORDER_TESTS_DELETE_FILES
if (File.Exists($"{m_OutputFilePath}.meta"))
File.Delete($"{m_OutputFilePath}.meta");
if (File.Exists(m_OutputFilePath))
File.Delete(m_OutputFilePath);
#endif
}
[Test]
public void OIIOBindings_SuccessfullyLoaded_WriteEXRImageFile()
{
uint width = 10;
uint height = 10;
uint channelCount = 3;
m_Headers = new NativeArray<OiioWrapper.ImageHeader>(1, Allocator.Persistent);
m_ImageBuffer = new NativeArray<ushort>((int)(width * height * channelCount), Allocator.Persistent);
for (var i = 0; i < width * height * channelCount; ++i)
{
m_ImageBuffer[i] = Mathf.FloatToHalf(0.5f);
}
unsafe
{
m_Headers[0] = GenerateImageHeader(width, height, channelCount, m_ImageBuffer, "exr");
m_OutputFilePath = "Assets/" + Path.GetRandomFileName() + ".exr";
var returnCode = OiioWrapper.WriteImage(m_OutputFilePath, 1,
(OiioWrapper.ImageHeader*)m_Headers.GetUnsafeReadOnlyPtr());
Assert.AreEqual(0, returnCode, $"WriteImage() returned with code: {returnCode}");
Assert.IsTrue(File.Exists(m_OutputFilePath), $"Output file \"{m_OutputFilePath}\" does not exist.");
}
}
[Test]
[TestCase("exr", 0, "f2ff785a344874d429edb7be0065d286", Description = "EXR File Output")]
[TestCase("png", 0, "11249b7f3bcc3594084e04d5f69f5163", Description = "PNG File Output")]
[TestCase("jpg", 70, "bca35194ecf29384eb80cf4666af720e", Description = "JPG File Output", ExcludePlatform = "Linux", Reason = "Editor crashes when writing JPG files on Linux, https://jira.unity3d.com/browse/REC-1669")]
public void OIIOBindings_WriteFilesAsExpected(string extension, int jpgCompression, string referenceImageGUID)
{
unsafe
{
int width = 17;
int height = 31;
int channelCount = 3;
m_Headers = new NativeArray<OiioWrapper.ImageHeader>(1, Allocator.Persistent);
m_ImageBuffer = new NativeArray<ushort>((width * height * channelCount), Allocator.Persistent);
FillBuffer(width, height, channelCount);
m_Headers[0] = GenerateImageHeader((uint)width, (uint)height, (uint)channelCount, m_ImageBuffer, extension, jpgCompression);
m_OutputFilePath = $"Assets/{Path.GetRandomFileName()}.{extension}";
var returnCode = OiioWrapper.WriteImage(m_OutputFilePath, 1,
(OiioWrapper.ImageHeader*)m_Headers.GetUnsafeReadOnlyPtr());
Assert.AreEqual(0, returnCode, $"WriteImage() returned with code: {returnCode}");
Assert.IsTrue(File.Exists(m_OutputFilePath), $"Output file \"{m_OutputFilePath}\" does not exist.");
var path = AssetDatabase.GUIDToAssetPath(referenceImageGUID);
AssertImagesAreTheSame(LoadImageFromPath(path), LoadImageFromPath(m_OutputFilePath));
}
}
[Test]
[TestCase("f2ff785a344874d429edb7be0065d286", Description = "EXR File Input")]
public void OIIOBindings_ReadFilesAsExpected(string referenceImageGUID)
{
var path = AssetDatabase.GUIDToAssetPath(referenceImageGUID);
Assert.IsTrue(File.Exists(path), $"Reference file '{path}' does not exist.");
allocatedMemoryForAOVs = OiioWrapper.ReadImage(Path.GetFullPath(path));
var subImagesArr = OiioWrapper.IntPtrToManagedArray<OiioWrapper.ImageHeader>(allocatedMemoryForAOVs.Value.data, allocatedMemoryForAOVs.Value.subImagesCount);
Assert.AreEqual(1, subImagesArr.Length, "OIIOBindings read wrong number of subImages.");
foreach (var subImage in subImagesArr)
{
var tex = OiioWrapper.Tex2DFromImageHeader(subImage);
AssertImagesAreTheSame(LoadImageFromPath(path), tex);
}
}
private void FillBuffer(int width, int height, int channelCount)
{
for (var row = 0; row < height; row++)
{
ushort red, green, blue;
// Alternating lines (red, green, blue, red, green, blue ...)
red = Mathf.FloatToHalf(row % 3 == 0 ? 1 : 0);
green = Mathf.FloatToHalf(row % 3 == 1 ? 1 : 0);
blue = Mathf.FloatToHalf(row % 3 == 2 ? 1 : 0);
for (var col = 0; col < width; col++)
{
int currPixelStartIdx = (row * width + col) * channelCount;
m_ImageBuffer[currPixelStartIdx] = red;
m_ImageBuffer[currPixelStartIdx + 1] = green;
m_ImageBuffer[currPixelStartIdx + 2] = blue;
}
}
}
}
}