Fix the face count and level count issues in the new crunch decoder

This commit is contained in:
ds5678 2025-09-21 21:48:45 -07:00
parent 61da5e9348
commit 65afadabb3
6 changed files with 6 additions and 111 deletions

View File

@ -11,27 +11,12 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AssetRipper.Conversions.Crunch" Version="1.0.1" />
<PackageReference Include="AssetRipper.Conversions.Crunch" Version="1.0.3" />
<PackageReference Include="AssetRipper.Conversions.FastPng" Version="1.1.0" />
<PackageReference Include="AssetRipper.Conversions.UnityCrunch" Version="1.0.1" />
<PackageReference Include="AssetRipper.Conversions.UnityCrunch" Version="1.0.3" />
<PackageReference Include="AssetRipper.TextureDecoder" Version="2.3.0" />
<PackageReference Include="AssetRipper.Tpk" Version="1.1.0" />
<PackageReference Include="Kyaru.Texture2DDecoder" Version="0.17.0" />
<PackageReference Include="Kyaru.Texture2DDecoder.Windows" Version="0.1.0" />
<PackageReference Include="Kyaru.Texture2DDecoder.macOS" Version="0.1.0" />
<PackageReference Include="Kyaru.Texture2DDecoder.Linux" Version="0.1.0" />
<PackageReference Include="StbImageWriteSharp" Version="1.16.7" />
</ItemGroup>
<ItemGroup>
<ContentWithTargetPath Include="Libraries\x64\crunch_x64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>crunch.dll</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Libraries\x64\crunchunity_x64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>crunchunity.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
</Project>

View File

@ -1,25 +1,16 @@
using AssetRipper.Conversions.Crunch;
using AssetRipper.Conversions.UnityCrunch;
using AssetRipper.Import.Logging;
using AssetRipper.SourceGenerated.Enums;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace AssetRipper.Export.UnityProjects.Textures;
internal static partial class CrunchHandler
internal static class CrunchHandler
{
public static bool DecompressCrunch(TextureFormat textureFormat, UnityVersion unityVersion, ReadOnlySpan<byte> data, [NotNullWhen(true)] out byte[]? uncompressedBytes)
{
/*if (OperatingSystem.IsWindows())
{
return DecompressCrunchWithUtinyDecoder(textureFormat, unityVersion, data, out uncompressedBytes);
}
else
{
return DecompressCrunchWithStudioDecoder(textureFormat, unityVersion, data, out uncompressedBytes);
}*/
return DecompressCrunchWithNewDecoder(textureFormat, unityVersion, data, out uncompressedBytes);
return IsUseUnityCrunch(unityVersion, textureFormat)
? UnityCrunch.TryDecompress(data, out uncompressedBytes)
: Crunch.TryDecompress(data, out uncompressedBytes);
}
private static bool IsUseUnityCrunch(UnityVersion version, TextureFormat format)
@ -30,85 +21,4 @@ internal static partial class CrunchHandler
}
return format is TextureFormat.ETC_RGB4Crunched or TextureFormat.ETC2_RGBA8Crunched;
}
[SupportedOSPlatform("windows")]
[LibraryImport("crunch")]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool DecompressCRN(ReadOnlySpan<byte> pSrcFileData, int srcFileSize, out IntPtr uncompressedData, out int uncompressedSize);
[SupportedOSPlatform("windows")]
[LibraryImport("crunchunity")]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool DecompressUnityCRN(ReadOnlySpan<byte> pSrcFileData, int srcFileSize, out IntPtr uncompressedData, out int uncompressedSize);
[SupportedOSPlatform("windows")]
private static bool DecompressCrunchWithUtinyDecoder(TextureFormat textureFormat, UnityVersion unityVersion, ReadOnlySpan<byte> data, [NotNullWhen(true)] out byte[]? uncompressedBytes)
{
IntPtr uncompressedData = default;
try
{
bool result = IsUseUnityCrunch(unityVersion, textureFormat)
? DecompressUnityCRN(data, data.Length, out uncompressedData, out int uncompressedSize)
: DecompressCRN(data, data.Length, out uncompressedData, out uncompressedSize);
if (result && uncompressedSize > 0 && uncompressedData != default)
{
uncompressedBytes = new byte[uncompressedSize];
Marshal.Copy(uncompressedData, uncompressedBytes, 0, uncompressedSize);
return true;
}
else
{
uncompressedBytes = null;
return false;
}
}
finally
{
if (uncompressedData != default)
{
Marshal.FreeHGlobal(uncompressedData);
}
}
}
private static bool DecompressCrunchWithStudioDecoder(TextureFormat textureFormat, UnityVersion unityVersion, ReadOnlySpan<byte> data, [NotNullWhen(true)] out byte[]? uncompressedBytes)
{
return IsUseUnityCrunch(unityVersion, textureFormat)
? DecompressUnityCrunchWithStudioDecoder(data, out uncompressedBytes)
: DecompressNormalCrunchWithStudioDecoder(data, out uncompressedBytes);
}
private static bool DecompressNormalCrunchWithStudioDecoder(ReadOnlySpan<byte> data, [NotNullWhen(true)] out byte[]? uncompressedBytes)
{
if (data.Length <= 0)
{
throw new ArgumentException(null, nameof(data));
}
Logger.Info("About to unpack normal crunch...");
uncompressedBytes = Texture2DDecoder.TextureDecoder.UnpackCrunch(data);
return uncompressedBytes is { Length: > 0 };
}
private static bool DecompressUnityCrunchWithStudioDecoder(ReadOnlySpan<byte> data, [NotNullWhen(true)] out byte[]? uncompressedBytes)
{
if (data.Length <= 0)
{
throw new ArgumentException(null, nameof(data));
}
Logger.Info("About to unpack unity crunch...");
uncompressedBytes = Texture2DDecoder.TextureDecoder.UnpackUnityCrunch(data);
return uncompressedBytes is { Length: > 0 };
}
private static bool DecompressCrunchWithNewDecoder(TextureFormat textureFormat, UnityVersion unityVersion, ReadOnlySpan<byte> data, [NotNullWhen(true)] out byte[]? uncompressedBytes)
{
return IsUseUnityCrunch(unityVersion, textureFormat)
? UnityCrunch.TryDecompress(data, out uncompressedBytes)
: Crunch.TryDecompress(data, out uncompressedBytes);
}
}