Decompiled source of Skins v0.12.0
Skins.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using CellMenu; using Clonesoft.Json; using Clonesoft.Json.Linq; using Clonesoft.Json.Serialization; using FluffyUnderware.DevTools.Extensions; using GameData; using Gear; using Globals; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using Skins.Assets; using Skins.Config; using Skins.Data; using Skins.Icons; using Skins.Interop; using Skins.Localization; using Skins.Manifest; using Skins.Meshes; using Skins.Patches; using Skins.Target; using Skins.Textures; using Skins.UI; using Skins.UI.Menu; using Skins.UI.Utils; using Skins.Utils; using Skins.Utils.Ext; using StbDxtSharp; using StbImageSharp; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Skins")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Skins")] [assembly: AssemblyTitle("Skins")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Skins { [HarmonyPatch] public class Events { public static event Action? OnGameDataInitialized; public static event Action<Item>? OnGearSpawnComplete; public static event Action? OnElevatorStop; public static event Action? OnBuilderDone; [HarmonyPatch(typeof(GameDataInit), "Initialize")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Postfix__GameDataInit_Initialize() { Events.OnGameDataInitialized?.Invoke(); } [HarmonyPatch(typeof(Item), "OnGearSpawnComplete")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Postfix__Item_OnGearSpawnComplete(Item __instance) { Events.OnGearSpawnComplete?.Invoke(__instance); } [HarmonyPatch(typeof(ItemEquippable), "OnGearSpawnComplete")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Postfix__ItemEquippable_OnGearSpawnComplete(Item __instance) { Events.OnGearSpawnComplete?.Invoke(__instance); } [HarmonyPatch(typeof(GS_StopElevatorRide), "Enter")] [HarmonyWrapSafe] [HarmonyPostfix] public static void Postfix__GS_StopElevatorRide_Enter() { Events.OnElevatorStop?.Invoke(); } [HarmonyPatch(typeof(Builder), "OnFactoryDone")] [HarmonyWrapSafe] [HarmonyPostfix] public static void Postfix__Builder_OnFactoryDone() { Events.OnBuilderDone?.Invoke(); } } internal static class Logger { private static ManualLogSource _mLogSource; public static bool Ready => _mLogSource != null; public static void Setup() { _mLogSource = Logger.CreateLogSource("io.takina.gtfo.Skins"); } public static void SetupFromInit(ManualLogSource logSource) { _mLogSource = logSource; } private static string Format(object data) { return data.ToString(); } public static void Debug(object msg) { if (ConfigMgr.Debug) { _mLogSource.LogDebug((object)Format(msg)); } } public static void Debugf(string fmt, params object[] args) { if (ConfigMgr.Debug) { _mLogSource.LogDebug((object)Format(string.Format(fmt, args))); } } public static void Info(object msg) { _mLogSource.LogInfo((object)Format(msg)); } public static void Infof(string fmt, params object[] args) { _mLogSource.LogInfo((object)Format(string.Format(fmt, args))); } public static void Warn(object msg) { _mLogSource.LogWarning((object)Format(msg)); } public static void Warnf(string fmt, params object[] args) { _mLogSource.LogWarning((object)Format(string.Format(fmt, args))); } public static void Error(object msg) { _mLogSource.LogError((object)Format(msg)); } public static void Errorf(string fmt, params object[] args) { _mLogSource.LogError((object)Format(string.Format(fmt, args))); } public static void Fatal(object msg) { _mLogSource.LogFatal((object)Format(msg)); } public static void Fatalf(string fmt, params object[] args) { _mLogSource.LogFatal((object)Format(string.Format(fmt, args))); } } [BepInPlugin("io.takina.gtfo.Skins", "Skins", "0.12.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { public const string NAME = "Skins"; public const string GUID = "io.takina.gtfo.Skins"; public const string VERSION = "0.12.0"; internal const string GUID_MTFO = "com.dak.MTFO"; internal const string GUID_LEGACY_LOBBY = "dev.aurirex.gtfo.legacylobby"; public static GameObject? PluginObject; public static SkinProcess? UnityBehaviourProcess; public event Action? OnManagersSetup; public override void Load() { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown Logger.Setup(); Logger.Info("Skins [io.takina.gtfo.Skins @ 0.12.0]"); JObject.Parse("{}"); ConfigMgr.Process(); ModData.Initialize(); if (!PersistentConfig<UserConfig>.Load()) { Logger.Fatal("Failed to load user config, aborting plugin load. Please ensure the config file is valid JSON"); return; } Events.OnGameDataInitialized += Loc.InsertToGtfoDB; GearDump.Load(); Application.quitting += Action.op_Implicit((Action)GearDump.FlushNow); MeshDump.Load(); Application.quitting += Action.op_Implicit((Action)MeshDump.FlushNow); ShaderRefs.Preload(); InternalData.Write(); SkinManager.Initialize().RunSync(); RegisterIl2CppTypes(); OnManagersSetup += Initialize; Global.OnAllManagersSetup += Action.op_Implicit(this.OnManagersSetup); Logger.Info("Patching..."); ApplyPatches(new Harmony("io.takina.gtfo.Skins")); Logger.Info("Finished Patching"); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void ApplyPatches(Harmony h) { ApplyPatch<Events>(h); ApplyPatch<GearPatches>(h); ApplyPatch<GearIconPatches>(h); ApplyPatch<GearIcons>(h); ApplyPatch<ShellSkinning>(h); ApplyPatch<UIManager>(h); ApplyPatch<UISettings>(h); h.PatchAll(typeof(Loc)); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void ApplyPatchIfLoaded<T>(Harmony h, string guid) { if (((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey(guid)) { ApplyPatch<T>(h); Logger.Info("Applied compat patches for plugin with GUID " + guid + "."); } else { Logger.Info("Plugin with GUID " + guid + " not found, skipping compat patches for it."); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void ApplyPatch<T>(Harmony h) { h.PatchAll(typeof(T)); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void RegisterIl2CppTypes() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { if (type.GetCustomAttribute<RegisterIl2CppAttribute>() != null) { ClassInjector.RegisterTypeInIl2Cpp(type); } } } private void Initialize() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Initializing..."); _ = Loc.CurrentLocale; UIManager.Initialize(); PluginObject = new GameObject("io.takina.gtfo.Skins"); Object.DontDestroyOnLoad((Object)(object)PluginObject); UnityBehaviourProcess = PluginObject.AddComponent<SkinProcess>(); new GameObject().AddComponent<DevUI>(); } } public static class SkinManager { public static readonly List<InventorySlot> OfflineGearInventorySlots; private static readonly Dictionary<int, ManagedGroupTarget> GroupTargets; private static readonly Dictionary<int, ManagedMaterialTarget> MaterialTargets; private static readonly Dictionary<string, SkinGroup> SkinGroups; private static bool _inReload; public static bool Initialized { get; private set; } public static bool InReload => _inReload; public static IEnumerable<SkinGroup> AllGroups => SkinGroups.Values; static SkinManager() { OfflineGearInventorySlots = new List<InventorySlot> { (InventorySlot)1, (InventorySlot)2, (InventorySlot)3, (InventorySlot)10, (InventorySlot)11 }; Initialized = false; GroupTargets = new Dictionary<int, ManagedGroupTarget>(); MaterialTargets = new Dictionary<int, ManagedMaterialTarget>(); SkinGroups = new Dictionary<string, SkinGroup>(); _inReload = false; Events.OnBuilderDone += RegisterPlayerBackpackTargets; } public static IEnumerator Initialize() { if (Initialized) { Logger.Warn("[SkinManager] Already initialized, skipping initialization."); yield break; } Logger.Info("[SkinManager] Started initialization."); Stopwatch loadTimer = Stopwatch.StartNew(); TextureLibrary.ResetStats(); if (!ConfigMgr.DevEnables(eDevOpts.NoNormalize)) { NormalizeFolder(ModData.SkinsFolder); NormalizeFolder(ModData.PerProfileSkinsFolder); } if (!ConfigMgr.DevEnables(eDevOpts.NoMove)) { MoveSkinGroups(ModData.PerProfileSkinsFolder, ModData.SkinsFolder); } yield return SkinPackageManager.InstallAll(); RegisterGroup(SkinGroup.Vanilla); yield return LoadSkinsFolder(ModData.SkinsFolder); yield return LoadSkinsFolder(ModData.PerProfileSkinsFolder); double manifestMs = loadTimer.Elapsed.TotalMilliseconds; yield return WaitForTextures(); Initialized = true; string value = (ConfigMgr.DevEnables(eDevOpts.NoCompress) ? "off" : "on"); string text = (ConfigMgr.DevEnables(eDevOpts.LegacyLoad) ? "legacy (Unity LoadImage/Compress, main thread)" : $"managed pipeline, {TextureLoader.MaxWorkers} workers"); text += $"; load mode {ConfigMgr.SkinLoadMode}, unload {ConfigMgr.SkinUnloadMode}"; Logger.Info($"[SkinManager] Initialization complete in {loadTimer.Elapsed.TotalMilliseconds:F0} ms (manifests {manifestMs:F0} ms, textures {loadTimer.Elapsed.TotalMilliseconds - manifestMs:F0} ms wall): {SkinGroups.Count - 1} skin group(s), {TextureLibrary.LoadedCount} texture(s) ({(double)TextureLibrary.BytesRead / 1024.0 / 1024.0:F1} MB on disk, ~{(double)TextureLibrary.EstimatedVramBytes / 1024.0 / 1024.0:F0} MB in VRAM); decode {TextureLibrary.DecodeMs:F0} ms + compress {TextureLibrary.CompressMs:F0} ms (summed across threads), upload {TextureLibrary.UploadMs:F0} ms (main thread); loader: {text}; compression {value}, {TextureLibrary.CompressedCount} compressed"); } private static IEnumerator WaitForTextures() { int total = TextureLoader.Pending; if (total == 0) { yield break; } if (_inReload) { DevUI.Instance?.SetCenterDisplayActive(active: true); } while (TextureLoader.Pending > 0) { TextureLoader.Pump(_inReload ? 8 : 0); if (TextureLoader.Pending == 0) { break; } if (_inReload) { int num = total - TextureLoader.Pending; DevUI.Instance?.SetCenterDisplayText($"{Loc.T("settings.reloading")}\n<size=24>textures</size>\n<b>{num}/{total}</b>"); DevUI.Instance?.SetCenterDisplayProgress((float)num / (float)total); yield return null; } else { Thread.Sleep(1); } } if (_inReload) { DevUI.Instance?.SetCenterDisplayActive(active: false); } } private static IEnumerator LoadSkinsFolder(string path) { if (_inReload) { DevUI.Instance?.SetCenterDisplayActive(active: true); yield return null; } List<string> files = FileUtils.FileInEachSubdirectory(path, "manifest.skingroup.json").ToList(); int fileCount = files.Count; int i = 0; while (i < fileCount) { if (UpdateProgress(i, fileCount)) { yield return null; } string text = files[i]; Stopwatch stopwatch = Stopwatch.StartNew(); SkinGroup skinGroup = JsonUtils.DeserializeFromFile<SkinGroup>(text); if (skinGroup == null) { Logger.Warn("[SkinManager] group manifest at '" + text + "' deserialized to null, skipping."); } else if (skinGroup.Initialize(text)) { RegisterGroup(skinGroup); Logger.Info($"[SkinManager] Loaded skin group '{skinGroup.Name}' in {stopwatch.Elapsed.TotalMilliseconds:F0} ms."); } else { Logger.Error($"[SkinManager] Failed to initialize skin group '{skinGroup.Name}' at '{text}', skipping."); } int num = i + 1; i = num; } if (_inReload) { DevUI.Instance?.SetCenterDisplayActive(active: false); } bool UpdateProgress(int current, int total) { if (!_inReload) { return false; } string centerDisplayText = $"{Loc.T("settings.reloading")}\n<size=24>{path}</size>\n<b>{current + 1}/{total}</b>"; DevUI.Instance?.SetCenterDisplayText(centerDisplayText); DevUI.Instance?.SetCenterDisplayProgress((float)current / (float)total); return true; } } private static void NormalizeFolder(string path) { if (!Directory.Exists(path)) { return; } string[] directories = Directory.GetDirectories(path); foreach (string text in directories) { string text2 = Path.Combine(text, "manifest.skingroup.json"); if (!File.Exists(text2)) { Logger.Debug("[SkinManager] NormalizeFolder: no manifest found in '" + text + "', skipping."); continue; } SkinGroup skinGroup = JsonUtils.DeserializeFromFile<SkinGroup>(text2); if (skinGroup == null || string.IsNullOrEmpty(skinGroup.Guid)) { Logger.Warn("[SkinManager] NormalizeFolder: could not read a valid GUID from '" + text2 + "', skipping."); continue; } string fileName = Path.GetFileName(text); if (string.Equals(fileName, skinGroup.Guid, StringComparison.OrdinalIgnoreCase)) { continue; } string text3 = Path.Combine(path, skinGroup.Guid); if (Directory.Exists(text3)) { Logger.Warn($"[SkinManager] NormalizeFolder: cannot rename '{fileName}' -> '{skinGroup.Guid}' -- a folder with that name already exists. Skipping."); continue; } try { Directory.Move(text, text3); Logger.Info($"[SkinManager] NormalizeFolder: renamed '{fileName}' -> '{skinGroup.Guid}'"); } catch (Exception ex) { Logger.Error($"[SkinManager] NormalizeFolder: failed to rename '{fileName}' -> '{skinGroup.Guid}': {ex.Message}"); } } } internal static void MoveSkinGroups(string from, string to, string callerTag = "AutoMove") { if (!Directory.Exists(from)) { return; } string[] directories = Directory.GetDirectories(from); foreach (string text in directories) { string fileName = Path.GetFileName(text); string text2 = Path.Combine(to, fileName); if (Directory.Exists(text2)) { try { Directory.Delete(text2, recursive: true); Logger.Info($"[SkinManager] {callerTag}: removed old global copy of '{fileName}'."); } catch (Exception ex) { Logger.Error($"[SkinManager] {callerTag}: failed to remove existing '{fileName}' from global skins folder, skipping move: {ex.Message}"); continue; } } try { FileUtils.MoveDirectory(text, text2); Logger.Info("[SkinManager] AutoMove: moved '" + fileName + "' to global skins folder."); } catch (Exception ex2) { Logger.Error("[SkinManager] AutoMove: failed to move '" + fileName + "': " + ex2.Message); } } } public static void ApplyGroupToTargetsUnder(SkinGroup group, GameObject root, object owner) { foreach (MeshRenderer componentsInChild in root.GetComponentsInChildren<MeshRenderer>()) { ApplyGroupToRawTarget(group, componentsInChild, owner); } } public static void ReleaseOwner(object owner) { TextureLibrary.ReleaseOwner(owner); MeshLibrary.ReleaseOwner(owner); } public static void SweepIdle() { if (ConfigMgr.SkinLoadMode != eSkinLoadMode.Eager) { float idleSeconds = ((ConfigMgr.SkinUnloadMode == eSkinUnloadMode.Immediate) ? 0f : ((float)ConfigMgr.UnloadIdleSeconds)); int num = TextureLibrary.SweepIdle(idleSeconds); int num2 = MeshLibrary.SweepIdle(idleSeconds); if (num + num2 > 0) { Logger.Info($"[SkinManager] Freed {num} idle texture(s) and {num2} idle mesh(es); resident: {TextureLibrary.ResidentCount} texture(s) (~{(double)TextureLibrary.ResidentVramBytes / 1024.0 / 1024.0:F0} MB), {MeshLibrary.ResidentCount} mesh(es)"); } } } public static void ApplyGroupToRawTarget(SkinGroup group, MeshRenderer meshRenderer, object owner) { Material material = ((Renderer)meshRenderer).material; MeshFilter component = ((Component)meshRenderer).GetComponent<MeshFilter>(); string cleanName = NameUtils.GetCleanName(((Object)material).name); string text = (((Object)(object)component == (Object)null) ? null : NameUtils.GetCleanName(((Object)component.sharedMesh).name)); MaterialSnapshot materialSnapshot = MaterialSnapshot.Capture(material); Dictionary<string, string> textureNames = materialSnapshot.GetTextureNames(); materialSnapshot.Release(); if (text != null && group.TryGetMeshTarget(text, cleanName, out MeshTarget targetOut)) { Mesh val = targetOut.Acquire(owner); if ((Object)(object)val != (Object)null) { component.sharedMesh = val; } } if (!group.TryGetMaterialTarget(cleanName, textureNames, out MaterialTarget targetOut2)) { Logger.Debug($"[ApplyGroupToRawTarget] skin group '{group.Name}' does not have a matching material target for material '{cleanName}' with the required textures."); return; } if (targetOut2.Shader != null && targetOut2.Shader != ((Object)material.shader).name) { Shader val2 = ShaderRefs.Get(targetOut2.Shader); if ((Object)(object)val2 == (Object)null) { Logger.Warn($"[ManagedMaterialTarget] failed to load shader '{targetOut2.Shader}' for material target '{targetOut2.MaterialNameToMatch}' in skin group '{group.Name}'. Shader will not be substituted."); } else { material.shader = val2; } } foreach (var (propertyName, materialProperty2) in targetOut2.Properties) { materialProperty2?.Apply(material, propertyName, owner); } } public static void UpdateTargetsUnder(GameObject go) { foreach (ManagedMaterialTarget componentsInChild in go.GetComponentsInChildren<ManagedMaterialTarget>()) { componentsInChild.UpdateMaterial(); } } public static void UpdateTargetsUnder(GameObject go, string groupGuid) { foreach (ManagedMaterialTarget componentsInChild in go.GetComponentsInChildren<ManagedMaterialTarget>()) { componentsInChild.UpdateMaterial(overrideGroup: true, groupGuid); } } public static void UpdateAllTargets() { foreach (ManagedMaterialTarget value in MaterialTargets.Values) { if (!((Object)(object)value == (Object)null)) { value.UpdateMaterial(); } } } public static void UpdateAllGroups() { foreach (ManagedGroupTarget value in GroupTargets.Values) { if (!((Object)(object)value == (Object)null)) { value.UpdateTargets(); } } } internal static void RegisterPlayerBackpackTargets() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) BackpackItem val = default(BackpackItem); foreach (InventorySlot offlineGearInventorySlot in OfflineGearInventorySlots) { if (!PlayerBackpackManager.LocalBackpack.TryGetBackpackItem(offlineGearInventorySlot, ref val)) { continue; } Item component = ((Component)val.Instance).GetComponent<Item>(); if ((Object)(object)component == (Object)null) { Logger.Debug("[SkinManager] RegisterPlayerBackpackTargets: no Item component found on backpack item in slot " + $"{offlineGearInventorySlot}, skipping ManagedGroupTarget setup for this item."); continue; } ManagedGroupTarget orAddComponent = ((Component)component).gameObject.GetOrAddComponent<ManagedGroupTarget>(); if ((Object)(object)orAddComponent == (Object)null) { Logger.Error("[SkinManager] RegisterPlayerBackpackTargets: failed to add ManagedGroupTarget component to backpack item in slot " + $"{offlineGearInventorySlot}, skipping ManagedGroupTarget setup for this item."); } else if (!((Object)(object)orAddComponent.BulletWeapon == (Object)null)) { BulletWeapon bulletWeapon = orAddComponent.BulletWeapon; if (GearUtils.TryGetOfflineGearId(((ItemEquippable)bulletWeapon).GearIDRange, out var gearId) && ((ItemEquippable)bulletWeapon).ShellCasingData != null) { ShellSkinning.SetupPoolForGear(gearId, ((ItemEquippable)bulletWeapon).ShellCasingData.ShellCasingType); } } } } public static IEnumerator Reload() { if (_inReload) { Logger.Warn("[SkinManager] Already reloading!"); yield break; } _inReload = true; try { GearIcons.BeforeReload(); Unload(); yield return Initialize(); UpdateAllTargets(); ShellSkinning.RebuildPools(); GearIcons.OnSkinsReloaded(); } finally { _inReload = false; DevUI.Instance?.SetCenterDisplayActive(active: false); } } public static void Unload() { if (_inReload) { DevUI.Instance?.SetCenterDisplayActive(active: true); DevUI.Instance?.SetCenterDisplayText("Unloading Assets..."); } SkinGroups.Clear(); TextureLoader.CancelAll(); TextureLibrary.UnloadAll(); TextureMacro.UnloadAll(); MeshLibrary.UnloadAll(); Initialized = false; if (_inReload) { DevUI.Instance?.SetCenterDisplayActive(active: false); } } public static bool TryGetGroup(string guid, [NotNullWhen(true)] out SkinGroup? group) { return SkinGroups.TryGetValue(guid, out group); } public static List<SkinGroup> GetAllMatchingGroups(TargetContext ctx) { List<SkinGroup> list = new List<SkinGroup>(); Logger.Debug($"[SkinManager] GetAllMatchingGroups => {ctx}"); foreach (SkinGroup value in SkinGroups.Values) { if (value.IsMatch(ctx)) { list.Add(value); Logger.Debug($"[SkinManager] GetAllMatchingGroups => MATCH '{value.Name}' ({value.Guid})"); } } return list; } public static SkinGroup? GetCurrentSkinGroupOfGear(uint gearPersistentId) { if (!GameDataBlockBase<PlayerOfflineGearDataBlock>.HasBlock(gearPersistentId)) { return null; } if (PersistentConfig<UserConfig>.Instance == null) { return null; } if (PersistentConfig<UserConfig>.Instance.CurrentSkinConfig.OfflineGear.TryGetValue(gearPersistentId, out string value)) { if (SkinGroups.TryGetValue(value, out SkinGroup value2)) { return value2; } PersistentConfig<UserConfig>.Instance.CurrentSkinConfig.OfflineGear[gearPersistentId] = "10chambers.vanilla"; PersistentConfig<UserConfig>.Save(); } return SkinGroup.Vanilla; } public static SkinGroup? GetAnyMatchingGroup(TargetContext ctx) { foreach (SkinGroup value in SkinGroups.Values) { if (value.IsMatch(ctx)) { return value; } } return null; } private static bool RegisterGroup(SkinGroup group) { if (string.IsNullOrEmpty(group.Guid)) { Logger.Error($"Failed to register skin group '{group.Name}' because it has an empty guid."); return false; } if (!SkinGroups.TryAdd(group.Guid, group)) { Logger.Warn($"Unable to register skin group '{group.Name}' ({group.Guid}) because a group with the same guid already exists. Skipping."); return false; } return true; } internal static void RegisterGroupTarget(ManagedGroupTarget target) { GroupTargets.Add(((Object)target).GetInstanceID(), target); } internal static void UnregisterGroupTarget(ManagedGroupTarget target) { GroupTargets.Remove(((Object)target).GetInstanceID()); } internal static void RegisterMatTarget(ManagedMaterialTarget target) { MaterialTargets.Add(((Object)target).GetInstanceID(), target); } internal static void UnregisterMatTarget(ManagedMaterialTarget target) { MaterialTargets.Remove(((Object)target).GetInstanceID()); } } public class SkinPackageManager { public const string SkinPackageExtension = ".skinspkg"; public static IEnumerator InstallAll() { List<string> pkgFiles = FileUtils.FilesWithExtension(ModData.SkinsFolder, ".skinspkg").ToList(); int pkgFileCount = pkgFiles.Count; if (pkgFileCount == 0) { yield break; } if (SkinManager.InReload) { DevUI.Instance?.SetCenterDisplayActive(active: true); yield return null; } for (int i = 0; i < pkgFileCount; i++) { string pkgFile = pkgFiles[i]; if (UpdateProgress(i, pkgFileCount, Path.GetFileName(pkgFile), Loc.T("settings.install.unpack"))) { yield return null; } if (!Unpack(pkgFile)) { Logger.Error("[SkinPackageManager] InstallAll: failed to unpack package '" + pkgFile + "'."); continue; } if (UpdateProgress(i, pkgFileCount, Path.GetFileName(pkgFile), Loc.T("settings.install.normalize"))) { yield return null; } StagingNormalize(ModData.SkinsStagingFolder); string[] stagingGroups = (Directory.Exists(ModData.SkinsStagingFolder) ? Directory.GetDirectories(ModData.SkinsStagingFolder) : Array.Empty<string>()); if (stagingGroups.Length == 0) { Logger.Error("[SkinPackageManager] InstallAll: package '" + Path.GetFileName(pkgFile) + "' contained no valid skin groups after normalization, skipping."); continue; } if (UpdateProgress(i, pkgFileCount, Path.GetFileName(pkgFile), Loc.T("settings.install.move"))) { yield return null; } SkinManager.MoveSkinGroups(ModData.SkinsStagingFolder, ModData.SkinsFolder); Logger.Info($"[SkinPackageManager] InstallAll: successfully installed package '{pkgFile}' with {stagingGroups.Length} skin groups."); try { File.Delete(pkgFile); } catch (Exception ex) { Logger.Error("[SkinPackageManager] InstallAll: failed to delete package file '" + pkgFile + "' after installation: " + ex.Message); } } CleanupStagingArea(); if (SkinManager.InReload) { DevUI.Instance?.SetCenterDisplayActive(active: false); } static bool UpdateProgress(int completed, int total, string processing, string message) { if (!SkinManager.InReload) { return false; } string centerDisplayText = $"{Loc.T("settings.installing")}\n<size=24>{processing}</size>\n<b>{completed + 1}/{total}</b>{(string.IsNullOrWhiteSpace(message) ? "" : (" " + message))}"; DevUI.Instance?.SetCenterDisplayText(centerDisplayText); DevUI.Instance?.SetCenterDisplayProgress((float)completed / (float)total); return true; } } private static bool SetupStagingArea() { try { Directory.CreateDirectory(ModData.SkinsStagingFolder); return true; } catch (Exception ex) { Logger.Error("[SkinPackageManager] SetupStagingArea: failed to create staging directory '" + ModData.SkinsStagingFolder + "': " + ex.Message); return false; } } private static bool CleanupStagingArea() { if (!Directory.Exists(ModData.SkinsStagingFolder)) { return true; } try { Directory.Delete(ModData.SkinsStagingFolder, recursive: true); return true; } catch (Exception ex) { Logger.Error("[SkinPackageManager] CleanupStagingArea: failed to clear staging directory '" + ModData.SkinsStagingFolder + "': " + ex.Message); return false; } } private static bool Unpack(string packageFile) { if (!CleanupStagingArea()) { return false; } if (!SetupStagingArea()) { return false; } try { ZipFile.ExtractToDirectory(packageFile, ModData.SkinsStagingFolder); return true; } catch (Exception ex) { Logger.Error("[SkinPackageManager] Unpack: failed to unpack package '" + packageFile + "': " + ex.Message); return false; } } private static void StagingNormalize(string folderPath) { if (!Directory.Exists(folderPath)) { return; } string[] directories = Directory.GetDirectories(folderPath); foreach (string text in directories) { string text2 = Path.Combine(text, "manifest.skingroup.json"); if (!File.Exists(text2)) { Logger.Debug("[SkinPackageManager] NormalizeFolder: no manifest found in '" + text + "', skipping."); continue; } SkinGroup skinGroup = JsonUtils.DeserializeFromFile<SkinGroup>(text2); if (skinGroup == null || string.IsNullOrEmpty(skinGroup.Guid)) { Logger.Error("[SkinPackageManager] NormalizeFolder: could not read a valid GUID from '" + text2 + "'. Unstaging folder for installation."); try { Directory.Delete(text, recursive: true); } catch (Exception ex) { Logger.Error("[SkinPackageManager] NormalizeFolder: failed to delete & unstage folder '" + text + "': " + ex.Message); } continue; } string fileName = Path.GetFileName(text); if (string.Equals(fileName, skinGroup.Guid, StringComparison.OrdinalIgnoreCase)) { continue; } string text3 = Path.Combine(folderPath, skinGroup.Guid); if (Directory.Exists(text3)) { Logger.Error($"[SkinPackageManager] NormalizeFolder: cannot rename '{fileName}' -> '{skinGroup.Guid}' -- a folder with that name already exists. Unstaging folder for installation."); try { Directory.Delete(text, recursive: true); } catch (Exception ex2) { Logger.Error("[SkinPackageManager] NormalizeFolder: failed to delete & unstage folder '" + text + "': " + ex2.Message); } continue; } try { Directory.Move(text, text3); Logger.Info($"[SkinPackageManager] NormalizeFolder: renamed '{fileName}' -> '{skinGroup.Guid}'"); } catch (Exception ex3) { Logger.Error($"[SkinPackageManager] NormalizeFolder: failed to rename '{fileName}' -> '{skinGroup.Guid}': {ex3.Message}"); } } } } [RegisterIl2Cpp] public class SkinProcess : MonoBehaviour { private const float DumpDirtyCheckInterval = 30f; private const float SweepInterval = 1f; private const double TextureUploadBudgetMs = 4.0; private float _nextDumpDirtyCheckTime; private float _nextSweepTime; private void Update() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) TextureLoader.Pump(4.0); GearIcons.Pump(4.0); GearIconPatches.Tick(); if (Time.time >= _nextSweepTime) { SkinManager.SweepIdle(); _nextSweepTime = Time.time + 1f; } if (ConfigMgr.EnableHotReloadKey && Input.GetKeyDown(ConfigMgr.HotReloadKey)) { ((MonoBehaviour)this).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(SkinManager.Reload())); } if (Time.time >= _nextDumpDirtyCheckTime) { GearDump.FlushNow(); MeshDump.FlushNow(); _nextDumpDirtyCheckTime = Time.time + 30f; } } } } namespace Skins.Utils { public static class FileUtils { public static IEnumerable<string> FileInEachSubdirectory(string dir, string fileName) { if (!Directory.Exists(dir)) { yield break; } foreach (string item in Directory.EnumerateDirectories(dir)) { string text = Path.Combine(item, fileName); if (File.Exists(text)) { yield return text; } } } public static IEnumerable<string> FilesWithExtensionRecursive(string dir, string extension) { if (!Directory.Exists(dir)) { yield break; } string text = (extension.StartsWith(".") ? extension : ("." + extension)); foreach (string item in Directory.EnumerateFiles(dir, "*" + text, SearchOption.AllDirectories)) { yield return item; } } public static IEnumerable<string> FilesWithExtension(string dir, string extension) { if (!Directory.Exists(dir) || string.IsNullOrWhiteSpace(extension)) { yield break; } string text = (extension.StartsWith(".") ? extension : ("." + extension)); foreach (string item in Directory.EnumerateFiles(dir, "*" + text, SearchOption.TopDirectoryOnly)) { yield return item; } } public static void MoveFile(string sourcePath, string destPath, bool overwrite = false) { if (!File.Exists(sourcePath)) { Logger.Warn("[FileUtils] Source file does not exist: " + sourcePath); return; } if (File.Exists(destPath)) { if (!overwrite) { Logger.Warn("[FileUtils] Destination file already exists: " + destPath); return; } File.Delete(destPath); } File.Copy(sourcePath, destPath); File.Delete(sourcePath); } public static void MoveDirectory(string sourceDir, string destDir, bool overwrite = false) { if (!Directory.Exists(sourceDir)) { Logger.Warn("[FileUtils] Source directory does not exist: " + sourceDir); return; } if (Directory.Exists(destDir)) { if (!overwrite) { Logger.Warn("[FileUtils] Destination directory already exists: " + destDir); return; } Directory.Delete(destDir, recursive: true); } Directory.CreateDirectory(destDir); foreach (string item in Directory.EnumerateFiles(sourceDir)) { string destFileName = Path.Combine(destDir, Path.GetFileName(item)); File.Copy(item, destFileName); File.Delete(item); } foreach (string item2 in Directory.EnumerateDirectories(sourceDir)) { string destDir2 = Path.Combine(destDir, Path.GetFileName(item2)); MoveDirectory(item2, destDir2, overwrite); } Directory.Delete(sourceDir); } } public static class GearUtils { private const string GearIdPattern = "^OfflineGear_ID_(\\d+)$"; private static readonly Regex GearIdRe = new Regex("^OfflineGear_ID_(\\d+)$", RegexOptions.Compiled); public static uint? ExtractOfflineGearId(string? gearPartId) { if (gearPartId == null) { return null; } Match match = GearIdRe.Match(gearPartId); if (!match.Success) { return null; } if (uint.TryParse(match.Groups[1].Value, out var result)) { return result; } return null; } public static bool TryGetOfflineGearId(BackpackItem item, out uint gearId) { if (item.GearIDRange != null) { return TryGetOfflineGearId(item.GearIDRange, out gearId); } gearId = 0u; return false; } public static bool TryGetOfflineGearId(ItemEquippable item, out uint gearId) { if (item.GearIDRange != null) { return TryGetOfflineGearId(item.GearIDRange, out gearId); } gearId = 0u; return false; } public static bool TryGetOfflineGearId(GearIDRange idRange, out uint gearId) { uint? num = ExtractOfflineGearId(idRange.PlayfabItemInstanceId); if (num.HasValue) { gearId = num.Value; return true; } gearId = 0u; return false; } public static bool TryGetShellType(GearIDRange? idRange, out ShellTypes type) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected I4, but got Unknown type = (ShellTypes)0; if (idRange == null) { return false; } uint compID = idRange.GetCompID((eGearComponent)7); if (!GameDataBlockBase<WeaponShellCasingDataBlock>.HasBlock(compID)) { return false; } WeaponShellCasingDataBlock block = GameDataBlockBase<WeaponShellCasingDataBlock>.GetBlock(compID); type = (ShellTypes)(int)block.ShellCasingType; return true; } public static bool TryGetShellTypePrefab(ShellTypes type, [NotNullWhen(true)] out GameObject? prefab) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected I4, but got Unknown WeaponShellManager current = WeaponShellManager.Current; prefab = (GameObject?)((type - 1) switch { 0 => current.m_shell_9mm_prefab, 1 => current.m_shell_45_ACP_prefab, 2 => current.m_shell_338_prefab, 3 => current.m_shell_12_Gauge_prefab, _ => null, }); return (Object)(object)prefab != (Object)null; } } public static class GuiUtils { public static void SetItemColor(CM_Item item, Color spriteColor, Color textColorAll) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) Color spriteColorOut = default(Color); ((Color)(ref spriteColorOut))..ctor(spriteColor.r, spriteColor.g, spriteColor.b, item.m_spriteAlphaOut); Color spriteColorOver = default(Color); ((Color)(ref spriteColorOver))..ctor(spriteColor.r, spriteColor.g, spriteColor.b, item.m_spriteAlphaOver); Color val = default(Color); ((Color)(ref val))..ctor(textColorAll.r, textColorAll.g, textColorAll.b, item.m_textAlphaOut); Color val2 = default(Color); ((Color)(ref val2))..ctor(textColorAll.r, textColorAll.g, textColorAll.b, item.m_textAlphaOver); item.m_spriteColorOrg = spriteColor; item.m_spriteColorOut = spriteColorOut; item.m_spriteColorOver = spriteColorOver; if (item.m_texts != null) { for (int i = 0; i < ((Il2CppArrayBase<TextMeshPro>)(object)item.m_texts).Count; i++) { ((Il2CppArrayBase<Color>)(object)item.m_textColorOrg)[i] = textColorAll; ((Il2CppArrayBase<Color>)(object)item.m_textColorOut)[i] = val; ((Il2CppArrayBase<Color>)(object)item.m_textColorOver)[i] = val2; } } item.OnHoverOut(); } public static void FixLobbyScrollItem(CM_LobbyScrollItem item, float? newX = null, float? newY = null, float leftLineThickness = 12f, float lineThickness = 4f) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = ((Il2CppObjectBase)((Component)item).transform).TryCast<RectTransform>(); RectTransform component = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineT", true)).GetComponent<RectTransform>(); RectTransform component2 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineB", true)).GetComponent<RectTransform>(); RectTransform component3 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineL", true)).GetComponent<RectTransform>(); RectTransform component4 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineR", true)).GetComponent<RectTransform>(); RectTransform component5 = ((Component)((Transform)component).parent).GetComponent<RectTransform>(); RectTransform component6 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)component5, "Background", true)).GetComponent<RectTransform>(); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(newX ?? component5.sizeDelta.x, newY ?? component5.sizeDelta.y); component5.sizeDelta = val; component6.anchorMin = Vector2.zero; component6.anchorMax = Vector2.one; component6.offsetMin = Vector2.zero; component6.offsetMax = Vector2.zero; component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.offsetMin = new Vector2(0f, 0f - lineThickness); component.offsetMax = new Vector2(0f, 0f); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(1f, 0f); component2.offsetMin = new Vector2(0f, 0f - lineThickness); component2.offsetMax = new Vector2(0f, 0f); component3.anchorMin = new Vector2(0f, 0f); component3.anchorMax = new Vector2(0f, 1f); component3.offsetMin = new Vector2(0f, 0f); component3.offsetMax = new Vector2(leftLineThickness, 0f); component4.anchorMin = new Vector2(1f, 0f); component4.anchorMax = new Vector2(1f, 1f); component4.offsetMin = new Vector2(0f, 0f); component4.offsetMax = new Vector2(lineThickness, 0f); foreach (UI_SpriteResizer componentsInChild in ((Component)item).GetComponentsInChildren<UI_SpriteResizer>()) { if (Object.op_Implicit((Object)(object)componentsInChild)) { componentsInChild.Resize(); } } ((CM_Item)item).m_collider.size = val; } } public static class JsonUtils { public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings { ContractResolver = (IContractResolver)(object)new SkinsContractResolver() }; public static T? Deserialize<T>(string json) { return JsonConvert.DeserializeObject<T>(json, Settings); } public static T? DeserializeFromFile<T>(string path) { if (!File.Exists(path)) { Logger.Warn("[JsonUtils] File not found: '" + path + "'"); return default(T); } return Deserialize<T>(File.ReadAllText(path)); } } public class SkinsContractResolver : DefaultContractResolver { protected override JsonConverter? ResolveContractConverter(Type objectType) { if (objectType == typeof(IMaterialProperty)) { return (JsonConverter?)(object)new MaterialPropertyConverter(); } return ((DefaultContractResolver)this).ResolveContractConverter(objectType); } } [RegisterIl2Cpp] public class LifecycleHook : MonoBehaviour { public event Action? OnStarted; public event Action? OnEnabled; public event Action? OnDisabled; public event Action? OnDestroyed; private void Start() { this.OnStarted?.Invoke(); } private void OnEnable() { this.OnEnabled?.Invoke(); } private void OnDisable() { this.OnDisabled?.Invoke(); } private void OnDestroy() { this.OnDestroyed?.Invoke(); } } public class LocaleUtils { public static readonly Dictionary<string, string> LocaleKeyToDisplayName = new Dictionary<string, string> { { "en", "English" }, { "fr", "Français" }, { "de", "Deutsch" }, { "es", "Español" }, { "it", "Italiano" }, { "ja", "日本語" }, { "ko", "한국어" }, { "pt-BR", "Português (Brasil)" }, { "ru", "Русский" }, { "pl", "Polski" }, { "zh-Hans", "简体中文" }, { "zh-Hant", "繁體中文" } }; public static string LocaleKeyFromEnum(Language key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected I4, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) return (key - 1) switch { 0 => "en", 1 => "fr", 3 => "de", 4 => "es", 2 => "it", 8 => "ja", 9 => "ko", 6 => "pt-BR", 5 => "ru", 7 => "pl", 11 => "zh-Hans", 10 => "zh-Hant", _ => throw new ArgumentOutOfRangeException("key", key, null), }; } public static void SetTranslation(TextDataBlock db, string locale, string text) { switch (locale) { case "en": db.English = text; break; case "fr": db.French = LanguageData.op_Implicit(text); break; case "de": db.German = LanguageData.op_Implicit(text); break; case "es": db.Spanish = LanguageData.op_Implicit(text); break; case "it": db.Italian = LanguageData.op_Implicit(text); break; case "ja": db.Japanese = LanguageData.op_Implicit(text); break; case "ko": db.Korean = LanguageData.op_Implicit(text); break; case "pt-BR": db.Portuguese_Brazil = LanguageData.op_Implicit(text); break; case "ru": db.Russian = LanguageData.op_Implicit(text); break; case "pl": db.Polish = LanguageData.op_Implicit(text); break; case "zh-Hans": db.Chinese_Simplified = LanguageData.op_Implicit(text); break; case "zh-Hant": db.Chinese_Traditional = LanguageData.op_Implicit(text); break; } } public static uint GetSlotGearSelectTextDbId(InventorySlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 switch (slot - 1) { default: if ((int)slot == 10) { return 490u; } return 0u; case 0: return 487u; case 1: return 488u; case 2: return 489u; } } public static string GetSlotGearSelectLocalizedText(InventorySlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return Text.Get(GetSlotGearSelectTextDbId(slot)); } } public static class LogDumper { private static readonly Dictionary<string, StreamWriter> LogStreams = new Dictionary<string, StreamWriter>(); private static readonly Dictionary<string, HashSet<int>> LoggedIds = new Dictionary<string, HashSet<int>>(); public static void Dump(string name, string content, bool append = false) { if (!LogStreams.TryGetValue(name, out StreamWriter value)) { value = new StreamWriter(Path.Combine(ModData.DumpFolder, name + ".log"), append); LogStreams[name] = value; LoggedIds[name] = new HashSet<int>(); } value.WriteLine(content); value.Flush(); } public static void DumpUnique(string name, int id, string content, bool append = false) { if (!LogStreams.TryGetValue(name, out StreamWriter value)) { value = new StreamWriter(Path.Combine(ModData.DumpFolder, name + ".log"), append); LogStreams[name] = value; LoggedIds[name] = new HashSet<int>(); } if (!LoggedIds[name].Contains(id)) { value.WriteLine(content); value.Flush(); LoggedIds[name].Add(id); } } } public static class NameUtils { private static readonly Regex CleanPattern = new Regex("\\s*(?:\\(Clone\\)|\\(Instance\\)|Instance).*$", RegexOptions.Compiled); public static string GetCleanName(string name) { return CleanPattern.Replace(name, ""); } } public static class PluginUtils { public static bool IsPluginLoaded(string pluginGuid) { return ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey(pluginGuid); } } public static class TextureUtils { public static Texture2D CreateBlankWhiteTexture() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, Color.white); val.Apply(); return val; } public static Texture2D CreateBlankTexture(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } public static Sprite SpriteFromRenderTexture(RenderTexture rt) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(((Texture)rt).width, ((Texture)rt).height, (TextureFormat)4, false); RenderTexture active = RenderTexture.active; RenderTexture.active = rt; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)rt).width, (float)((Texture)rt).height), 0, 0); val.Apply(); RenderTexture.active = active; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } public static Sprite SpriteFromTexture2D(Texture2D tex) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) float num = ((Texture)tex).width; float num2 = ((Texture)tex).height; return Sprite.Create(tex, new Rect(0f, 0f, num, num2), new Vector2(0.5f, 0.5f)); } public static TextureOptions InferOptionsFromSlot(string slot) { return new TextureOptions(slot switch { "_BumpMap" => true, "_MetallicGlossMap" => true, "_AOCurveTex" => true, "_SpecGlossMap" => true, "_HeightMap" => true, "_DistortionTex" => true, "_DistortionSignal" => true, _ => false, }, PersistentConfig<UserConfig>.Instance?.PluginConfig.EnableMipMaps ?? false); } } public class TMPUtils { public static bool CreateTMP(string name, Transform? parent, [NotNullWhen(true)] out TextMeshPro? tp) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) WatermarkGuiLayer watermarkLayer = GuiManager.WatermarkLayer; object obj; if (watermarkLayer == null) { obj = null; } else { PUI_Watermark watermark = watermarkLayer.m_watermark; obj = ((watermark != null) ? watermark.m_fpsText : null); } TextMeshPro val = (TextMeshPro)obj; if ((Object)(object)parent == (Object)null || (Object)(object)val == (Object)null) { tp = null; return false; } tp = Object.Instantiate<TextMeshPro>(val, parent, false); ((Object)tp).name = name; ((TMP_Text)tp).rectTransform.anchorMax = new Vector2(0.5f, 0.5f); ((TMP_Text)tp).rectTransform.anchorMin = new Vector2(0.5f, 0.5f); ((TMP_Text)tp).rectTransform.pivot = new Vector2(1f, 0f); ((TMP_Text)tp).rectTransform.anchoredPosition3D = new Vector3(0f, 2f, 0f); ((Transform)((TMP_Text)tp).rectTransform).localRotation = Quaternion.Euler(0f, 0f, 0f); ((TMP_Text)tp).enableAutoSizing = false; ((TMP_Text)tp).overflowMode = (TextOverflowModes)0; ((TMP_Text)tp).alignment = (TextAlignmentOptions)513; ((TMP_Text)tp).fontSize = 16f; return true; } public static bool CreateTMPUGUI(string name, Transform? parent, [NotNullWhen(true)] out TextMeshProUGUI? tp) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) WatermarkGuiLayer watermarkLayer = GuiManager.WatermarkLayer; object obj; if (watermarkLayer == null) { obj = null; } else { PUI_Watermark watermark = watermarkLayer.m_watermark; obj = ((watermark != null) ? watermark.m_fpsText : null); } TextMeshPro val = (TextMeshPro)obj; GameObject val2 = new GameObject(); val2.transform.SetParent(parent, false); tp = val2.AddComponent<TextMeshProUGUI>(); ((Object)tp).name = name; ((TMP_Text)tp).rectTransform.anchorMax = new Vector2(0.5f, 0.5f); ((TMP_Text)tp).rectTransform.anchorMin = new Vector2(0.5f, 0.5f); ((TMP_Text)tp).rectTransform.pivot = new Vector2(0.5f, 0.5f); ((TMP_Text)tp).rectTransform.anchoredPosition3D = new Vector3(0f, 0f, 0f); ((Transform)((TMP_Text)tp).rectTransform).localRotation = Quaternion.Euler(0f, 0f, 0f); ((TMP_Text)tp).enableAutoSizing = false; ((TMP_Text)tp).overflowMode = (TextOverflowModes)0; ((TMP_Text)tp).alignment = (TextAlignmentOptions)514; ((TMP_Text)tp).fontSize = 16f; if ((Object)(object)val != (Object)null) { ((TMP_Text)tp).font = ((TMP_Text)val).font; ((TMP_Text)tp).fontSharedMaterial = ((TMP_Text)val).fontSharedMaterial; } return true; } } } namespace Skins.Utils.Ext { public static class BackpackExtensions { public static TargetContext GetContextForSlot(this PlayerBackpack bkpk, InventorySlot slot) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 TargetContext targetContext = new TargetContext(); BackpackItem item = default(BackpackItem); if ((slot - 1 <= 2 || (int)slot == 10) && bkpk.TryGetBackpackItem(slot, ref item) && GearUtils.TryGetOfflineGearId(item, out var gearId)) { targetContext.OfflineGearId = gearId; } return targetContext; } } public static class ComponentExtensions { public static T? AddComponentIfMissing<T>(this GameObject obj) where T : Component { if (!((Object)(object)obj.GetComponent<T>() == (Object)null)) { return default(T); } return obj.AddComponent<T>(); } public static T GetOrAddComponent<T>(this GameObject obj) where T : Component { T val = obj.GetComponent<T>(); if ((Object)(object)val == (Object)null) { val = obj.AddComponent<T>(); } return val; } public static T? GetComponentSafe<T>(this GameObject? obj) where T : Component { if ((Object)(object)obj == (Object)null) { return default(T); } return obj.GetComponent<T>(); } public static T? GetComponentSafe<T>(this Component? obj) where T : Component { if ((Object)(object)obj == (Object)null) { return default(T); } return obj.GetComponent<T>(); } } public static class EnumeratorExtensions { public static void RunSync(this IEnumerator enumerator) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); stack.Push(enumerator); while (stack.Count > 0) { IEnumerator enumerator2 = stack.Peek(); if (enumerator2.MoveNext()) { if (enumerator2.Current is IEnumerator item) { stack.Push(item); } } else { stack.Pop(); } } } } } namespace Skins.UI { [RegisterIl2Cpp] public class DevUI : MonoBehaviour { private static readonly Vector2 ReferenceResolution = new Vector2(2560f, 1440f); private Canvas _canvas; private CanvasScaler _canvasScaler; private GameObject _centerContainer; private Image _centerContainerImage; private TMP_Text _centerDisplayTxt; private Image _progressBarFill; private RectTransform _progressBarFillRt; public static DevUI? Instance { get; private set; } = null; private void Awake() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance != (Object)null) { Logger.Warn("[DevUI] Instance already exists, destroying new instance."); Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); ((Object)((Component)this).gameObject).name = "io.takina.gtfo.Skins.DevUI"; _canvas = ((Component)this).gameObject.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 1000; _canvasScaler = ((Component)this).gameObject.AddComponent<CanvasScaler>(); _canvasScaler.uiScaleMode = (ScaleMode)1; _canvasScaler.referenceResolution = ReferenceResolution; _canvasScaler.m_MatchWidthOrHeight = 1f; CreateElements(); } public void SetCenterDisplayActive(bool active) { if (!((Object)(object)_centerContainer == (Object)null)) { _centerContainer.SetActive(active); } } public void SetCenterDisplayText(string text) { if (!((Object)(object)_centerDisplayTxt == (Object)null)) { _centerDisplayTxt.text = text; } } public void SetCenterDisplayProgress(float progress) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_progressBarFill == (Object)null)) { RectTransform progressBarFillRt = _progressBarFillRt; progressBarFillRt.anchorMin = Vector2.zero; progressBarFillRt.anchorMax = new Vector2(Mathf.Clamp01(progress), 1f); progressBarFillRt.offsetMin = Vector2.zero; progressBarFillRt.offsetMax = Vector2.zero; } } private void CreateElements() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) _centerContainer = new GameObject("CenterTextDisplay Container"); _centerContainer.transform.SetParent(((Component)this).gameObject.transform, false); RectTransform obj = _centerContainer.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0f, 0.33f); obj.anchorMax = new Vector2(1f, 0.66f); obj.anchoredPosition = Vector2.zero; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; _centerContainerImage = _centerContainer.AddComponent<Image>(); ((Graphic)_centerContainerImage).color = new Color(0f, 0f, 0f, 0.95f); if (TMPUtils.CreateTMPUGUI("io.takina.gtfo.Skins.CenterTextDisplay", _centerContainer.transform, out TextMeshProUGUI tp)) { ((TMP_Text)tp).enableAutoSizing = true; ((TMP_Text)tp).m_maxFontSize = 100f; ((TMP_Text)tp).m_minFontSize = 32f; ((Graphic)tp).color = UIManager.AccentColor; ((TMP_Text)tp).rectTransform.sizeDelta = new Vector2(ReferenceResolution.x, ReferenceResolution.y / 3f); _centerDisplayTxt = (TMP_Text)(object)tp; } GameObject val = new GameObject("ProgressBar Background"); val.transform.SetParent(_centerContainer.transform, false); RectTransform obj2 = val.AddComponent<RectTransform>(); obj2.anchorMin = new Vector2(0f, 0f); obj2.anchorMax = new Vector2(1f, 0f); obj2.pivot = new Vector2(0.5f, 0f); obj2.anchoredPosition = Vector2.zero; obj2.sizeDelta = new Vector2(0f, 8f); ((Graphic)val.AddComponent<Image>()).color = new Color(1f, 1f, 1f, 0.15f); GameObject val2 = new GameObject("ProgressBar Fill"); val2.transform.SetParent(val.transform, false); _progressBarFillRt = val2.AddComponent<RectTransform>(); _progressBarFillRt.anchorMin = Vector2.zero; _progressBarFillRt.anchorMax = Vector2.one; _progressBarFillRt.offsetMin = Vector2.zero; _progressBarFillRt.offsetMax = Vector2.zero; _progressBarFill = val2.AddComponent<Image>(); ((Graphic)_progressBarFill).color = UIManager.AccentColor; _progressBarFill.type = (Type)3; _progressBarFill.fillMethod = (FillMethod)0; _progressBarFill.fillAmount = 0f; _centerContainer.SetActive(false); } } [HarmonyPatch] public class UIManager { public static readonly Color AccentColor = Color32.op_Implicit(new Color32((byte)137, (byte)180, (byte)250, byte.MaxValue)); private static readonly Action<int> OnOfflineGearShowSkinSelectPopup = OpenOfflineGearSkinSelect; public static readonly List<InventorySlot> GearSlots = new List<InventorySlot> { (InventorySlot)1, (InventorySlot)2, (InventorySlot)3, (InventorySlot)10 }; private static Sprite? _pluginIcon = null; public static void Initialize() { Text.UpdateAllTexts(); Texture2D val = TextureLibrary.Load(Path.Combine(ModData.PluginFolder, "icon.png"), default(TextureOptions), managed: false); if ((Object)(object)val != (Object)null) { _pluginIcon = TextureUtils.SpriteFromTexture2D(val); } } private static void OpenOfflineGearSkinSelect(int _) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack; SelectionPopupMenu selectionPopupMenu = new SelectionPopupMenu(); BackpackItem val = default(BackpackItem); foreach (InventorySlot gearSlot in GearSlots) { Logger.Debug($"[UIManager.OpenOfflineGearSkinSelect] Setting up skin select for slot {gearSlot}"); SelectionPopupHeader header = new SelectionPopupHeader(LocaleUtils.GetSlotGearSelectLocalizedText(gearSlot)) { SetActiveConfirmText = "<color=orange>" + Loc.T("gear.select.clickAgain") + "</color>", IsActiveText = "<color=green>" + Loc.T("gear.select.active") + "</color>" }; TargetContext ctx = localBackpack.GetContextForSlot(gearSlot); BackpackItem bkpkItem = (localBackpack.TryGetBackpackItem(gearSlot, ref val) ? val : null); SelectionPopupHeader selectionPopupHeader = header; UserConfig? instance = PersistentConfig<UserConfig>.Instance; selectionPopupHeader.ActiveItemID = ((instance != null && instance.CurrentSkinConfig.OfflineGear.TryGetValue(ctx.OfflineGearId.GetValueOrDefault(), out string value)) ? value : "10chambers.vanilla"); AddGroup(SkinGroup.Vanilla); foreach (SkinGroup allMatchingGroup in SkinManager.GetAllMatchingGroups(ctx)) { AddGroup(allMatchingGroup); } if (header.Items.Any((ISelectionPopupItem it) => it.ID == header.ActiveItemID)) { header.LastSelectedItemID = header.ActiveItemID; } selectionPopupMenu.AddHeader(header); void AddGroup(SkinGroup group) { SkinSelectionPopupItem obj = new SkinSelectionPopupItem { DisplayName = group.Name.Resolve(), ID = group.Guid, SubTitle = group.Author.Resolve(), Description = group.Description?.Resolve(), setActiveAction = OnOfflineGearSkinSelected, upperTextCustomization = AuthorTextDecoration, subtitleTextCustomization = DescriptionTextDecoration, Context = ctx }; BackpackItem obj2 = bkpkItem; object obj3; if (obj2 == null) { obj3 = null; } else { Item instance2 = obj2.Instance; obj3 = ((instance2 != null) ? ((Component)instance2).gameObject : null); } if (obj3 == null) { obj3 = null; } obj.ApplicationTarget = (GameObject?)obj3; BackpackItem obj4 = bkpkItem; obj.GearID = ((obj4 != null) ? obj4.GearIDRange : null); obj.SkinGUID = group.Guid; obj.IsVanilla = group.Guid == SkinGroup.Vanilla.Guid; SkinSelectionPopupItem item = obj; if ((Object)(object)_pluginIcon != (Object)null) { item.SpriteLarge = _pluginIcon; item.SpriteSmall = _pluginIcon; } if (GearIcons.Enabled) { BackpackItem obj5 = bkpkItem; if (((obj5 != null) ? obj5.GearIDRange : null) != null) { GearIcons.Request(bkpkItem.GearIDRange, group, delegate(Sprite sprite) { item.SetSprites(sprite, sprite); }); } } header.AddItem(item); } } selectionPopupMenu.Show(); } private static void OnOfflineGearSkinSelected(ISelectionPopupItem item) { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) if (!(item is SkinSelectionPopupItem skinSelectionPopupItem)) { Logger.Warn("[UIManager] OnSkinSelected called with non-skin item."); return; } TargetContext context = skinSelectionPopupItem.Context; if (!context.OfflineGearId.HasValue) { Logger.Warn("[UIManager] Selected skin for item with no offline gear id - context: " + context); return; } string text = (skinSelectionPopupItem.IsVanilla ? "10chambers.vanilla" : skinSelectionPopupItem.SkinGUID); if (PersistentConfig<UserConfig>.Instance != null) { if (PersistentConfig<UserConfig>.Instance.CurrentSkinConfig.OfflineGear.TryGetValue(context.OfflineGearId.Value, out string value) && value == text) { return; } PersistentConfig<UserConfig>.Instance.CurrentSkinConfig.OfflineGear[context.OfflineGearId.Value] = text; PersistentConfig<UserConfig>.Save(); } else { Logger.Warn("[UIManager] Cannot save skin selection because UserConfig.Instance is null."); } if ((Object)(object)skinSelectionPopupItem.ApplicationTarget != (Object)null) { ItemEquippable component = skinSelectionPopupItem.ApplicationTarget.GetComponent<ItemEquippable>(); if ((Object)(object)component != (Object)null) { WeaponShellCasingDataBlock shellCasingData = component.ShellCasingData; ShellTypes? val = ((shellCasingData != null) ? new ShellTypes?(shellCasingData.ShellCasingType) : ((ShellTypes?)null)); if (val.HasValue) { ShellSkinning.SetupPoolForGear(context.OfflineGearId.Value, val.Value); } } SkinManager.UpdateTargetsUnder(skinSelectionPopupItem.ApplicationTarget); } GearIconPatches.RegenerateIcons(skinSelectionPopupItem.GearID); } private static string AuthorTextDecoration(ISelectionPopupItem item, string text) { return text; } private static string DescriptionTextDecoration(ISelectionPopupItem item, string text) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return "<" + ColorExt.ToHtml(AccentColor) + ">" + text + "</color>"; } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "SetupFromPage")] [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPriority(700)] private static void AddLobbyBarSelectSkinEntryPoint(CM_PlayerLobbyBar __instance) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) RectTransform component = ((Component)__instance.m_weaponsHeaderText.transform).GetComponent<RectTransform>(); CM_LobbyScrollItem val = Object.Instantiate<CM_LobbyScrollItem>(__instance.m_clothesButton, ((Component)__instance.m_clothesButton).transform.parent, true); ((RectTransformComp)val).Setup(); ((Object)((Component)val).gameObject).name = "Skins Select Button"; ((CM_Item)val).SetOnBtnPressCallback(Action<int>.op_Implicit(OnOfflineGearShowSkinSelectPopup)); RectTransform val2 = ((Il2CppObjectBase)((Component)val).transform).TryCast<RectTransform>(); if ((Object)(object)val2 != (Object)null && (Object)(object)component != (Object)null) { Vector2 anchoredPosition = val2.anchoredPosition; anchoredPosition.y = component.anchoredPosition.y + 15f; val2.anchoredPosition = anchoredPosition; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; ((Transform)val2).Translate(new Vector3(32f, 0f, 0f)); if (PluginUtils.IsPluginLoaded("dev.aurirex.gtfo.legacylobby")) { ((Transform)val2).Translate(new Vector3(83f, 160f, 0f)); } GuiUtils.FixLobbyScrollItem(val, val2.sizeDelta.x * 0.4f); GuiUtils.SetItemColor((CM_Item)(object)val, AccentColor, Color.white); } Loc.TrySetExistingTMP((Component)(object)val, "ui.skinsButton"); GameStateCache.LobbyBar2LobbyScrollItem.Save((Component)(object)__instance, val); } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "PrepareForIntro")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Postfix__LobbyBar_PrepareForIntro(CM_PlayerLobbyBar __instance) { CM_LobbyScrollItem val = GameStateCache.LobbyBar2LobbyScrollItem.Get((Component)(object)__instance); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "SpawnPlayerModel")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Postfix__LobbyBar_SpawnPlayerModel(CM_PlayerLobbyBar __instance) { CM_LobbyScrollItem val = GameStateCache.LobbyBar2LobbyScrollItem.Get((Component)(object)__instance); if ((Object)(object)val != (Object)null && (Object)(object)__instance.m_player != (Object)null && __instance.m_player.IsLocal) { CoroutineManager.BlinkIn((CM_Item)(object)val, 1.2f, (Transform)null); } } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "ShowWeaponSelectionPopup")] [HarmonyWrapSafe] [HarmonyPostfix] private static void AddWeaponSelectSkinEntryPoint(CM_PlayerLobbyBar __instance) { } [HarmonyPatch(typeof(CM_PageSettings), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPriority(700)] private static void AddHotReloadButton(CM_PageSettings __instance) { Logger.Warn("Uhh... maybe TheArchive should find a better way to store offset, because I hate to have to take VeryHigh priority ;)"); } private static void OnPageMenuSettingReloadSkins(int _) { ReloadSkins(); } public static void ReloadSkins() { if ((Object)(object)Plugin.UnityBehaviourProcess == (Object)null) { Logger.Error("[UIManager] Cannot reload skins because UnityBehaviourProcess is null."); } else { ((MonoBehaviour)Plugin.UnityBehaviourProcess).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(SkinManager.Reload())); } } private static void OnPageMenuSettingOpenGlobalSkinsFolder(int _) { OpenGlobalSkinsFolder(); } public static void OpenGlobalSkinsFolder() { Process.Start(new ProcessStartInfo { FileName = "explorer.exe", Arguments = ModData.SkinsFolder, UseShellExecute = true }); } } public sealed class BoolHandle { private readonly Action<bool> _refresh; internal BoolHandle(Action<bool> refresh) { _refresh = refresh; } public void Refresh(bool value) { _refresh(value); } } public sealed class TextHandle { private readonly TextMeshPro _tmp; public TMP_Text TMP => (TMP_Text)(object)_tmp; internal TextHandle(TextMeshPro tmp) { _tmp = tmp; } public void SetVisible(bool visible) { if ((Object)(object)_tmp != (Object)null) { ((Component)_tmp).gameObject.SetActive(visible); } } public void SetText(string text) { TextMeshPro tmp = _tmp; if (tmp != null) { ((TMP_Text)tmp).SetText(text, true); } } } public sealed class EnumHandle<T> { private readonly Action<T> _refresh; internal EnumHandle(Action<T> refresh) { _refresh = refresh; } public void Refresh(T value) { _refresh(value); } } [HarmonyPatch] public class UISettings { private static class Layout { internal const float WindowX = 420f; internal const float WindowY = -200f; internal const float WindowWidth = 1020f; internal const float WindowHeight = 900f; internal const float ItemPadding = 5f; internal const float ControlW = 550f; internal const float ControlH = 50f; internal const float ControlOfsX = 250f; internal const float ControlOfsY = -25f; internal static readonly Vector3 WidgetAnchorPosition = new Vector3(-325f, 0f, 0f); } private static CM_PageSettings? _pageInstance; private static CM_ScrollWindow? _settingsWindow; private static CM_ScrollWindow? _popupWindow; private static GameObject? _settingsItemPrefab; private static Coroutine? _hideMessageCoroutine; public static TextHandle? ThMessageBox { get; private set; } public static LifecycleHook? SettingsWindowLifecycle { get; private set; } [HarmonyPatch(typeof(CM_PageSettings), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPriority(800)] private static void SetupSettingsPage(CM_PageSettings __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) _pageInstance = __instance; _settingsItemPrefab = __instance.m_settingsItemPrefab; _popupWindow = __instance.m_popupWindow; CM_Item val = __instance.CreateSingleButton(__instance.m_subMenuButtonPrefab, Loc.ID("settings.page.skins")); if ((Object)(object)val == (Object)null) { return; } GuiUtils.SetItemColor(val, UIManager.AccentColor, UIManager.AccentColor); CM_ScrollWindow val2 = ((Il2CppObjectBase)((GuiLayer)((CM_PageBase)__instance).m_guiLayer).AddRectComp(__instance.m_scrollwindowPrefab, (GuiAnchor)1, new Vector2(420f, -200f), (Transform)(object)((CM_PageBase)__instance).m_movingContentHolder)).TryCast<CM_ScrollWindow>(); if (!((Object)(object)val2 == (Object)null)) { val2.Setup(((Component)__instance).transform); ((RectTransformComp)val2).SetSize(new Vector2(1020f, 900f)); ((RectTransformComp)val2).SetVisible(false); if (((Il2CppArrayBase<CM_ScrollWindowHeader>)(object)val2.m_headers).Count > 0) { Loc.AttachToTMP((Component)(object)((Il2CppArrayBase<CM_ScrollWindowHeader>)(object)val2.m_headers)[0], "settings.page.skins"); } ((Component)val2).gameObject.AddComponent<LifecycleHook>(); __instance.m_allSettingsWindows.Add(val2); _settingsWindow = val2; PopulateSettings(__instance, val2); val.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)OnSkinsSettingsButtonPressed); } } private static void PopulateSettings(CM_PageSettings instance, CM_ScrollWindow window) { List<iScrollWindowContent> val = new List<iScrollWindowContent>(); AddHeader(instance, window, val, "settings.page.general.header"); AddBoolToggle(instance, window, val, "settings.mipmaps", "settings.mipmaps.desc", () => PersistentConfig<UserConfig>.Instance?.PluginConfig.EnableMipMaps ?? true, delegate(bool enableMipMaps) { if (PersistentConfig<UserConfig>.Instance != null) { OnSettingsMipMapChanged(); PersistentConfig<UserConfig>.Instance.PluginConfig.EnableMipMaps = enableMipMaps; PersistentConfig<UserConfig>.Save(); } }); AddHeader(instance, window, val, "settings.page.manage.header"); AddButton(instance, window, val, "settings.page.manage.reload.label", "settings.page.manage.reload.desc", "settings.page.manage.reload.button", OnSettingsSkinReload); AddButton(instance, window, val, "settings.page.manage.globalSkinsFolder.label", "settings.page.manage.globalSkinsFolder.desc", "settings.page.manage.globalSkinsFolder.button", OnSettingsOpenSkinsFolder); AddButton(instance, window, val, "settings.page.manage.updateAllMatTargets.label", "settings.page.manage.updateAllMatTargets.desc", "settings.page.manage.updateAllMatTargets.button", OnSettingsUpdateAllGroupTargets); AddButton(instance, window, val, "settings.page.manage.reloadSkinsSettings.label", "settings.page.manage.reloadSkinsSettings.desc", "settings.page.manage.reloadSkinsSettings.button", OnSettingsReloadSkinsSettings); AddHeader(instance, window, val, "settings.page.info.header"); AddTextDisplay(instance, window, val, "settings.page.info.version.label", "v0.12.0"); ThMessageBox = AddTextRegion(instance, window, val, "settings.page.info.credits.label"); window.SetContentItems(val, 5f); if ((Object)(object)SettingsWindowLifecycle != (Object)null) { SettingsWindowLifecycle.OnEnabled += OnSettingsPageEnabled; SettingsWindowLifecycle.OnDisabled += OnSettingsPageDisabled; } } private static void OnSettingsMipMapChanged() { if (ThMessageBox != null) { ShowInfoMessage("settings.page.info.reloadToTakeEffect"); } } private static void OnSettingsOpenSkinsFolder() { if (ThMessageBox != null) { ShowInfoMessage("settings.page.info.reloadToTakeEffect"); UIManager.OpenGlobalSkinsFolder(); } } private static void OnSettingsSkinReload() { if (ThMessageBox != null) { HideInfoMessage(); UIManager.ReloadSkins(); } } private static void OnSettingsUpdateAllGroupTargets() { SkinManager.UpdateAllGroups(); ShowInfoMessage("settings.page.info.allTargetsUpdated", 5f); } private static void OnSettingsReloadSkinsSettings() { PersistentConfig<UserConfig>.Load(); SkinManager.UpdateAllGroups(); ShowInfoMessage("settings.page.info.skinsSettingsReloaded", 5f); } private static void OnSettingsPageEnabled() { } private static void OnSettingsPageDisabled() { HideInfoMessage(); } private static void ShowInfoMessage(string textKey) { if (ThMessageBox != null) { ThMessageBox.SetVisible(visible: true); ThMessageBox.SetText(Loc.T(textKey)); ThMessageBox.TMP.alignment = (TextAlignmentOptions)514; if (_hideMessageCoroutine != null) { CoroutineManager.StopCoroutine(_hideMessageCoroutine); _hideMessageCoroutine = null; } } } private static void ShowInfoMessage(string textKey, float autoHideTimeout) { if (ThMessageBox != null) { ShowInfoMessage(textKey); _hideMessageCoroutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(AutoHideInfoMessage(autoHideTimeout)), (Action)null); } } private static IEnumerator AutoHideInfoMessage(float timeout) { yield return (object)new WaitForSeconds(timeout); HideInfoMessage(); _hideMessageCoroutine = null; } private static void HideInfoMessage() { if (ThMessageBox != null) { ThMessageBox.SetText(""); ThMessageBox.SetVisible(visible: false); } } private static CM_SettingsItem? CreateSettingsItem(CM_PageSettings instance, CM_ScrollWindow window, List<iScrollWindowContent> items, string labelKey, Color? titleColor = null) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_settingsItemPrefab == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(_settingsItemPrefab, ((Component)window).transform); CM_SettingsItem component = val.GetComponent<CM_SettingsItem>(); if ((Object)(object)component == (Object)null) { return null; } ((CM_Item)component).TextMeshRoot = ((Component)instance).transform; Transform obj = val.transform.Find("Title/TitleText"); TextMeshPro val2 = ((obj != null) ? ((Component)obj).GetComponent<TextMeshPro>() : null); if ((Object)(object)val2 != (Object)null) { if (titleColor.HasValue) { ((Graphic)val2).color = titleColor.Value; } Loc.AttachToTMP((Component)(object)val2, labelKey); } else { ((CM_Item)component).SetText(Loc.T(labelKey)); } ((RectTransformComp)component).ForcePopupLayer(true, (GameObject)null); iScrollWindowContent val3 = ((Il2CppObjectBase)component).TryCast<iScrollWindowContent>(); if (val3 != null) { items.Add(val3); } else { Logger.Warn("[UISettings] CM_SettingsItem → iScrollWindowContent cast failed for '" + labelKey + "'"); } return component; } private static (CM_Item button, TextMeshPro? label) SetupControlButton(CM_SettingsItem item, GameObject widgetPrefab) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(widgetPrefab, item.m_inputAlign, false); CM_Item val = obj.AddComponent<CM_Item>(); ((RectTransformComp)val).RectTrans.anchoredPosition3D = Layout.WidgetAnchorPosition; BoxCollider2D component = obj.GetComponent<BoxCollider2D>(); if ((Object)(object)component != (Object)null) { component.size = new Vector2(550f, 50f); ((Collider2D)component).offset = new Vector2(250f, -25f); } TextMeshPro componentInChildren = obj.GetComponentInChildren<TextMeshPro>(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).fontStyle = (FontStyles)(((TMP_Text)componentInChildren).fontStyle | 0x10); ((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)4097; } return (button: val, label: componentInChildren); } private static CM_Item? SetupEnumButton(CM_SettingsItem item, out GameObject popupItemPrefab, out Transform? popupAnchor) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(item.m_enumDropdownInputPrefab, item.m_inputAlign); CM_SettingsEnumDropdownButton component = obj.GetComponent<CM_SettingsEnumDropdownButton>(); CM_Item val = obj.AddComponent<CM_Item>(); ((RectTransformComp)val).Setup(); popupItemPrefab = component.m_popupItemPrefab; popupAnchor = component.m_popupWindowAlign; BoxCollider2D component2 = obj.GetComponent<BoxCollider2D>(); if ((Object)(object)component2 != (Object)null) { component2.size = new Vector2(550f, 50f); ((Collider2D)component2).offset = new Vector2(250f, -25f); } ((Behaviour)component).enabled = false; if ((Object)(object)_popupWindow != (Object)null) { component.m_popupWindow = _popupWindow; } Object.Destroy((Object)(object)component); return val; } private static void SetTooltip(CM_Item item, string headerKey, string? bodyKey = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown item.TooltipInfo = new TooltipInfo { PositionType = (TooltipPositionType)0, TooltipHeader = Loc.T(headerKey), TooltipText = ((bodyKey == null) ? "" : Loc.T(bodyKey)), UseTooptip = true }; TooltipInfoLocalizer tooltipInfoLocalizer = ((Component)item).gameObject.AddComponent<TooltipInfoLocalizer>(); if ((Object)(object)tooltipInfoLocalizer != (Object)null) { tooltipInfoLocalizer.Setup(headerKey, bodyKey); } } private static void AddHeader(CM_PageSettings instance, CM_ScrollWindow window, List<iScrollWindowContent> items, string labelKey, Color? color = null, float heightMultiplier = 1.5f, float? fontSize = null) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) CM_SettingsItem val = CreateSettingsItem(instance, window, items, labelKey, color); if (!((Object)(object)val == (Object)null)) { RectTransform val2 = ((Component)val).gameObject.GetComponent<RectTransform>() ?? ((Il2CppObjectBase)((Component)val).transform).TryCast<RectTransform>(); if ((Object)(object)val2 != (Object)null) { val2.sizeDelta = new Vector2(val2.sizeDelta.x, val2.sizeDelta.y * heightMultiplier); } ((Renderer)val.m_background).enabled = false; Transform obj = ((Component)val).transform.Find("Title/TitleText"); TextMeshPro val3 = ((obj != null) ? ((Component)obj).GetComponent<TextMeshPro>() : null); if ((Object)(object)val3 != (Object)null) { RectTransform rectTransform = ((TMP_Text)val3).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = new Vector2(1f, 0.6f); rectTransform.offsetMin = new Vector2(10f, 0f); rectTransform.offsetMax = new Vector2(0f, 0f); ((TMP_Text)val3).alignment = (TextAlignmentOptions)1025; ((TMP_Text)val3).fontSizeMax = fontSize ?? (((TMP_Text)val3).fontSizeMax * heightMultiplier); } BoxCollider2D component = ((Component)val).gameObject.GetComponent<BoxCollider2D>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } } } private static BoolHandle? AddBoolToggle(CM_PageSettings instance, CM_ScrollWindow window, List<iScrollWindowContent> items, string labelKey, string? descriptionKey, Func<bool> getter, Action<bool> setter) { CM_SettingsItem val = CreateSettingsItem(instance, window, items, labelKey); if ((Object)(object)val == (Object)null) { return null; } CM_SettingsToggleButton componentInChildren = ((Component)val).GetComponentInChildren<CM_SettingsToggleButton>(); if ((Object)(object)componentInChildren != (Object)null) { ObjectExt.Destroy((Object)(object)componentInChildren); } (CM_Item, TextMeshPro) tuple = SetupControlButton(val, val.m_toggleInputPrefab); CM_Item item = tuple.Item1; TextMeshPro label = tuple.Item2; Collider2D componentInChildren2 = ((Component)item).GetComponentInChildren<Collider2D>(); if ((Object)(object)componentInChildren2 != (Object)null) { ((Behaviour)componentInChildren2).enabled = false; } Refresh(getter()); if (descriptionKey != null) { SetTooltip((CM_Item)(object)val, labelKey, descriptionKey); } ((CM_Item)(object)val).SetEvents(delegate { bool flag = !getter(); setter(flag); Refresh(flag); }); return new BoolHandle(Refresh); void Refresh(bool flag) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)label == (Object)null)) { ((TMP_Text)label).SetText(Loc.T(flag ? "ui.on" : "ui.off"), true); ((Graphic)label).color = (flag ? Color.green : Color.red); } } } private static void AddButton(CM_PageSettings instance, CM_ScrollWindow window, List<iScrollWindowContent> items, string labelKey, string? descriptionKey, string buttonTextKey, Action onClick) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) CM_SettingsItem val = CreateSettingsItem(instance, window, items, labelKey); if (!((Object)(object)val == (Object)null)) { (CM_Item button, TextMeshPro? label) tuple = SetupControlButton(val, val.m_toggleInputPrefab); CM_Item item = tuple.button; TextMeshPro item2 = tuple.label; Collider2D componentInChildren = ((Component)item).GetComponentInChildren<Collider2D>(); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } if ((Object)(object)item2 != (Object)null) { ((TMP_Text)item2).SetText(Loc.T(buttonTextKey), true); Loc.AttachToTMP((Component)(object)item2, buttonTextKey); ((TMP_Text)item2).fontStyle = (FontStyles)(((TMP_Text)item2).fontStyle | 4); ((Graphic)item2).color = UIManager.AccentColor; } if (descriptionKey != null) { SetTooltip((CM_Item)(object)val, labelKey, descriptionKey); } ((CM_Item)(object)val).SetEvents(delegate { onClick(); }); } } private static TextHandle? AddTextDisplay(CM_PageSettings instance, CM_ScrollWindow window, List<iScrollWindowContent> items, string labelKey, string initialText = "") { //IL_006e: Unknown result type (might be due to invalid IL or missing references) CM_SettingsItem val = CreateSettingsItem(instance, window, items, labelKey); if ((Object)(object)val == (Object)null) { return null; } GameObject obj = Object.Instantiate<GameObject>(val.m_toggleInputPrefab, val.m_inputAlign); CM_Item component = obj.GetComponent<CM_Item>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } BoxCollider2D component2 = obj.GetComponent<BoxCollider2D>(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } RectTransform component3 = obj.GetComponent<RectTransform>(); if ((Object)(object)component3 != (Object)null) { component3.anchoredPosition3D = Layout.WidgetAnchorPosition; } TextMeshPro componentInChildren = obj.GetComponentInChildren<TextMeshPro>(); if (componentInChildren != null) { ((TMP_Text)componentInChildren).SetText(initialText, true); } if (!((Object)(object)componentInChildren != (Object)null)) { return null; } return new TextHandle(componentInChildren); } private static TextHandle? AddTextRegion(CM_PageSettings instance, CM_ScrollWindow window, List<iScrollWindowContent> items, string labelKey, Color? color = null, float heightMultiplier = 2f, float? fontSize = null) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) CM_SettingsItem val = CreateSettingsItem(instance, window, items, labelKey, color); if ((Object)(object)val == (Object)null) { return null; } RectTransform val2 = ((Component)val).gameObject.GetComponent<RectTransform>() ?? ((Il2CppObjectBase)((Component)val).transform).TryCast<RectTransform>(); if ((Object)(object)val2 != (Object)null) { val2.sizeDelta = new Vector2(val2.sizeDelta.x, val2.sizeDelta.y * heightMultiplier); } ((Renderer)val.m_background).enabled = false; Transform obj = ((Component)val).transform.Find("Title/TitleText"); TextMeshPro val3 = ((obj != null) ? ((Component)obj).GetComponent<TextMeshPro>() : null); if ((Object)(object)val3 != (Object)null) { RectTransform rectTransform = ((TMP_Text)val3).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = new Vector2(1f, 1f); rectTransform.offsetMin = new Vector2(10f, 0f); rectTransform.offsetMax = new Vector2(0f, 0f); ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; } BoxCollider2D component = ((Component)val).gameObject.GetComponent<BoxCollider2D>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } if (!((Object)(object)val3 != (Object)null)) { return null; } return new TextHandle(val3); } private static EnumHandle<T>? AddEnumDropdown<T>(CM_PageSettings instance, CM_ScrollWindow window, List<iScrollWindowContent> items, string labelKey, string? descriptionKey, Func<T> getter, Action<T> setter, IReadOnlyList<(string label, T value)> options) where T : notnull { CM_SettingsItem val = CreateSettingsItem(instance, window, items, labelKey); if ((Object)(object)val == (Object)null) { return null; } GameObject popupItemPrefab; Transform popupAnchor; CM_Item button = SetupEnumButton(val, out popupItemPrefab, out popupAnchor); if ((Object)(object)button == (Object)null) { return null; } Refresh(getter()); if (descriptionKey != null) { SetTooltip((CM_Item)(object)val, labelKey, descriptionKey); } ((CM_Item)(object)val).SetEvents(delegate { ShowEnumPopup(getter, setter, options, button, popupItemPrefab, popupAnchor, Refresh); }); return new EnumHandle<T>(Refresh); void Refresh(T y) { string text = y.ToString() ?? ""; foreach (var option in options) { if (EqualityComparer<T>.Default.Equals(option.value, y)) { (text, _) = option; break; } } button.SetText(text); } } private static void ShowEnumPopup<T>(Func<T> getter, Action<T> setter, IReadOnlyList<(string label, T value)> options, CM_Item button, GameObject popupItemPrefab, Transform? popupAnchor, Action<T> refreshButton) where T : notnull { //IL_00c6: Unknown result type (might be d
StbDxtSharp.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("StbDxtSharpTeam")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("C# port of the stb_dxt.h")] [assembly: AssemblyFileVersion("1.10.3.0")] [assembly: AssemblyInformationalVersion("1.10.3")] [assembly: AssemblyProduct("StbDxtSharp")] [assembly: AssemblyTitle("StbDxtSharp")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.10.3.0")] [module: UnverifiableCode] namespace StbDxtSharp; internal static class CRuntime { public unsafe static void memcpy(void* a, void* b, long size) { byte* ptr = (byte*)a; byte* ptr2 = (byte*)b; for (long num = 0L; num < size; num++) { *(ptr++) = *(ptr2++); } } public unsafe static void memcpy(void* a, void* b, ulong size) { memcpy(a, b, (long)size); } public unsafe static void memset(void* ptr, int value, long size) { byte* ptr2 = (byte*)ptr; byte b = (byte)value; for (long num = 0L; num < size; num++) { *(ptr2++) = b; } } public unsafe static void memset(void* ptr, int value, ulong size) { memset(ptr, value, (long)size); } public static int abs(int v) { return Math.Abs(v); } public static float fabs(double a) { return (float)Math.Abs(a); } } [Flags] public enum CompressionMode { None = 0, Dithered = 1, HighQuality = 2 } public static class StbDxt { public static byte[] stb__Expand5 = new byte[32]; public static byte[] stb__Expand6 = new byte[64]; public static byte[] stb__OMatch5 = new byte[512]; public static byte[] stb__OMatch6 = new byte[512]; public static byte[] stb__QuantRBTab = new byte[272]; public static byte[] stb__QuantGTab = new byte[272]; public static int nIterPower = 4; public static float[] midpoints5 = new float[32] { 0.015686f, 0.047059f, 0.078431f, 0.111765f, 0.145098f, 0.176471f, 0.207843f, 0.241176f, 0.27451f, 0.305882f, 0.337255f, 0.370588f, 0.403922f, 0.435294f, 0.466667f, 0.5f, 0.533333f, 0.564706f, 0.596078f, 0.629412f, 0.662745f, 0.694118f, 0.72549f, 0.758824f, 0.792157f, 0.823529f, 0.854902f, 0.888235f, 0.921569f, 0.952941f, 0.984314f, 1f }; public static float[] midpoints6 = new float[64] { 0.007843f, 0.023529f, 0.039216f, 0.054902f, 0.070588f, 0.086275f, 0.101961f, 0.117647f, 0.133333f, 0.14902f, 0.164706f, 0.180392f, 0.196078f, 0.211765f, 0.227451f, 0.245098f, 0.262745f, 0.278431f, 0.294118f, 0.309804f, 0.32549f, 0.341176f, 0.356863f, 0.372549f, 0.388235f, 0.403922f, 0.419608f, 0.435294f, 0.45098f, 0.466667f, 0.482353f, 0.5f, 0.517647f, 0.533333f, 0.54902f, 0.564706f, 0.580392f, 0.596078f, 0.611765f, 32f / 51f, 0.643137f, 0.658824f, 0.67451f, 0.690196f, 0.705882f, 0.721569f, 0.737255f, 0.754902f, 0.772549f, 0.788235f, 0.803922f, 0.819608f, 0.835294f, 0.85098f, 0.866667f, 0.882353f, 0.898039f, 0.913725f, 0.929412f, MathF.E * 105f / 302f, 0.960784f, 0.976471f, 0.992157f, 1f }; public static int[] w1Tab = new int[4] { 3, 0, 2, 1 }; public static int[] prods = new int[4] { 589824, 2304, 262402, 66562 }; public static int init = 1; public unsafe static void stb__DitherBlock(byte* dest, byte* block) { int* ptr = stackalloc int[8]; int* ptr2 = ptr; int* ptr3 = ptr + 4; for (int i = 0; i < 3; i++) { byte* ptr4 = block + i; byte* ptr5 = dest + i; fixed (byte* ptr6 = ((i == 1) ? stb__QuantGTab : stb__QuantRBTab)) { CRuntime.memset(ptr, 0, 32uL); for (int j = 0; j < 4; j++) { *ptr5 = ptr6[*ptr4 + (3 * ptr3[1] + 5 * *ptr3 >> 4)]; *ptr2 = *ptr4 - *ptr5; ptr5[4] = ptr6[ptr4[4] + (7 * *ptr2 + 3 * ptr3[2] + 5 * ptr3[1] + *ptr3 >> 4)]; ptr2[1] = ptr4[4] - ptr5[4]; ptr5[8] = ptr6[ptr4[8] + (7 * ptr2[1] + 3 * ptr3[3] + 5 * ptr3[2] + ptr3[1] >> 4)]; ptr2[2] = ptr4[8] - ptr5[8]; ptr5[12] = ptr6[ptr4[12] + (7 * ptr2[2] + 5 * ptr3[3] + ptr3[2] >> 4)]; ptr2[3] = ptr4[12] - ptr5[12]; ptr4 += 16; ptr5 += 16; int* intPtr = ptr2; ptr2 = ptr3; ptr3 = intPtr; } } } } public unsafe static byte[] CompressDxt(int width, int height, byte[] data, bool hasAlpha, CompressionMode mode) { if (data.Length != width * height * 4) { throw new Exception("This method supports only rgba images"); } int num = (hasAlpha ? 16 : 8); byte[] array = new byte[width * height * num / 16]; byte* ptr = stackalloc byte[64]; fixed (byte* ptr2 = data) { fixed (byte* ptr3 = array) { byte* ptr4 = ptr3; for (int i = 0; i < height; i += 4) { for (int j = 0; j < width; j += 4) { for (int k = 0; k < 4 && i + k < height; k++) { CRuntime.memcpy(ptr + k * 16, ptr2 + width * 4 * (i + k) + j * 4, 16L); } stb_compress_dxt_block(ptr4, ptr, hasAlpha ? 1 : 0, (int)mode); ptr4 += (hasAlpha ? 16 : 8); } } } } return array; } public static byte[] CompressDxt1(int width, int height, byte[] data, CompressionMode mode = CompressionMode.None) { return CompressDxt(width, height, data, hasAlpha: false, mode); } public static byte[] CompressDxt5(int width, int height, byte[] data, CompressionMode mode = CompressionMode.None) { return CompressDxt(width, height, data, hasAlpha: true, mode); } public static int stb__Mul8Bit(int a, int b) { int num = a * b + 128; return num + (num >> 8) >> 8; } public unsafe static void stb__From16Bit(byte* _out_, ushort v) { int num = (v & 0xF800) >> 11; int num2 = (v & 0x7E0) >> 5; int num3 = v & 0x1F; *_out_ = stb__Expand5[num]; _out_[1] = stb__Expand6[num2]; _out_[2] = stb__Expand5[num3]; _out_[3] = 0; } public static ushort stb__As16Bit(int r, int g, int b) { return (ushort)((stb__Mul8Bit(r, 31) << 11) + (stb__Mul8Bit(g, 63) << 5) + stb__Mul8Bit(b, 31)); } public static int stb__Lerp13(int a, int b) { return (2 * a + b) / 3; } public unsafe static void stb__Lerp13RGB(byte* _out_, byte* p1, byte* p2) { *_out_ = (byte)stb__Lerp13(*p1, *p2); _out_[1] = (byte)stb__Lerp13(p1[1], p2[1]); _out_[2] = (byte)stb__Lerp13(p1[2], p2[2]); } public static void stb__PrepareOptTable(byte[] Table, byte[] expand, int size) { int num = 0; int num2 = 0; int num3 = 0; for (num = 0; num < 256; num++) { int num4 = 256; for (num2 = 0; num2 < size; num2++) { for (num3 = 0; num3 < size; num3++) { int num5 = expand[num2]; int num6 = expand[num3]; int num7 = CRuntime.abs(stb__Lerp13(num6, num5) - num); num7 += CRuntime.abs(num6 - num5) * 3 / 100; if (num7 < num4) { Table[num * 2] = (byte)num3; Table[num * 2 + 1] = (byte)num2; num4 = num7; } } } } } public unsafe static void stb__EvalColors(byte* color, ushort c0, ushort c1) { stb__From16Bit(color, c0); stb__From16Bit(color + 4, c1); stb__Lerp13RGB(color + 8, color, color + 4); stb__Lerp13RGB(color + 12, color + 4, color); } public unsafe static uint stb__MatchColorsBlock(byte* block, byte* color, int dither) { uint num = 0u; int num2 = *color - color[4]; int num3 = color[1] - color[5]; int num4 = color[2] - color[6]; int* ptr = stackalloc int[16]; int* ptr2 = stackalloc int[4]; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; for (num5 = 0; num5 < 16; num5++) { ptr[num5] = block[num5 * 4] * num2 + block[num5 * 4 + 1] * num3 + block[num5 * 4 + 2] * num4; } for (num5 = 0; num5 < 4; num5++) { ptr2[num5] = color[num5 * 4] * num2 + color[num5 * 4 + 1] * num3 + color[num5 * 4 + 2] * num4; } num6 = ptr2[1] + ptr2[3]; num7 = ptr2[3] + ptr2[2]; num8 = ptr2[2] + *ptr2; if (dither == 0) { for (num5 = 15; num5 >= 0; num5--) { int num9 = ptr[num5] * 2; num <<= 2; num = ((num9 >= num7) ? (num | (uint)((num9 < num8) ? 2 : 0)) : (num | (uint)((num9 < num6) ? 1 : 3))); } } else { int* ptr3 = stackalloc int[8]; int* ptr4 = ptr3; int* ptr5 = ptr3 + 4; int* ptr6 = ptr; int num10 = 0; num6 <<= 3; num7 <<= 3; num8 <<= 3; for (num5 = 0; num5 < 8; num5++) { ptr3[num5] = 0; } for (num10 = 0; num10 < 4; num10++) { int num11 = 0; int num12 = 0; int num13 = 0; num11 = (*ptr6 << 4) + 3 * ptr5[1] + 5 * *ptr5; num13 = ((num11 >= num7) ? ((num11 < num8) ? 2 : 0) : ((num11 < num6) ? 1 : 3)); *ptr4 = *ptr6 - ptr2[num13]; num12 = num13; num11 = (ptr6[1] << 4) + 7 * *ptr4 + 3 * ptr5[2] + 5 * ptr5[1] + *ptr5; num13 = ((num11 >= num7) ? ((num11 < num8) ? 2 : 0) : ((num11 < num6) ? 1 : 3)); ptr4[1] = ptr6[1] - ptr2[num13]; num12 |= num13 << 2; num11 = (ptr6[2] << 4) + 7 * ptr4[1] + 3 * ptr5[3] + 5 * ptr5[2] + ptr5[1]; num13 = ((num11 >= num7) ? ((num11 < num8) ? 2 : 0) : ((num11 < num6) ? 1 : 3)); ptr4[2] = ptr6[2] - ptr2[num13]; num12 |= num13 << 4; num11 = (ptr6[3] << 4) + 7 * ptr4[2] + 5 * ptr5[3] + ptr5[2]; num13 = ((num11 >= num7) ? ((num11 < num8) ? 2 : 0) : ((num11 < num6) ? 1 : 3)); ptr4[3] = ptr6[3] - ptr2[num13]; num12 |= num13 << 6; ptr6 += 4; num |= (uint)(num12 << num10 * 8); int* intPtr = ptr4; ptr4 = ptr5; ptr5 = intPtr; } } return num; } public unsafe static void stb__OptimizeColorsBlock(byte* block, ushort* pmax16, ushort* pmin16) { int num = int.MaxValue; int num2 = -2147483647; byte* ptr = null; byte* ptr2 = null; double num3 = 0.0; int num4 = 0; int num5 = 0; int num6 = 0; float* ptr3 = stackalloc float[6]; float num7 = 0f; float num8 = 0f; float num9 = 0f; int* ptr4 = stackalloc int[6]; int* ptr5 = stackalloc int[3]; int* ptr6 = stackalloc int[3]; int* ptr7 = stackalloc int[3]; int num10 = 0; int num11 = 0; int num12 = 0; for (num10 = 0; num10 < 3; num10++) { byte* ptr8 = block + num10; int num13 = 0; int num14 = 0; int num15 = 0; num13 = (num14 = (num15 = *ptr8)); for (num11 = 4; num11 < 64; num11 += 4) { num13 += ptr8[num11]; if (ptr8[num11] < num14) { num14 = ptr8[num11]; } else if (ptr8[num11] > num15) { num15 = ptr8[num11]; } } ptr5[num10] = num13 + 8 >> 4; ptr6[num10] = num14; ptr7[num10] = num15; } for (num11 = 0; num11 < 6; num11++) { ptr4[num11] = 0; } for (num11 = 0; num11 < 16; num11++) { int num16 = block[num11 * 4] - *ptr5; int num17 = block[num11 * 4 + 1] - ptr5[1]; int num18 = block[num11 * 4 + 2] - ptr5[2]; *ptr4 += num16 * num16; ptr4[1] += num16 * num17; ptr4[2] += num16 * num18; ptr4[3] += num17 * num17; ptr4[4] += num17 * num18; ptr4[5] += num18 * num18; } for (num11 = 0; num11 < 6; num11++) { ptr3[num11] = (float)ptr4[num11] / 255f; } num7 = *ptr7 - *ptr6; num8 = ptr7[1] - ptr6[1]; num9 = ptr7[2] - ptr6[2]; for (num12 = 0; num12 < nIterPower; num12++) { float num19 = num7 * *ptr3 + num8 * ptr3[1] + num9 * ptr3[2]; float num20 = num7 * ptr3[1] + num8 * ptr3[3] + num9 * ptr3[4]; float num21 = num7 * ptr3[2] + num8 * ptr3[4] + num9 * ptr3[5]; num7 = num19; num8 = num20; num9 = num21; } num3 = CRuntime.fabs(num7); if ((double)CRuntime.fabs(num8) > num3) { num3 = CRuntime.fabs(num8); } if ((double)CRuntime.fabs(num9) > num3) { num3 = CRuntime.fabs(num9); } if (num3 < 4.0) { num4 = 299; num5 = 587; num6 = 114; } else { num3 = 512.0 / num3; num4 = (int)((double)num7 * num3); num5 = (int)((double)num8 * num3); num6 = (int)((double)num9 * num3); } for (num11 = 0; num11 < 16; num11++) { int num22 = block[num11 * 4] * num4 + block[num11 * 4 + 1] * num5 + block[num11 * 4 + 2] * num6; if (num22 < num) { num = num22; ptr = block + num11 * 4; } if (num22 > num2) { num2 = num22; ptr2 = block + num11 * 4; } } *pmax16 = stb__As16Bit(*ptr2, ptr2[1], ptr2[2]); *pmin16 = stb__As16Bit(*ptr, ptr[1], ptr[2]); } public static ushort stb__Quantize5(float x) { ushort num = 0; x = ((x < 0f) ? 0f : ((x > 1f) ? 1f : x)); num = (ushort)(x * 31f); return (ushort)(num + (ushort)((x > midpoints5[num]) ? 1 : 0)); } public static ushort stb__Quantize6(float x) { ushort num = 0; x = ((x < 0f) ? 0f : ((x > 1f) ? 1f : x)); num = (ushort)(x * 63f); return (ushort)(num + (ushort)((x > midpoints6[num]) ? 1 : 0)); } public unsafe static int stb__RefineBlock(byte* block, ushort* pmax16, ushort* pmin16, uint mask) { float num = 0f; ushort num2 = 0; ushort num3 = 0; ushort num4 = 0; ushort num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int num10 = 0; int num11 = 0; int num12 = 0; int num13 = 0; int num14 = 0; int num15 = 0; int num16 = 0; uint num17 = mask; num2 = *pmin16; num3 = *pmax16; if ((mask ^ (mask << 2)) < 4) { int num18 = 8; int num19 = 8; int num20 = 8; for (num6 = 0; num6 < 16; num6++) { num18 += block[num6 * 4]; num19 += block[num6 * 4 + 1]; num20 += block[num6 * 4 + 2]; } num18 >>= 4; num19 >>= 4; num20 >>= 4; num5 = (ushort)((stb__OMatch5[num18 * 2] << 11) | (stb__OMatch6[num19 * 2] << 5) | stb__OMatch5[num20 * 2]); num4 = (ushort)((stb__OMatch5[num18 * 2 + 1] << 11) | (stb__OMatch6[num19 * 2 + 1] << 5) | stb__OMatch5[num20 * 2 + 1]); } else { num11 = (num12 = (num13 = 0)); num14 = (num15 = (num16 = 0)); num6 = 0; while (num6 < 16) { int num21 = (int)(num17 & 3); int num22 = w1Tab[num21]; int num23 = block[num6 * 4]; int num24 = block[num6 * 4 + 1]; int num25 = block[num6 * 4 + 2]; num7 += prods[num21]; num11 += num22 * num23; num12 += num22 * num24; num13 += num22 * num25; num14 += num23; num15 += num24; num16 += num25; num6++; num17 >>= 2; } num14 = 3 * num14 - num11; num15 = 3 * num15 - num12; num16 = 3 * num16 - num13; num8 = num7 >> 16; num10 = (num7 >> 8) & 0xFF; num9 = num7 & 0xFF; num = 1f / 85f / (float)(num8 * num10 - num9 * num9); num5 = (ushort)(stb__Quantize5((float)(num11 * num10 - num14 * num9) * num) << 11); num5 |= (ushort)(stb__Quantize6((float)(num12 * num10 - num15 * num9) * num) << 5); num5 |= stb__Quantize5((float)(num13 * num10 - num16 * num9) * num); num4 = (ushort)(stb__Quantize5((float)(num14 * num8 - num11 * num9) * num) << 11); num4 |= (ushort)(stb__Quantize6((float)(num15 * num8 - num12 * num9) * num) << 5); num4 |= stb__Quantize5((float)(num16 * num8 - num13 * num9) * num); } *pmin16 = num4; *pmax16 = num5; if (num2 == num4 && num3 == num5) { return 0; } return 1; } public unsafe static void stb__CompressColorBlock(byte* dest, byte* block, int mode) { uint num = 0u; int num2 = 0; int num3 = 0; int num4 = 0; ushort num5 = 0; ushort num6 = 0; byte* ptr = stackalloc byte[64]; byte* color = stackalloc byte[16]; num3 = mode & 1; num4 = (((mode & 2) == 0) ? 1 : 2); for (num2 = 1; num2 < 16 && ((uint*)block)[num2] == *(uint*)block; num2++) { } if (num2 == 16) { int num7 = *block; int num8 = block[1]; int num9 = block[2]; num = 2863311530u; num5 = (ushort)((stb__OMatch5[num7 * 2] << 11) | (stb__OMatch6[num8 * 2] << 5) | stb__OMatch5[num9 * 2]); num6 = (ushort)((stb__OMatch5[num7 * 2 + 1] << 11) | (stb__OMatch6[num8 * 2 + 1] << 5) | stb__OMatch5[num9 * 2 + 1]); } else { if (num3 != 0) { stb__DitherBlock(ptr, block); } stb__OptimizeColorsBlock((num3 != 0) ? ptr : block, &num5, &num6); if (num5 != num6) { stb__EvalColors(color, num5, num6); num = stb__MatchColorsBlock(block, color, num3); } else { num = 0u; } for (num2 = 0; num2 < num4; num2++) { uint num10 = num; if (stb__RefineBlock((num3 != 0) ? ptr : block, &num5, &num6, num) != 0) { if (num5 == num6) { num = 0u; break; } stb__EvalColors(color, num5, num6); num = stb__MatchColorsBlock(block, color, num3); } if (num == num10) { break; } } } if (num5 < num6) { ushort num11 = num6; num6 = num5; num5 = num11; num ^= 0x55555555; } *dest = (byte)num5; dest[1] = (byte)(num5 >> 8); dest[2] = (byte)num6; dest[3] = (byte)(num6 >> 8); dest[4] = (byte)num; dest[5] = (byte)(num >> 8); dest[6] = (byte)(num >> 16); dest[7] = (byte)(num >> 24); } public unsafe static void stb__CompressAlphaBlock(byte* dest, byte* src, int stride) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; num8 = (num9 = *src); for (num = 1; num < 16; num++) { if (src[num * stride] < num8) { num8 = src[num * stride]; } else if (src[num * stride] > num9) { num9 = src[num * stride]; } } *dest = (byte)num9; dest[1] = (byte)num8; dest += 2; num2 = num9 - num8; num4 = num2 * 4; num5 = num2 * 2; num3 = ((num2 < 8) ? (num2 - 1) : (num2 / 2 + 2)); num3 -= num8 * 7; num6 = 0; num7 = 0; for (num = 0; num < 16; num++) { int num10 = src[num * stride] * 7 + num3; int num11 = 0; int num12 = 0; num12 = ((num10 >= num4) ? (-1) : 0); num11 = num12 & 4; num10 -= num4 & num12; num12 = ((num10 >= num5) ? (-1) : 0); num11 += num12 & 2; num10 -= num5 & num12; num11 += ((num10 >= num2) ? 1 : 0); num11 = -num11 & 7; num11 ^= ((2 > num11) ? 1 : 0); num7 |= num11 << num6; if ((num6 += 3) >= 8) { *(dest++) = (byte)num7; num7 >>= 8; num6 -= 8; } } } public static void stb__InitDXT() { int num = 0; for (num = 0; num < 32; num++) { stb__Expand5[num] = (byte)((num << 3) | (num >> 2)); } for (num = 0; num < 64; num++) { stb__Expand6[num] = (byte)((num << 2) | (num >> 4)); } for (num = 0; num < 272; num++) { int a = ((num - 8 >= 0) ? ((num - 8 > 255) ? 255 : (num - 8)) : 0); stb__QuantRBTab[num] = stb__Expand5[stb__Mul8Bit(a, 31)]; stb__QuantGTab[num] = stb__Expand6[stb__Mul8Bit(a, 63)]; } stb__PrepareOptTable(stb__OMatch5, stb__Expand5, 32); stb__PrepareOptTable(stb__OMatch6, stb__Expand6, 64); } public unsafe static void stb_compress_dxt_block(byte* dest, byte* src, int alpha, int mode) { byte* ptr = stackalloc byte[64]; if (init != 0) { stb__InitDXT(); init = 0; } if (alpha != 0) { int num = 0; stb__CompressAlphaBlock(dest, src + 3, 4); dest += 8; CRuntime.memcpy(ptr, src, 64uL); for (num = 0; num < 16; num++) { ptr[num * 4 + 3] = byte.MaxValue; } src = ptr; } stb__CompressColorBlock(dest, src, mode); } public unsafe static void stb_compress_bc4_block(byte* dest, byte* src) { stb__CompressAlphaBlock(dest, src, 1); } public unsafe static void stb_compress_bc5_block(byte* dest, byte* src) { stb__CompressAlphaBlock(dest, src, 2); stb__CompressAlphaBlock(dest + 8, src + 1, 2); } }
StbImageSharp.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using StbImageSharp.Hebron.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("StbImageSharpTeam")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("C# port of the stb_image.h")] [assembly: AssemblyFileVersion("2.30.16.0")] [assembly: AssemblyInformationalVersion("2.30.16+125af70cb557033f2c46aec8e82eaaf72ac49817")] [assembly: AssemblyProduct("StbImageSharp")] [assembly: AssemblyTitle("StbImageSharp")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.30.16.0")] [module: UnverifiableCode] namespace StbImageSharp { public class AnimatedFrameResult : ImageResult { public int DelayInMs { get; set; } } internal class AnimatedGifEnumerator : IEnumerator<AnimatedFrameResult>, IEnumerator, IDisposable { private readonly StbImage.stbi__context _context; private StbImage.stbi__gif _gif; private readonly ColorComponents _colorComponents; public ColorComponents ColorComponents => _colorComponents; public AnimatedFrameResult Current { get; private set; } object IEnumerator.Current => Current; public AnimatedGifEnumerator(Stream input, ColorComponents colorComponents) { if (input == null) { throw new ArgumentNullException("input"); } _context = new StbImage.stbi__context(input); if (StbImage.stbi__gif_test(_context) == 0) { throw new Exception("Input stream is not GIF file."); } _gif = new StbImage.stbi__gif(); _colorComponents = colorComponents; } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } public unsafe bool MoveNext() { int num = default(int); byte b = default(byte); byte* ptr = StbImage.stbi__gif_load_next(_context, _gif, &num, (int)ColorComponents, &b); if (ptr == null) { return false; } if (Current == null) { Current = new AnimatedFrameResult { Width = _gif.w, Height = _gif.h, SourceComp = (ColorComponents)num, Comp = ((ColorComponents == ColorComponents.Default) ? ((ColorComponents)num) : ColorComponents) }; Current.Data = new byte[Current.Width * Current.Height * (int)Current.Comp]; } Current.DelayInMs = _gif.delay; Marshal.Copy(new IntPtr(ptr), Current.Data, 0, Current.Data.Length); return true; } public void Reset() { throw new NotImplementedException(); } ~AnimatedGifEnumerator() { Dispose(disposing: false); } protected unsafe virtual void Dispose(bool disposing) { if (_gif != null) { if (_gif._out_ != null) { CRuntime.free(_gif._out_); _gif._out_ = null; } if (_gif.history != null) { CRuntime.free(_gif.history); _gif.history = null; } if (_gif.background != null) { CRuntime.free(_gif.background); _gif.background = null; } _gif = null; } } } internal class AnimatedGifEnumerable : IEnumerable<AnimatedFrameResult>, IEnumerable { private readonly Stream _input; private readonly ColorComponents _colorComponents; public ColorComponents ColorComponents => _colorComponents; public AnimatedGifEnumerable(Stream input, ColorComponents colorComponents) { _input = input; _colorComponents = colorComponents; } public IEnumerator<AnimatedFrameResult> GetEnumerator() { return new AnimatedGifEnumerator(_input, ColorComponents); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public enum ColorComponents { Default, Grey, GreyAlpha, RedGreenBlue, RedGreenBlueAlpha } public struct ImageInfo { public int Width; public int Height; public ColorComponents ColorComponents; public int BitsPerChannel; public unsafe static ImageInfo? FromStream(Stream stream) { StbImage.stbi__context s = new StbImage.stbi__context(stream); bool flag = StbImage.stbi__is_16_main(s) == 1; StbImage.stbi__rewind(s); int width = default(int); int height = default(int); int colorComponents = default(int); int num = StbImage.stbi__info_main(s, &width, &height, &colorComponents); StbImage.stbi__rewind(s); if (num == 0) { return null; } return new ImageInfo { Width = width, Height = height, ColorComponents = (ColorComponents)colorComponents, BitsPerChannel = (flag ? 16 : 8) }; } } public class ImageResult { public int Width { get; set; } public int Height { get; set; } public ColorComponents SourceComp { get; set; } public ColorComponents Comp { get; set; } public byte[] Data { get; set; } internal unsafe static ImageResult FromResult(byte* result, int width, int height, ColorComponents comp, ColorComponents req_comp) { if (result == null) { throw new InvalidOperationException(StbImage.stbi__g_failure_reason); } ImageResult imageResult = new ImageResult { Width = width, Height = height, SourceComp = comp, Comp = ((req_comp == ColorComponents.Default) ? comp : req_comp) }; imageResult.Data = new byte[width * height * (int)imageResult.Comp]; Marshal.Copy(new IntPtr(result), imageResult.Data, 0, imageResult.Data.Length); return imageResult; } public unsafe static ImageResult FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default) { byte* ptr = null; try { int width = default(int); int height = default(int); int comp = default(int); ptr = StbImage.stbi__load_and_postprocess_8bit(new StbImage.stbi__context(stream), &width, &height, &comp, (int)requiredComponents); return FromResult(ptr, width, height, (ColorComponents)comp, requiredComponents); } finally { if (ptr != null) { CRuntime.free(ptr); } } } public static ImageResult FromMemory(byte[] data, ColorComponents requiredComponents = ColorComponents.Default) { using MemoryStream stream = new MemoryStream(data); return FromStream(stream, requiredComponents); } public static IEnumerable<AnimatedFrameResult> AnimatedGifFramesFromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default) { return new AnimatedGifEnumerable(stream, requiredComponents); } } public class ImageResultFloat { public int Width { get; set; } public int Height { get; set; } public ColorComponents SourceComp { get; set; } public ColorComponents Comp { get; set; } public float[] Data { get; set; } internal unsafe static ImageResultFloat FromResult(float* result, int width, int height, ColorComponents comp, ColorComponents req_comp) { if (result == null) { throw new InvalidOperationException(StbImage.stbi__g_failure_reason); } ImageResultFloat imageResultFloat = new ImageResultFloat { Width = width, Height = height, SourceComp = comp, Comp = ((req_comp == ColorComponents.Default) ? comp : req_comp) }; imageResultFloat.Data = new float[width * height * (int)imageResultFloat.Comp]; Marshal.Copy(new IntPtr(result), imageResultFloat.Data, 0, imageResultFloat.Data.Length); return imageResultFloat; } public unsafe static ImageResultFloat FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default) { float* ptr = null; try { int width = default(int); int height = default(int); int comp = default(int); ptr = StbImage.stbi__loadf_main(new StbImage.stbi__context(stream), &width, &height, &comp, (int)requiredComponents); return FromResult(ptr, width, height, (ColorComponents)comp, requiredComponents); } finally { if (ptr != null) { CRuntime.free(ptr); } } } public static ImageResultFloat FromMemory(byte[] data, ColorComponents requiredComponents = ColorComponents.Default) { using MemoryStream stream = new MemoryStream(data); return FromStream(stream, requiredComponents); } } public static class StbImage { public class stbi__context { private readonly Stream _stream; public byte[] _tempBuffer; public int img_n; public int img_out_n; public uint img_x; public uint img_y; public Stream Stream => _stream; public stbi__context(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } _stream = stream; } } public struct stbi__bmp_data { public int bpp; public int offset; public int hsz; public uint mr; public uint mg; public uint mb; public uint ma; public uint all_a; public int extra_read; } public struct stbi__result_info { public int bits_per_channel; public int num_channels; public int channel_order; } public class stbi__gif { public unsafe byte* _out_; public unsafe byte* background; public int bgindex; public stbi__gif_lzw[] codes = new stbi__gif_lzw[8192]; public byte[][] color_table; public int cur_x; public int cur_y; public int delay; public int eflags; public int flags; public int h; public unsafe byte* history; public int lflags; public int line_size; public byte[][] lpal = Utility.CreateArray<byte>(256, 4); public int max_x; public int max_y; public byte[][] pal = Utility.CreateArray<byte>(256, 4); public int parse; public int ratio; public int start_x; public int start_y; public int step; public int transparent; public int w; } public struct stbi__gif_lzw { public short prefix; public byte first; public byte suffix; } public unsafe delegate void delegate0(byte* arg0, int arg1, short* arg2); public unsafe delegate void delegate1(byte* arg0, byte* arg1, byte* arg2, byte* arg3, int arg4, int arg5); public unsafe delegate byte* delegate2(byte* arg0, byte* arg1, byte* arg2, int arg3, int arg4); public struct stbi__huffman { public unsafe fixed byte fast[512]; public unsafe fixed ushort code[256]; public unsafe fixed byte values[256]; public unsafe fixed byte size[257]; public unsafe fixed uint maxcode[18]; public unsafe fixed int delta[17]; } public class stbi__jpeg { public struct unnamed1 { public int id; public int h; public int v; public int tq; public int hd; public int ha; public int dc_pred; public int x; public int y; public int w2; public int h2; public unsafe byte* data; public unsafe void* raw_data; public unsafe void* raw_coeff; public unsafe byte* linebuf; public unsafe short* coeff; public int coeff_w; public int coeff_h; } public int app14_color_transform; public int code_bits; public uint code_buffer; public ushort[][] dequant = Utility.CreateArray<ushort>(4, 64); public int eob_run; public short[][] fast_ac = Utility.CreateArray<short>(4, 512); public stbi__huffman[] huff_ac = new stbi__huffman[4]; public stbi__huffman[] huff_dc = new stbi__huffman[4]; public delegate0 idct_block_kernel; public unnamed1[] img_comp = new unnamed1[4]; public int img_h_max; public int img_mcu_h; public int img_mcu_w; public int img_mcu_x; public int img_mcu_y; public int img_v_max; public int jfif; public byte marker; public int nomore; public int[] order = new int[4]; public int progressive; public delegate2 resample_row_hv_2_kernel; public int restart_interval; public int rgb; public stbi__context s; public int scan_n; public int spec_end; public int spec_start; public int succ_high; public int succ_low; public int todo; public delegate1 YCbCr_to_RGB_kernel; } public class stbi__resample { public int hs; public unsafe byte* line0; public unsafe byte* line1; public delegate2 resample; public int vs; public int w_lores; public int ypos; public int ystep; } public class stbi__png { public unsafe byte* _out_; public int depth; public unsafe byte* expanded; public unsafe byte* idata; public stbi__context s; } public struct stbi__pngchunk { public uint length; public uint type; } public struct stbi__zbuf { public unsafe byte* zbuffer; public unsafe byte* zbuffer_end; public int num_bits; public int hit_zeof_once; public uint code_buffer; public unsafe sbyte* zout; public unsafe sbyte* zout_start; public unsafe sbyte* zout_end; public int z_expandable; public stbi__zhuffman z_length; public stbi__zhuffman z_distance; } public struct stbi__zhuffman { public unsafe fixed ushort fast[512]; public unsafe fixed ushort firstcode[16]; public unsafe fixed int maxcode[17]; public unsafe fixed ushort firstsymbol[16]; public unsafe fixed byte size[288]; public unsafe fixed ushort value[288]; } public static string stbi__g_failure_reason; public static readonly char[] stbi__parse_png_file_invalid_chunk = new char[25]; public const int STBI_default = 0; public const int STBI_grey = 1; public const int STBI_grey_alpha = 2; public const int STBI_rgb = 3; public const int STBI_rgb_alpha = 4; public const int STBI_ORDER_RGB = 0; public const int STBI_ORDER_BGR = 1; public const int STBI__SCAN_load = 0; public const int STBI__SCAN_type = 1; public const int STBI__SCAN_header = 2; public static int stbi__vertically_flip_on_load_global; public static int stbi__vertically_flip_on_load_local; public static int stbi__vertically_flip_on_load_set; public static float stbi__l2h_gamma = 2.2f; public static float stbi__l2h_scale = 1f; public static float stbi__h2l_gamma_i = 0.45454544f; public static float stbi__h2l_scale_i = 1f; public static int stbi__unpremultiply_on_load_global; public static int stbi__de_iphone_flag_global; public static int stbi__unpremultiply_on_load_local; public static int stbi__unpremultiply_on_load_set; public static int stbi__de_iphone_flag_local; public static int stbi__de_iphone_flag_set; public static byte[] stbi__process_marker_tag = new byte[6] { 65, 100, 111, 98, 101, 0 }; public static byte[] stbi__process_frame_header_rgb = new byte[3] { 82, 71, 66 }; public static byte[] stbi__compute_huffman_codes_length_dezigzag = new byte[19] { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; public static int[] stbi__shiftsigned_mul_table = new int[9] { 0, 255, 85, 73, 17, 33, 65, 129, 1 }; public static int[] stbi__shiftsigned_shift_table = new int[9] { 0, 0, 0, 1, 0, 2, 4, 6, 0 }; public static uint[] stbi__bmask = new uint[17] { 0u, 1u, 3u, 7u, 15u, 31u, 63u, 127u, 255u, 511u, 1023u, 2047u, 4095u, 8191u, 16383u, 32767u, 65535u }; public static int[] stbi__jbias = new int[16] { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 }; public static byte[] stbi__jpeg_dezigzag = new byte[79] { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }; public const int STBI__F_none = 0; public const int STBI__F_sub = 1; public const int STBI__F_up = 2; public const int STBI__F_avg = 3; public const int STBI__F_paeth = 4; public const int STBI__F_avg_first = 5; public static byte[] first_row_filter = new byte[5] { 0, 1, 0, 5, 1 }; public static byte[] stbi__check_png_header_png_sig = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }; public static byte[] stbi__depth_scale_table = new byte[9] { 0, 255, 85, 0, 17, 0, 0, 0, 1 }; public static byte[] stbi__zdefault_distance = new byte[32] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; public static byte[] stbi__zdefault_length = new byte[288] { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8 }; public static int[] stbi__zdist_base = new int[32] { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 }; public static int[] stbi__zdist_extra = new int[32] { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0 }; public static int[] stbi__zlength_base = new int[31] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; public static int[] stbi__zlength_extra = new int[31] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 }; public static int NativeAllocations => MemoryStats.Allocations; private static int stbi__err(string str) { stbi__g_failure_reason = str; return 0; } public static byte stbi__get8(stbi__context s) { int num = s.Stream.ReadByte(); if (num == -1) { return 0; } return (byte)num; } public static void stbi__skip(stbi__context s, int skip) { s.Stream.Seek(skip, SeekOrigin.Current); } public static void stbi__rewind(stbi__context s) { s.Stream.Seek(0L, SeekOrigin.Begin); } public static int stbi__at_eof(stbi__context s) { return (s.Stream.Position == s.Stream.Length) ? 1 : 0; } public unsafe static int stbi__getn(stbi__context s, byte* buf, int size) { if (s._tempBuffer == null || s._tempBuffer.Length < size) { s._tempBuffer = new byte[size * 2]; } int num = s.Stream.Read(s._tempBuffer, 0, size); Marshal.Copy(s._tempBuffer, 0, new IntPtr(buf), num); return num; } public static int stbi__bmp_test(stbi__context s) { int result = stbi__bmp_test_raw(s); stbi__rewind(s); return result; } public unsafe static void* stbi__bmp_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) { uint num = 0u; uint num2 = 0u; uint num3 = 0u; uint num4 = 0u; uint num5 = 0u; byte[][] array = Utility.CreateArray<byte>(256, 4); int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int num10 = 0; int num11 = 0; int num12 = 0; stbi__bmp_data stbi__bmp_data = new stbi__bmp_data { all_a = 255u }; if (stbi__bmp_parse_header(s, &stbi__bmp_data) == null) { return null; } num10 = (((int)s.img_y > 0) ? 1 : 0); s.img_y = (uint)CRuntime.abs((int)s.img_y); if (s.img_y > 16777216) { return (void*)(int)((stbi__err("too large") != 0) ? 0u : 0u); } if (s.img_x > 16777216) { return (void*)(int)((stbi__err("too large") != 0) ? 0u : 0u); } num = stbi__bmp_data.mr; num2 = stbi__bmp_data.mg; num3 = stbi__bmp_data.mb; num4 = stbi__bmp_data.ma; num5 = stbi__bmp_data.all_a; if (stbi__bmp_data.hsz == 12) { if (stbi__bmp_data.bpp < 24) { num6 = (stbi__bmp_data.offset - stbi__bmp_data.extra_read - 24) / 3; } } else if (stbi__bmp_data.bpp < 16) { num6 = stbi__bmp_data.offset - stbi__bmp_data.extra_read - stbi__bmp_data.hsz >> 2; } if (num6 == 0) { int num13 = (int)s.Stream.Position; int num14 = 1024; int num15 = 1024; if (num13 <= 0 || num13 > num14) { return (void*)(int)((stbi__err("bad header") != 0) ? 0u : 0u); } if (stbi__bmp_data.offset < num13 || stbi__bmp_data.offset - num13 > num15) { return (void*)(int)((stbi__err("bad offset") != 0) ? 0u : 0u); } stbi__skip(s, stbi__bmp_data.offset - num13); } if (stbi__bmp_data.bpp == 24 && num4 == 4278190080u) { s.img_n = 3; } else { s.img_n = ((num4 != 0) ? 4 : 3); } num12 = ((req_comp == 0 || req_comp < 3) ? s.img_n : req_comp); if (stbi__mad3sizes_valid(num12, (int)s.img_x, (int)s.img_y, 0) == 0) { return (void*)(int)((stbi__err("too large") != 0) ? 0u : 0u); } byte* ptr = (byte*)stbi__malloc_mad3(num12, (int)s.img_x, (int)s.img_y, 0); if (ptr == null) { return (void*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } if (stbi__bmp_data.bpp < 16) { int num16 = 0; if (num6 == 0 || num6 > 256) { CRuntime.free(ptr); return (void*)(int)((stbi__err("invalid") != 0) ? 0u : 0u); } for (num7 = 0; num7 < num6; num7++) { array[num7][2] = stbi__get8(s); array[num7][1] = stbi__get8(s); array[num7][0] = stbi__get8(s); if (stbi__bmp_data.hsz != 12) { stbi__get8(s); } array[num7][3] = byte.MaxValue; } stbi__skip(s, stbi__bmp_data.offset - stbi__bmp_data.extra_read - stbi__bmp_data.hsz - num6 * ((stbi__bmp_data.hsz == 12) ? 3 : 4)); if (stbi__bmp_data.bpp == 1) { num9 = (int)(s.img_x + 7 >> 3); } else if (stbi__bmp_data.bpp == 4) { num9 = (int)(s.img_x + 1 >> 1); } else { if (stbi__bmp_data.bpp != 8) { CRuntime.free(ptr); return (void*)(int)((stbi__err("bad bpp") != 0) ? 0u : 0u); } num9 = (int)s.img_x; } num11 = -num9 & 3; if (stbi__bmp_data.bpp == 1) { for (num8 = 0; num8 < (int)s.img_y; num8++) { int num17 = 7; int num18 = stbi__get8(s); for (num7 = 0; num7 < (int)s.img_x; num7++) { int num19 = (num18 >> num17) & 1; ptr[num16++] = array[num19][0]; ptr[num16++] = array[num19][1]; ptr[num16++] = array[num19][2]; if (num12 == 4) { ptr[num16++] = byte.MaxValue; } if (num7 + 1 == (int)s.img_x) { break; } if (--num17 < 0) { num17 = 7; num18 = stbi__get8(s); } } stbi__skip(s, num11); } } else { for (num8 = 0; num8 < (int)s.img_y; num8++) { for (num7 = 0; num7 < (int)s.img_x; num7 += 2) { int num20 = stbi__get8(s); int num21 = 0; if (stbi__bmp_data.bpp == 4) { num21 = num20 & 0xF; num20 >>= 4; } ptr[num16++] = array[num20][0]; ptr[num16++] = array[num20][1]; ptr[num16++] = array[num20][2]; if (num12 == 4) { ptr[num16++] = byte.MaxValue; } if (num7 + 1 == (int)s.img_x) { break; } num20 = ((stbi__bmp_data.bpp == 8) ? stbi__get8(s) : num21); ptr[num16++] = array[num20][0]; ptr[num16++] = array[num20][1]; ptr[num16++] = array[num20][2]; if (num12 == 4) { ptr[num16++] = byte.MaxValue; } } stbi__skip(s, num11); } } } else { int shift = 0; int shift2 = 0; int shift3 = 0; int shift4 = 0; int num22 = 0; int num23 = 0; int num24 = 0; int num25 = 0; int num26 = 0; int num27 = 0; stbi__skip(s, stbi__bmp_data.offset - stbi__bmp_data.extra_read - stbi__bmp_data.hsz); num9 = (int)((stbi__bmp_data.bpp == 24) ? (3 * s.img_x) : ((stbi__bmp_data.bpp == 16) ? (2 * s.img_x) : 0)); num11 = -num9 & 3; if (stbi__bmp_data.bpp == 24) { num27 = 1; } else if (stbi__bmp_data.bpp == 32 && num3 == 255 && num2 == 65280 && num == 16711680 && num4 == 4278190080u) { num27 = 2; } if (num27 == 0) { if (num == 0 || num2 == 0 || num3 == 0) { CRuntime.free(ptr); return (void*)(int)((stbi__err("bad masks") != 0) ? 0u : 0u); } shift = stbi__high_bit(num) - 7; num22 = stbi__bitcount(num); shift2 = stbi__high_bit(num2) - 7; num23 = stbi__bitcount(num2); shift3 = stbi__high_bit(num3) - 7; num24 = stbi__bitcount(num3); shift4 = stbi__high_bit(num4) - 7; num25 = stbi__bitcount(num4); if (num22 > 8 || num23 > 8 || num24 > 8 || num25 > 8) { CRuntime.free(ptr); return (void*)(int)((stbi__err("bad masks") != 0) ? 0u : 0u); } } for (num8 = 0; num8 < (int)s.img_y; num8++) { if (num27 != 0) { for (num7 = 0; num7 < (int)s.img_x; num7++) { byte b = 0; ptr[num26 + 2] = stbi__get8(s); ptr[num26 + 1] = stbi__get8(s); ptr[num26] = stbi__get8(s); num26 += 3; b = ((num27 == 2) ? stbi__get8(s) : byte.MaxValue); num5 |= b; if (num12 == 4) { ptr[num26++] = b; } } } else { int bpp = stbi__bmp_data.bpp; for (num7 = 0; num7 < (int)s.img_x; num7++) { uint num28 = ((bpp == 16) ? ((uint)stbi__get16le(s)) : stbi__get32le(s)); uint num29 = 0u; ptr[num26++] = (byte)(stbi__shiftsigned(num28 & num, shift, num22) & 0xFF); ptr[num26++] = (byte)(stbi__shiftsigned(num28 & num2, shift2, num23) & 0xFF); ptr[num26++] = (byte)(stbi__shiftsigned(num28 & num3, shift3, num24) & 0xFF); num29 = ((num4 != 0) ? ((uint)stbi__shiftsigned(num28 & num4, shift4, num25)) : 255u); num5 |= num29; if (num12 == 4) { ptr[num26++] = (byte)(num29 & 0xFF); } } } stbi__skip(s, num11); } } if (num12 == 4 && num5 == 0) { for (num7 = (int)(4 * s.img_x * s.img_y - 1); num7 >= 0; num7 -= 4) { ptr[num7] = byte.MaxValue; } } if (num10 != 0) { byte b2 = 0; for (num8 = 0; num8 < (int)s.img_y >> 1; num8++) { byte* ptr2 = ptr + num8 * s.img_x * num12; byte* ptr3 = ptr + (s.img_y - 1 - num8) * s.img_x * num12; for (num7 = 0; num7 < (int)s.img_x * num12; num7++) { b2 = ptr2[num7]; ptr2[num7] = ptr3[num7]; ptr3[num7] = b2; } } } if (req_comp != 0 && req_comp != num12) { ptr = stbi__convert_format(ptr, num12, req_comp, s.img_x, s.img_y); if (ptr == null) { return ptr; } } *x = (int)s.img_x; *y = (int)s.img_y; if (comp != null) { *comp = s.img_n; } return ptr; } public unsafe static int stbi__bmp_info(stbi__context s, int* x, int* y, int* comp) { stbi__bmp_data stbi__bmp_data = new stbi__bmp_data { all_a = 255u }; if (stbi__bmp_parse_header(s, &stbi__bmp_data) == null) { stbi__rewind(s); return 0; } if (x != null) { *x = (int)s.img_x; } if (y != null) { *y = (int)s.img_y; } if (comp != null) { if (stbi__bmp_data.bpp == 24 && stbi__bmp_data.ma == 4278190080u) { *comp = 3; } else { *comp = ((stbi__bmp_data.ma != 0) ? 4 : 3); } } return 1; } public static int stbi__bmp_test_raw(stbi__context s) { int num = 0; if (stbi__get8(s) != 66) { return 0; } if (stbi__get8(s) != 77) { return 0; } stbi__get32le(s); stbi__get16le(s); stbi__get16le(s); stbi__get32le(s); num = (int)stbi__get32le(s); if (num != 12 && num != 40 && num != 56 && num != 108 && num != 124) { return 0; } return 1; } public unsafe static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) { switch (compress) { case 3: return 1; case 0: if (info->bpp == 16) { info->mr = 31744u; info->mg = 992u; info->mb = 31u; } else if (info->bpp == 32) { info->mr = 16711680u; info->mg = 65280u; info->mb = 255u; info->ma = 4278190080u; info->all_a = 0u; } else { info->mr = (info->mg = (info->mb = (info->ma = 0u))); } return 1; default: return 0; } } public unsafe static void* stbi__bmp_parse_header(stbi__context s, stbi__bmp_data* info) { int num = 0; if (stbi__get8(s) != 66 || stbi__get8(s) != 77) { return (void*)(int)((stbi__err("not BMP") != 0) ? 0u : 0u); } stbi__get32le(s); stbi__get16le(s); stbi__get16le(s); info->offset = (int)stbi__get32le(s); num = (info->hsz = (int)stbi__get32le(s)); info->mr = (info->mg = (info->mb = (info->ma = 0u))); info->extra_read = 14; if (info->offset < 0) { return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u); } if (num != 12 && num != 40 && num != 56 && num != 108 && num != 124) { return (void*)(int)((stbi__err("unknown BMP") != 0) ? 0u : 0u); } if (num == 12) { s.img_x = (uint)stbi__get16le(s); s.img_y = (uint)stbi__get16le(s); } else { s.img_x = stbi__get32le(s); s.img_y = stbi__get32le(s); } if (stbi__get16le(s) != 1) { return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u); } info->bpp = stbi__get16le(s); if (num != 12) { int num2 = (int)stbi__get32le(s); if (num2 == 1 || num2 == 2) { return (void*)(int)((stbi__err("BMP RLE") != 0) ? 0u : 0u); } if (num2 >= 4) { return (void*)(int)((stbi__err("BMP JPEG/PNG") != 0) ? 0u : 0u); } if (num2 == 3 && info->bpp != 16 && info->bpp != 32) { return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u); } stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); if (num == 40 || num == 56) { if (num == 56) { stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); } if (info->bpp == 16 || info->bpp == 32) { switch (num2) { case 0: stbi__bmp_set_mask_defaults(info, num2); break; case 3: info->mr = stbi__get32le(s); info->mg = stbi__get32le(s); info->mb = stbi__get32le(s); info->extra_read += 12; if (info->mr == info->mg && info->mg == info->mb) { return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u); } break; default: return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u); } } } else { int num3 = 0; if (num != 108 && num != 124) { return (void*)(int)((stbi__err("bad BMP") != 0) ? 0u : 0u); } info->mr = stbi__get32le(s); info->mg = stbi__get32le(s); info->mb = stbi__get32le(s); info->ma = stbi__get32le(s); if (num2 != 3) { stbi__bmp_set_mask_defaults(info, num2); } stbi__get32le(s); for (num3 = 0; num3 < 12; num3++) { stbi__get32le(s); } if (num == 124) { stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); } } } return (void*)1; } public static void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1f / gamma; } public static void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1f / scale; } public static void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } public static void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } public static void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) { stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; } public static void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) { stbi__de_iphone_flag_global = flag_true_if_should_convert; } public static void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) { stbi__vertically_flip_on_load_global = flag_true_if_should_flip; } public static void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) { stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; stbi__unpremultiply_on_load_set = 1; } public static void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) { stbi__de_iphone_flag_local = flag_true_if_should_convert; stbi__de_iphone_flag_set = 1; } public static void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) { stbi__vertically_flip_on_load_local = flag_true_if_should_flip; stbi__vertically_flip_on_load_set = 1; } public unsafe static void* stbi__malloc(ulong size) { return CRuntime.malloc(size); } public static int stbi__addsizes_valid(int a, int b) { if (b < 0) { return 0; } return (a <= int.MaxValue - b) ? 1 : 0; } public static int stbi__mul2sizes_valid(int a, int b) { if (a < 0 || b < 0) { return 0; } if (b == 0) { return 1; } return (a <= int.MaxValue / b) ? 1 : 0; } public static int stbi__mad2sizes_valid(int a, int b, int add) { if (stbi__mul2sizes_valid(a, b) == 0 || stbi__addsizes_valid(a * b, add) == 0) { return 0; } return 1; } public static int stbi__mad3sizes_valid(int a, int b, int c, int add) { if (stbi__mul2sizes_valid(a, b) == 0 || stbi__mul2sizes_valid(a * b, c) == 0 || stbi__addsizes_valid(a * b * c, add) == 0) { return 0; } return 1; } public static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) { if (stbi__mul2sizes_valid(a, b) == 0 || stbi__mul2sizes_valid(a * b, c) == 0 || stbi__mul2sizes_valid(a * b * c, d) == 0 || stbi__addsizes_valid(a * b * c * d, add) == 0) { return 0; } return 1; } public unsafe static void* stbi__malloc_mad2(int a, int b, int add) { if (stbi__mad2sizes_valid(a, b, add) == 0) { return null; } return stbi__malloc((ulong)(a * b + add)); } public unsafe static void* stbi__malloc_mad3(int a, int b, int c, int add) { if (stbi__mad3sizes_valid(a, b, c, add) == 0) { return null; } return stbi__malloc((ulong)(a * b * c + add)); } public unsafe static void* stbi__malloc_mad4(int a, int b, int c, int d, int add) { if (stbi__mad4sizes_valid(a, b, c, d, add) == 0) { return null; } return stbi__malloc((ulong)(a * b * c * d + add)); } public static int stbi__addints_valid(int a, int b) { if (a >= 0 != b >= 0) { return 1; } if (a < 0 && b < 0) { return (a >= int.MinValue - b) ? 1 : 0; } return (a <= int.MaxValue - b) ? 1 : 0; } public static int stbi__mul2shorts_valid(int a, int b) { if (b == 0 || b == -1) { return 1; } if (a >= 0 == b >= 0) { return (a <= 32767 / b) ? 1 : 0; } if (b < 0) { return (a <= -32768 / b) ? 1 : 0; } return (a >= -32768 / b) ? 1 : 0; } public unsafe static float* stbi__ldr_to_hdr(byte* data, int x, int y, int comp) { int num = 0; int num2 = 0; int num3 = 0; if (data == null) { return null; } float* ptr = (float*)stbi__malloc_mad4(x, y, comp, 4, 0); if (ptr == null) { CRuntime.free(data); return (float*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } num3 = (((comp & 1) == 0) ? (comp - 1) : comp); for (num = 0; num < x * y; num++) { for (num2 = 0; num2 < num3; num2++) { ptr[num * comp + num2] = (float)(CRuntime.pow((float)(int)data[num * comp + num2] / 255f, stbi__l2h_gamma) * (double)stbi__l2h_scale); } } if (num3 < comp) { for (num = 0; num < x * y; num++) { ptr[num * comp + num3] = (float)(int)data[num * comp + num3] / 255f; } } CRuntime.free(data); return ptr; } public unsafe static void* stbi__load_main(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) { CRuntime.memset(ri, 0, (ulong)sizeof(stbi__result_info)); ri->bits_per_channel = 8; ri->channel_order = 0; ri->num_channels = 0; if (stbi__png_test(s) != 0) { return stbi__png_load(s, x, y, comp, req_comp, ri); } if (stbi__bmp_test(s) != 0) { return stbi__bmp_load(s, x, y, comp, req_comp, ri); } if (stbi__gif_test(s) != 0) { return stbi__gif_load(s, x, y, comp, req_comp, ri); } if (stbi__psd_test(s) != 0) { return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc); } if (stbi__jpeg_test(s) != 0) { return stbi__jpeg_load(s, x, y, comp, req_comp, ri); } if (stbi__hdr_test(s) != 0) { return stbi__hdr_to_ldr(stbi__hdr_load(s, x, y, comp, req_comp, ri), *x, *y, (req_comp != 0) ? req_comp : (*comp)); } if (stbi__tga_test(s) != 0) { return stbi__tga_load(s, x, y, comp, req_comp, ri); } return (void*)(int)((stbi__err("unknown image type") != 0) ? 0u : 0u); } public unsafe static byte* stbi__convert_16_to_8(ushort* orig, int w, int h, int channels) { int num = 0; int num2 = w * h * channels; byte* ptr = (byte*)stbi__malloc((ulong)num2); if (ptr == null) { return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } for (num = 0; num < num2; num++) { ptr[num] = (byte)((orig[num] >> 8) & 0xFF); } CRuntime.free(orig); return ptr; } public unsafe static ushort* stbi__convert_8_to_16(byte* orig, int w, int h, int channels) { int num = 0; int num2 = w * h * channels; ushort* ptr = (ushort*)stbi__malloc((ulong)(num2 * 2)); if (ptr == null) { return (ushort*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } for (num = 0; num < num2; num++) { ptr[num] = (ushort)((orig[num] << 8) + orig[num]); } CRuntime.free(orig); return ptr; } public unsafe static void stbi__vertical_flip(void* image, int w, int h, int bytes_per_pixel) { int num = 0; int num2 = w * bytes_per_pixel; byte* ptr = stackalloc byte[2048]; for (num = 0; num < h >> 1; num++) { byte* ptr2 = (byte*)image + num * num2; byte* ptr3 = (byte*)image + (h - num - 1) * num2; ulong num3 = (ulong)num2; while (num3 != 0L) { ulong num4 = ((num3 < 2048) ? num3 : 2048); CRuntime.memcpy(ptr, ptr2, num4); CRuntime.memcpy(ptr2, ptr3, num4); CRuntime.memcpy(ptr3, ptr, num4); ptr2 += num4; ptr3 += num4; num3 -= num4; } } } public unsafe static void stbi__vertical_flip_slices(void* image, int w, int h, int z, int bytes_per_pixel) { int num = 0; int num2 = w * h * bytes_per_pixel; byte* ptr = (byte*)image; for (num = 0; num < z; num++) { stbi__vertical_flip(ptr, w, h, bytes_per_pixel); ptr += num2; } } public unsafe static byte* stbi__load_and_postprocess_8bit(stbi__context s, int* x, int* y, int* comp, int req_comp) { stbi__result_info stbi__result_info = default(stbi__result_info); void* ptr = stbi__load_main(s, x, y, comp, req_comp, &stbi__result_info, 8); if (ptr == null) { return null; } if (stbi__result_info.bits_per_channel != 8) { ptr = stbi__convert_16_to_8((ushort*)ptr, *x, *y, (req_comp == 0) ? (*comp) : req_comp); stbi__result_info.bits_per_channel = 8; } if (((stbi__vertically_flip_on_load_set != 0) ? stbi__vertically_flip_on_load_local : stbi__vertically_flip_on_load_global) != 0) { int bytes_per_pixel = ((req_comp != 0) ? req_comp : (*comp)); stbi__vertical_flip(ptr, *x, *y, bytes_per_pixel); } return (byte*)ptr; } public unsafe static ushort* stbi__load_and_postprocess_16bit(stbi__context s, int* x, int* y, int* comp, int req_comp) { stbi__result_info stbi__result_info = default(stbi__result_info); void* ptr = stbi__load_main(s, x, y, comp, req_comp, &stbi__result_info, 16); if (ptr == null) { return null; } if (stbi__result_info.bits_per_channel != 16) { ptr = stbi__convert_8_to_16((byte*)ptr, *x, *y, (req_comp == 0) ? (*comp) : req_comp); stbi__result_info.bits_per_channel = 16; } if (((stbi__vertically_flip_on_load_set != 0) ? stbi__vertically_flip_on_load_local : stbi__vertically_flip_on_load_global) != 0) { int num = ((req_comp != 0) ? req_comp : (*comp)); stbi__vertical_flip(ptr, *x, *y, num * 2); } return (ushort*)ptr; } public unsafe static void stbi__float_postprocess(float* result, int* x, int* y, int* comp, int req_comp) { if (((stbi__vertically_flip_on_load_set != 0) ? stbi__vertically_flip_on_load_local : stbi__vertically_flip_on_load_global) != 0 && result != null) { int num = ((req_comp != 0) ? req_comp : (*comp)); stbi__vertical_flip(result, *x, *y, num * 4); } } public unsafe static float* stbi__loadf_main(stbi__context s, int* x, int* y, int* comp, int req_comp) { if (stbi__hdr_test(s) != 0) { stbi__result_info stbi__result_info = default(stbi__result_info); float* ptr = stbi__hdr_load(s, x, y, comp, req_comp, &stbi__result_info); if (ptr != null) { stbi__float_postprocess(ptr, x, y, comp, req_comp); } return ptr; } byte* ptr2 = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); if (ptr2 != null) { return stbi__ldr_to_hdr(ptr2, *x, *y, (req_comp != 0) ? req_comp : (*comp)); } return (float*)(int)((stbi__err("unknown image type") != 0) ? 0u : 0u); } public static int stbi__get16be(stbi__context s) { return (stbi__get8(s) << 8) + stbi__get8(s); } public static uint stbi__get32be(stbi__context s) { return (uint)((uint)(stbi__get16be(s) << 16) + stbi__get16be(s)); } public static int stbi__get16le(stbi__context s) { return stbi__get8(s) + (stbi__get8(s) << 8); } public static uint stbi__get32le(stbi__context s) { return (uint)(stbi__get16le(s) + (stbi__get16le(s) << 16)); } public static byte stbi__compute_y(int r, int g, int b) { return (byte)(r * 77 + g * 150 + 29 * b >> 8); } public unsafe static byte* stbi__convert_format(byte* data, int img_n, int req_comp, uint x, uint y) { int num = 0; int num2 = 0; if (req_comp == img_n) { return data; } byte* ptr = (byte*)stbi__malloc_mad3(req_comp, (int)x, (int)y, 0); if (ptr == null) { CRuntime.free(data); return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } for (num2 = 0; num2 < (int)y; num2++) { byte* ptr2 = data + num2 * x * img_n; byte* ptr3 = ptr + num2 * x * req_comp; switch (img_n * 8 + req_comp) { case 10: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; ptr3[1] = byte.MaxValue; num--; ptr2++; ptr3 += 2; } break; case 11: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); num--; ptr2++; ptr3 += 3; } break; case 12: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); ptr3[3] = byte.MaxValue; num--; ptr2++; ptr3 += 4; } break; case 17: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; num--; ptr2 += 2; ptr3++; } break; case 19: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); num--; ptr2 += 2; ptr3 += 3; } break; case 20: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); ptr3[3] = ptr2[1]; num--; ptr2 += 2; ptr3 += 4; } break; case 28: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; ptr3[1] = ptr2[1]; ptr3[2] = ptr2[2]; ptr3[3] = byte.MaxValue; num--; ptr2 += 3; ptr3 += 4; } break; case 25: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]); num--; ptr2 += 3; ptr3++; } break; case 26: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]); ptr3[1] = byte.MaxValue; num--; ptr2 += 3; ptr3 += 2; } break; case 33: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]); num--; ptr2 += 4; ptr3++; } break; case 34: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y(*ptr2, ptr2[1], ptr2[2]); ptr3[1] = ptr2[3]; num--; ptr2 += 4; ptr3 += 2; } break; case 35: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; ptr3[1] = ptr2[1]; ptr3[2] = ptr2[2]; num--; ptr2 += 4; ptr3 += 3; } break; default: CRuntime.free(data); CRuntime.free(ptr); return (byte*)(int)((stbi__err("unsupported") != 0) ? 0u : 0u); } } CRuntime.free(data); return ptr; } public static ushort stbi__compute_y_16(int r, int g, int b) { return (ushort)(r * 77 + g * 150 + 29 * b >> 8); } public unsafe static ushort* stbi__convert_format16(ushort* data, int img_n, int req_comp, uint x, uint y) { int num = 0; int num2 = 0; if (req_comp == img_n) { return data; } ushort* ptr = (ushort*)stbi__malloc((ulong)(req_comp * x * y * 2)); if (ptr == null) { CRuntime.free(data); return (ushort*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } for (num2 = 0; num2 < (int)y; num2++) { ushort* ptr2 = data + num2 * x * img_n; ushort* ptr3 = ptr + num2 * x * req_comp; switch (img_n * 8 + req_comp) { case 10: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; ptr3[1] = ushort.MaxValue; num--; ptr2++; ptr3 += 2; } break; case 11: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); num--; ptr2++; ptr3 += 3; } break; case 12: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); ptr3[3] = ushort.MaxValue; num--; ptr2++; ptr3 += 4; } break; case 17: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; num--; ptr2 += 2; ptr3++; } break; case 19: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); num--; ptr2 += 2; ptr3 += 3; } break; case 20: num = (int)(x - 1); while (num >= 0) { *ptr3 = (ptr3[1] = (ptr3[2] = *ptr2)); ptr3[3] = ptr2[1]; num--; ptr2 += 2; ptr3 += 4; } break; case 28: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; ptr3[1] = ptr2[1]; ptr3[2] = ptr2[2]; ptr3[3] = ushort.MaxValue; num--; ptr2 += 3; ptr3 += 4; } break; case 25: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]); num--; ptr2 += 3; ptr3++; } break; case 26: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]); ptr3[1] = ushort.MaxValue; num--; ptr2 += 3; ptr3 += 2; } break; case 33: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]); num--; ptr2 += 4; ptr3++; } break; case 34: num = (int)(x - 1); while (num >= 0) { *ptr3 = stbi__compute_y_16(*ptr2, ptr2[1], ptr2[2]); ptr3[1] = ptr2[3]; num--; ptr2 += 4; ptr3 += 2; } break; case 35: num = (int)(x - 1); while (num >= 0) { *ptr3 = *ptr2; ptr3[1] = ptr2[1]; ptr3[2] = ptr2[2]; num--; ptr2 += 4; ptr3 += 3; } break; default: CRuntime.free(data); CRuntime.free(ptr); return (ushort*)(int)((stbi__err("unsupported") != 0) ? 0u : 0u); } } CRuntime.free(data); return ptr; } public static byte stbi__clamp(int x) { if ((uint)x > 255u) { if (x < 0) { return 0; } if (x > 255) { return byte.MaxValue; } } return (byte)x; } public static byte stbi__blinn_8x8(byte x, byte y) { int num = x * y + 128; return (byte)((uint)(num + (num >>> 8)) >> 8); } public static int stbi__bitreverse16(int n) { n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); n = ((n & 0xF0F0) >> 4) | ((n & 0xF0F) << 4); n = ((n & 0xFF00) >> 8) | ((n & 0xFF) << 8); return n; } public static int stbi__bit_reverse(int v, int bits) { return stbi__bitreverse16(v) >> 16 - bits; } public static int stbi__high_bit(uint z) { int num = 0; if (z == 0) { return -1; } if (z >= 65536) { num += 16; z >>= 16; } if (z >= 256) { num += 8; z >>= 8; } if (z >= 16) { num += 4; z >>= 4; } if (z >= 4) { num += 2; z >>= 2; } if (z >= 2) { num++; } return num; } public static int stbi__bitcount(uint a) { a = (a & 0x55555555) + ((a >> 1) & 0x55555555); a = (a & 0x33333333) + ((a >> 2) & 0x33333333); a = (a + (a >> 4)) & 0xF0F0F0F; a += a >> 8; a += a >> 16; return (int)(a & 0xFF); } public static int stbi__shiftsigned(uint v, int shift, int bits) { v = ((shift >= 0) ? (v >> shift) : (v << -shift)); v >>= 8 - bits; return (int)(v * stbi__shiftsigned_mul_table[bits]) >> stbi__shiftsigned_shift_table[bits]; } public unsafe static int stbi__info_main(stbi__context s, int* x, int* y, int* comp) { if (stbi__jpeg_info(s, x, y, comp) != 0) { return 1; } if (stbi__png_info(s, x, y, comp) != 0) { return 1; } if (stbi__gif_info(s, x, y, comp) != 0) { return 1; } if (stbi__bmp_info(s, x, y, comp) != 0) { return 1; } if (stbi__psd_info(s, x, y, comp) != 0) { return 1; } if (stbi__hdr_info(s, x, y, comp) != 0) { return 1; } if (stbi__tga_info(s, x, y, comp) != 0) { return 1; } return stbi__err("unknown image type"); } public static int stbi__is_16_main(stbi__context s) { if (stbi__png_is16(s) != 0) { return 1; } if (stbi__psd_is16(s) != 0) { return 1; } return 0; } public static int stbi__gif_test(stbi__context s) { int result = stbi__gif_test_raw(s); stbi__rewind(s); return result; } public unsafe static void* stbi__gif_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) { byte* ptr = null; stbi__gif stbi__gif = new stbi__gif(); ptr = stbi__gif_load_next(s, stbi__gif, comp, req_comp, null); if (ptr != null) { *x = stbi__gif.w; *y = stbi__gif.h; if (req_comp != 0 && req_comp != 4) { ptr = stbi__convert_format(ptr, 4, req_comp, (uint)stbi__gif.w, (uint)stbi__gif.h); } } else if (stbi__gif._out_ != null) { CRuntime.free(stbi__gif._out_); } CRuntime.free(stbi__gif.history); CRuntime.free(stbi__gif.background); return ptr; } public unsafe static void* stbi__load_gif_main(stbi__context s, int** delays, int* x, int* y, int* z, int* comp, int req_comp) { if (stbi__gif_test(s) != 0) { int num = 0; byte* ptr = null; byte* ptr2 = null; byte* two_back = null; stbi__gif stbi__gif = new stbi__gif(); int num2 = 0; if (delays != null) { *delays = null; } do { ptr = stbi__gif_load_next(s, stbi__gif, comp, req_comp, two_back); if (ptr == null) { continue; } *x = stbi__gif.w; *y = stbi__gif.h; num++; num2 = stbi__gif.w * stbi__gif.h * 4; if (ptr2 != null) { void* ptr3 = CRuntime.realloc(ptr2, (ulong)(num * num2)); if (ptr3 == null) { return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays); } ptr2 = (byte*)ptr3; if (delays != null) { int* ptr4 = (int*)CRuntime.realloc(*delays, (ulong)(4 * num)); if (ptr4 == null) { return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays); } *delays = ptr4; } } else { ptr2 = (byte*)stbi__malloc((ulong)(num * num2)); if (ptr2 == null) { return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays); } if (delays != null) { *delays = (int*)stbi__malloc((ulong)(num * 4)); if (*delays == null) { return stbi__load_gif_main_outofmem(stbi__gif, ptr2, delays); } } } CRuntime.memcpy(ptr2 + (num - 1) * num2, ptr, (ulong)num2); if (num >= 2) { two_back = ptr2 - 2 * num2; } if (delays != null) { (*delays)[(long)num - 1L] = stbi__gif.delay; } } while (ptr != null); CRuntime.free(stbi__gif._out_); CRuntime.free(stbi__gif.history); CRuntime.free(stbi__gif.background); if (req_comp != 0 && req_comp != 4) { ptr2 = stbi__convert_format(ptr2, 4, req_comp, (uint)(num * stbi__gif.w), (uint)stbi__gif.h); } *z = num; return ptr2; } return (void*)(int)((stbi__err("not GIF") != 0) ? 0u : 0u); } public unsafe static int stbi__gif_info(stbi__context s, int* x, int* y, int* comp) { return stbi__gif_info_raw(s, x, y, comp); } public static int stbi__gif_test_raw(stbi__context s) { int num = 0; if (stbi__get8(s) != 71 || stbi__get8(s) != 73 || stbi__get8(s) != 70 || stbi__get8(s) != 56) { return 0; } num = stbi__get8(s); if (num != 57 && num != 55) { return 0; } if (stbi__get8(s) != 97) { return 0; } return 1; } public static void stbi__gif_parse_colortable(stbi__context s, byte[][] pal, int num_entries, int transp) { int num = 0; for (num = 0; num < num_entries; num++) { pal[num][2] = stbi__get8(s); pal[num][1] = stbi__get8(s); pal[num][0] = stbi__get8(s); pal[num][3] = (byte)((transp != num) ? 255u : 0u); } } public unsafe static int stbi__gif_header(stbi__context s, stbi__gif g, int* comp, int is_info) { byte b = 0; if (stbi__get8(s) != 71 || stbi__get8(s) != 73 || stbi__get8(s) != 70 || stbi__get8(s) != 56) { return stbi__err("not GIF"); } b = stbi__get8(s); if (b != 55 && b != 57) { return stbi__err("not GIF"); } if (stbi__get8(s) != 97) { return stbi__err("not GIF"); } stbi__g_failure_reason = ""; g.w = stbi__get16le(s); g.h = stbi__get16le(s); g.flags = stbi__get8(s); g.bgindex = stbi__get8(s); g.ratio = stbi__get8(s); g.transparent = -1; if (g.w > 16777216) { return stbi__err("too large"); } if (g.h > 16777216) { return stbi__err("too large"); } if (comp != null) { *comp = 4; } if (is_info != 0) { return 1; } if ((g.flags & 0x80) != 0) { stbi__gif_parse_colortable(s, g.pal, 2 << (g.flags & 7), -1); } return 1; } public unsafe static int stbi__gif_info_raw(stbi__context s, int* x, int* y, int* comp) { stbi__gif stbi__gif = new stbi__gif(); if (stbi__gif == null) { return stbi__err("outofmem"); } if (stbi__gif_header(s, stbi__gif, comp, 1) == 0) { stbi__rewind(s); return 0; } if (x != null) { *x = stbi__gif.w; } if (y != null) { *y = stbi__gif.h; } return 1; } public unsafe static void stbi__out_gif_code(stbi__gif g, ushort code) { int num = 0; if (g.codes[code].prefix >= 0) { stbi__out_gif_code(g, (ushort)g.codes[code].prefix); } if (g.cur_y >= g.max_y) { return; } num = g.cur_x + g.cur_y; byte* ptr = g._out_ + num; g.history[num / 4] = 1; byte[] array = g.color_table[g.codes[code].suffix]; if (array[3] > 128) { *ptr = array[2]; ptr[1] = array[1]; ptr[2] = array[0]; ptr[3] = array[3]; } g.cur_x += 4; if (g.cur_x >= g.max_x) { g.cur_x = g.start_x; g.cur_y += g.step; while (g.cur_y >= g.max_y && g.parse > 0) { g.step = (1 << g.parse) * g.line_size; g.cur_y = g.start_y + (g.step >> 1); g.parse--; } } } public unsafe static byte* stbi__process_gif_raster(stbi__context s, stbi__gif g) { byte b = 0; int num = 0; int num2 = 0; uint num3 = 0u; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int num10 = 0; b = stbi__get8(s); if (b > 12) { return null; } num10 = 1 << (int)b; num3 = 1u; num4 = b + 1; num5 = (1 << num4) - 1; num8 = 0; num9 = 0; for (num2 = 0; num2 < num10; num2++) { g.codes[num2].prefix = -1; g.codes[num2].first = (byte)num2; g.codes[num2].suffix = (byte)num2; } num6 = num10 + 2; num7 = -1; num = 0; while (true) { if (num9 < num4) { if (num == 0) { num = stbi__get8(s); if (num == 0) { return g._out_; } } num--; num8 |= stbi__get8(s) << num9; num9 += 8; continue; } int num11 = num8 & num5; num8 >>= num4; num9 -= num4; if (num11 == num10) { num4 = b + 1; num5 = (1 << num4) - 1; num6 = num10 + 2; num7 = -1; num3 = 0u; continue; } if (num11 == num10 + 1) { stbi__skip(s, num); while ((num = stbi__get8(s)) > 0) { stbi__skip(s, num); } return g._out_; } if (num11 > num6) { break; } if (num3 != 0) { return (byte*)(int)((stbi__err("no clear code") != 0) ? 0u : 0u); } if (num7 >= 0) { fixed (stbi__gif_lzw* ptr = &g.codes[num6++]) { if (num6 > 8192) { return (byte*)(int)((stbi__err("too many codes") != 0) ? 0u : 0u); } ptr->prefix = (short)num7; ptr->first = g.codes[num7].first; ptr->suffix = ((num11 == num6) ? ptr->first : g.codes[num11].first); } } else if (num11 == num6) { return (byte*)(int)((stbi__err("illegal code in raster") != 0) ? 0u : 0u); } stbi__out_gif_code(g, (ushort)num11); if ((num6 & num5) == 0 && num6 <= 4095) { num4++; num5 = (1 << num4) - 1; } num7 = num11; } return (byte*)(int)((stbi__err("illegal code in raster") != 0) ? 0u : 0u); } public unsafe static byte* stbi__gif_load_next(stbi__context s, stbi__gif g, int* comp, int req_comp, byte* two_back) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; num2 = 0; if (g._out_ == null) { if (stbi__gif_header(s, g, comp, 0) == 0) { return null; } if (stbi__mad3sizes_valid(4, g.w, g.h, 0) == 0) { return (byte*)(int)((stbi__err("too large") != 0) ? 0u : 0u); } num4 = g.w * g.h; g._out_ = (byte*)stbi__malloc((ulong)(4 * num4)); g.background = (byte*)stbi__malloc((ulong)(4 * num4)); g.history = (byte*)stbi__malloc((ulong)num4); if (g._out_ == null || g.background == null || g.history == null) { return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } CRuntime.memset(g._out_, 0, (ulong)(4 * num4)); CRuntime.memset(g.background, 0, (ulong)(4 * num4)); CRuntime.memset(g.history, 0, (ulong)num4); num2 = 1; } else { num = (g.eflags & 0x1C) >> 2; num4 = g.w * g.h; if (num == 3 && two_back == null) { num = 2; } switch (num) { case 3: for (num3 = 0; num3 < num4; num3++) { if (g.history[num3] != 0) { CRuntime.memcpy(g._out_ + num3 * 4, two_back + num3 * 4, 4uL); } } break; case 2: for (num3 = 0; num3 < num4; num3++) { if (g.history[num3] != 0) { CRuntime.memcpy(g._out_ + num3 * 4, g.background + num3 * 4, 4uL); } } break; } CRuntime.memcpy(g.background, g._out_, (ulong)(4 * g.w * g.h)); } CRuntime.memset(g.history, 0, (ulong)(g.w * g.h)); while (true) { switch (stbi__get8(s)) { case 44: { int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; num6 = stbi__get16le(s); num7 = stbi__get16le(s); num8 = stbi__get16le(s); num9 = stbi__get16le(s); if (num6 + num8 > g.w || num7 + num9 > g.h) { return (byte*)(int)((stbi__err("bad Image Descriptor") != 0) ? 0u : 0u); } g.line_size = g.w * 4; g.start_x = num6 * 4; g.start_y = num7 * g.line_size; g.max_x = g.start_x + num8 * 4; g.max_y = g.start_y + num9 * g.line_size; g.cur_x = g.start_x; g.cur_y = g.start_y; if (num8 == 0) { g.cur_y = g.max_y; } g.lflags = stbi__get8(s); if ((g.lflags & 0x40) != 0) { g.step = 8 * g.line_size; g.parse = 3; } else { g.step = g.line_size; g.parse = 0; } if ((g.lflags & 0x80) != 0) { stbi__gif_parse_colortable(s, g.lpal, 2 << (g.lflags & 7), ((g.eflags & 1) != 0) ? g.transparent : (-1)); g.color_table = g.lpal; } else { if ((g.flags & 0x80) == 0) { return (byte*)(int)((stbi__err("missing color table") != 0) ? 0u : 0u); } g.color_table = g.pal; } byte* ptr = stbi__process_gif_raster(s, g); if (ptr == null) { return null; } num4 = g.w * g.h; if (num2 != 0 && g.bgindex > 0) { for (num3 = 0; num3 < num4; num3++) { if (g.history[num3] == 0) { g.pal[g.bgindex][3] = byte.MaxValue; fixed (byte* b = &g.pal[g.bgindex][0]) { CRuntime.memcpy(g._out_ + num3 * 4, b, 4uL); } } } } return ptr; } case 33: { int num5 = 0; if (stbi__get8(s) == 249) { num5 = stbi__get8(s); if (num5 != 4) { stbi__skip(s, num5); break; } g.eflags = stbi__get8(s); g.delay = 10 * stbi__get16le(s); if (g.transparent >= 0) { g.pal[g.transparent][3] = byte.MaxValue; } if ((g.eflags & 1) != 0) { g.transparent = stbi__get8(s); if (g.transparent >= 0) { g.pal[g.transparent][3] = 0; } } else { stbi__skip(s, 1); g.transparent = -1; } } while ((num5 = stbi__get8(s)) != 0) { stbi__skip(s, num5); } break; } case 59: return null; default: return (byte*)(int)((stbi__err("unknown code") != 0) ? 0u : 0u); } } } public unsafe static void* stbi__load_gif_main_outofmem(stbi__gif g, byte* _out_, int** delays) { CRuntime.free(g._out_); CRuntime.free(g.history); CRuntime.free(g.background); if (_out_ != null) { CRuntime.free(_out_); } if (delays != null && *delays != null) { CRuntime.free(*delays); } return (void*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } public static int stbi__hdr_test(stbi__context s) { int num = stbi__hdr_test_core(s, "#?RADIANCE\n"); stbi__rewind(s); if (num == 0) { num = stbi__hdr_test_core(s, "#?RGBE\n"); stbi__rewind(s); } return num; } public unsafe static float* stbi__hdr_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) { byte* ptr = stackalloc byte[4]; sbyte* buffer = stackalloc sbyte[1024]; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; byte b = 0; byte b2 = 0; int i = 0; int j = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; sbyte* src = stbi__hdr_gettoken(s, buffer); if (CRuntime.strcmp(src, "#?RADIANCE") != 0 && CRuntime.strcmp(src, "#?RGBE") != 0) { return (float*)(int)((stbi__err("not HDR") != 0) ? 0u : 0u); } sbyte* ptr2; while (true) { ptr2 = stbi__hdr_gettoken(s, buffer); if (*ptr2 == 0) { break; } if (CRuntime.strcmp(ptr2, "FORMAT=32-bit_rle_rgbe") == 0) { num = 1; } } if (num == 0) { return (float*)(int)((stbi__err("unsupported format") != 0) ? 0u : 0u); } ptr2 = stbi__hdr_gettoken(s, buffer); if (CRuntime.strncmp(ptr2, "-Y ", 3uL) != 0) { return (float*)(int)((stbi__err("unsupported data layout") != 0) ? 0u : 0u); } ptr2 += 3; num3 = (int)CRuntime.strtol(ptr2, &ptr2, 10); for (; *ptr2 == 32; ptr2++) { } if (CRuntime.strncmp(ptr2, "+X ", 3uL) != 0) { return (float*)(int)((stbi__err("unsupported data layout") != 0) ? 0u : 0u); } ptr2 += 3; num2 = (int)CRuntime.strtol(ptr2, null, 10); if (num3 > 16777216) { return (float*)(int)((stbi__err("too large") != 0) ? 0u : 0u); } if (num2 > 16777216) { return (float*)(int)((stbi__err("too large") != 0) ? 0u : 0u); } *x = num2; *y = num3; if (comp != null) { *comp = 3; } if (req_comp == 0) { req_comp = 3; } if (stbi__mad4sizes_valid(num2, num3, req_comp, 4, 0) == 0) { return (float*)(int)((stbi__err("too large") != 0) ? 0u : 0u); } float* ptr3 = (float*)stbi__malloc_mad4(num2, num3, req_comp, 4, 0); if (ptr3 == null) { return (float*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } if (num2 < 8 || num2 >= 32768) { for (; j < num3; j++) { for (; i < num2; i++) { stbi__getn(s, ptr, 4); stbi__hdr_convert(ptr3 + j * num2 * req_comp + i * req_comp, ptr, req_comp); } } } else { byte* ptr4 = null; j = 0; while (true) { if (j < num3) { num6 = stbi__get8(s); num7 = stbi__get8(s); num4 = stbi__get8(s); if (num6 != 2 || num7 != 2 || (num4 & 0x80) != 0) { *ptr = (byte)num6; ptr[1] = (byte)num7; ptr[2] = (byte)num4; ptr[3] = stbi__get8(s); stbi__hdr_convert(ptr3, ptr, req_comp); CRuntime.free(ptr4); j = 0; for (i = 1; i < num2; i++) { stbi__getn(s, ptr, 4); stbi__hdr_convert(ptr3 + j * num2 * req_comp + i * req_comp, ptr, req_comp); } for (j = 1; j < num3; j++) { for (i = 0; i < num2; i++) { stbi__getn(s, ptr, 4); stbi__hdr_convert(ptr3 + j * num2 * req_comp + i * req_comp, ptr, req_comp); } } break; } num4 <<= 8; num4 |= stbi__get8(s); if (num4 != num2) { CRuntime.free(ptr3); CRuntime.free(ptr4); return (float*)(int)((stbi__err("invalid decoded scanline length") != 0) ? 0u : 0u); } if (ptr4 == null) { ptr4 = (byte*)stbi__malloc_mad2(num2, 4, 0); if (ptr4 == null) { CRuntime.free(ptr3); return (float*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } } for (num5 = 0; num5 < 4; num5++) { int num9 = 0; i = 0; while ((num9 = num2 - i) > 0) { b = stbi__get8(s); if (b > 128) { b2 = stbi__get8(s); b -= 128; if (b == 0 || b > num9) { CRuntime.free(ptr3); CRuntime.free(ptr4); return (float*)(int)((stbi__err("corrupt") != 0) ? 0u : 0u); } for (num8 = 0; num8 < b; num8++) { ptr4[i++ * 4 + num5] = b2; } } else { if (b == 0 || b > num9) { CRuntime.free(ptr3); CRuntime.free(ptr4); return (float*)(int)((stbi__err("corrupt") != 0) ? 0u : 0u); } for (num8 = 0; num8 < b; num8++) { ptr4[i++ * 4 + num5] = stbi__get8(s); } } } } for (i = 0; i < num2; i++) { stbi__hdr_convert(ptr3 + (j * num2 + i) * req_comp, ptr4 + i * 4, req_comp); } j++; continue; } if (ptr4 != null) { CRuntime.free(ptr4); } break; } } return ptr3; } public unsafe static int stbi__hdr_info(stbi__context s, int* x, int* y, int* comp) { sbyte* buffer = stackalloc sbyte[1024]; int num = 0; int num2 = 0; if (x == null) { x = &num2; } if (y == null) { y = &num2; } if (comp == null) { comp = &num2; } if (stbi__hdr_test(s) == 0) { stbi__rewind(s); return 0; } sbyte* ptr; while (true) { ptr = stbi__hdr_gettoken(s, buffer); if (*ptr == 0) { break; } if (CRuntime.strcmp(ptr, "FORMAT=32-bit_rle_rgbe") == 0) { num = 1; } } if (num == 0) { stbi__rewind(s); return 0; } ptr = stbi__hdr_gettoken(s, buffer); if (CRuntime.strncmp(ptr, "-Y ", 3uL) != 0) { stbi__rewind(s); return 0; } ptr += 3; *y = (int)CRuntime.strtol(ptr, &ptr, 10); for (; *ptr == 32; ptr++) { } if (CRuntime.strncmp(ptr, "+X ", 3uL) != 0) { stbi__rewind(s); return 0; } ptr += 3; *x = (int)CRuntime.strtol(ptr, null, 10); *comp = 3; return 1; } public unsafe static byte* stbi__hdr_to_ldr(float* data, int x, int y, int comp) { int num = 0; int num2 = 0; int num3 = 0; if (data == null) { return null; } byte* ptr = (byte*)stbi__malloc_mad3(x, y, comp, 0); if (ptr == null) { CRuntime.free(data); return (byte*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } num3 = (((comp & 1) == 0) ? (comp - 1) : comp); for (num = 0; num < x * y; num++) { for (num2 = 0; num2 < num3; num2++) { float num4 = (float)CRuntime.pow(data[num * comp + num2] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255f + 0.5f; if (num4 < 0f) { num4 = 0f; } if (num4 > 255f) { num4 = 255f; } ptr[num * comp + num2] = (byte)(int)num4; } if (num2 < comp) { float num5 = data[num * comp + num2] * 255f + 0.5f; if (num5 < 0f) { num5 = 0f; } if (num5 > 255f) { num5 = 255f; } ptr[num * comp + num2] = (byte)(int)num5; } } CRuntime.free(data); return ptr; } public static int stbi__hdr_test_core(stbi__context s, string signature) { int num = 0; for (num = 0; num < signature.Length; num++) { if (stbi__get8(s) != signature[num]) { return 0; } } stbi__rewind(s); return 1; } public unsafe static sbyte* stbi__hdr_gettoken(stbi__context z, sbyte* buffer) { int num = 0; sbyte b = 0; b = (sbyte)stbi__get8(z); while (stbi__at_eof(z) == 0 && b != 10) { buffer[num++] = b; if (num == 1023) { while (stbi__at_eof(z) == 0 && stbi__get8(z) != 10) { } break; } b = (sbyte)stbi__get8(z); } buffer[num] = 0; return buffer; } public unsafe static void stbi__hdr_convert(float* output, byte* input, int req_comp) { if (input[3] != 0) { float num = 0f; num = (float)CRuntime.ldexp(1.0, input[3] - 136); if (req_comp <= 2) { *output = (float)(*input + input[1] + input[2]) * num / 3f; } else { *output = (float)(int)(*input) * num; output[1] = (float)(int)input[1] * num; output[2] = (float)(int)input[2] * num; } if (req_comp == 2) { output[1] = 1f; } if (req_comp == 4) { output[3] = 1f; } } else if ((uint)(req_comp - 1) > 1u) { switch (req_comp) { case 4: output[3] = 1f; break; case 3: break; default: return; } *output = (output[1] = (output[2] = 0f)); } else { if (req_comp == 2) { output[1] = 1f; } *output = 0f; } } public static int stbi__jpeg_test(stbi__context s) { stbi__jpeg stbi__jpeg = new stbi__jpeg(); if (stbi__jpeg == null) { return stbi__err("outofmem"); } stbi__jpeg.s = s; stbi__setup_jpeg(stbi__jpeg); int result = stbi__decode_jpeg_header(stbi__jpeg, 1); stbi__rewind(s); return result; } public unsafe static void* stbi__jpeg_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) { stbi__jpeg stbi__jpeg = new stbi__jpeg(); if (stbi__jpeg == null) { return (void*)(int)((stbi__err("outofmem") != 0) ? 0u : 0u); } stbi__jpeg.s = s; stbi__setup_jpeg(stbi__jpeg); return load_jpeg_image(stbi__jpeg, x, y, comp, req_comp); } public unsafe static int stbi__jpeg_info(stbi__context s, int* x, int* y, int* comp) { stbi__jpeg stbi__jpeg = new stbi__jpeg(); if (stbi__jpeg == null) { return stbi__err("outofmem"); } stbi__jpeg.s = s; return stbi__jpeg_info_raw(stbi__jpeg, x, y, comp); } public unsafe static int stbi__build_huffman(stbi__huffman* h, int* count) { int num = 0; int num2 = 0; int num3 = 0; uint num4 = 0u; for (num = 0; num < 16; num++) { for (num2 = 0; num2 < count[num]; num2++) { h->size[num3++] = (byte)(num + 1); if (num3 >= 257) { return stbi__err("bad size list"); } } } h->size[num3] = 0; num4 = 0u; num3 = 0; for (num2 = 1; num2 <= 16; num2++) { h->delta[num2] = (int)(num3 - num4); if (h->size[num3] == num2) { while (h->size[num3] == num2) { h->code[num3++] = (ushort)num4++; } if (num4 - 1 >= (uint)(1 << num2)) { return stbi__err("bad code lengths"); } } h->maxcode[num2] = num4 << 16 - num2; num4 <<= 1; } h->maxcode[num2] = uint.MaxValue; CRuntime.memset(h->fast, 255, 512uL); for (num = 0; num < num3; num++) { int num5 = h->size[num]; if (num5 <= 9) { int num6 = h->code[num] << 9 - num5; int num7 = 1 << 9 - num5; for (num2 = 0; num2 < num7; num2++) { h->fast[num6 + num2] = (byte)num; } } } return 1; } public unsafe static void stbi__build_fast_ac(short[] fast_ac, stbi__huffman* h) { int num = 0; for (num = 0; num < 512; num++) { byte b = h->fast[num]; fast_ac[num] = 0; if (b >= byte.MaxValue) { continue; } byte num2 = h->values[(int)b]; int num3 = (num2 >> 4) & 0xF; int num4 = num2 & 0xF; int num5 = h->size[(int)b]; if (num4 != 0 && num5 + num4 <= 9) { int num6 = ((num << num5) & 0x1FF) >> 9 - num4; int num7 = 1 << num4 - 1; if (num6 < num7) { num6 += (-1 << num4) + 1; } if (num6 >= -128 && num6 <= 127) { fast_ac[num] = (short)(num6 * 256 + num3 * 16 + num5 + num4); } } } } public static void stbi__grow_buffer_unsafe(stbi__jpeg j) { do { uint num = (uint)((j.nomore == 0) ? stbi__get8(j.s) : 0); if (num == 255) { int num2 = stbi__get8(j.s); while (true) { switch (num2) { case 255: goto IL_002d; default: j.marker = (byte)num2; j.nomore = 1; return; case 0: break; } break; IL_002d: num2 = stbi__get8(j.s); } } j.code_buffer |= num << 24 - j.code_bits; j.code_bits += 8; } while (j.code_bits <= 24); } public unsafe static int stbi__jpeg_huff_decode(stbi__jpeg j, stbi__huffman* h) { uint num = 0u; int num2 = 0; int num3 = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } num2 = (int)((j.code_buffer >> 23) & 0x1FF); num3 = h->fast[num2]; if (num3 < 255) { int num4 = h->size[num3]; if (num4 > j.code_bits) { return -1; } j.code_buffer <<= num4; j.code_bits -= num4; return h->values[num3]; } num = j.code_buffer >> 16; for (num3 = 10; num >= h->maxcode[num3]; num3++) { } if (num3 == 17) { j.code_bits -= 16; return -1; } if (num3 > j.code_bits) { return -1; } num2 = (int)(((j.code_buffer >> 32 - num3) & stbi__bmask[num3]) + h->delta[num3]); if (num2 < 0 || num2 >= 256) { return -1; } j.code_bits -= num3; j.code_buffer <<= num3; return h->values[num2]; } public static int stbi__extend_receive(stbi__jpeg j, int n) { uint num = 0u; int num2 = 0; if (j.code_bits < n) { stbi__grow_buffer_unsafe(j); } if (j.code_bits < n) { return 0; } num2 = (int)(j.code_buffer >> 31); num = CRuntime._lrotl(j.code_buffer, n); j.code_buffer = num & ~stbi__bmask[n]; num &= stbi__bmask[n]; j.code_bits -= n; return (int)(num + (stbi__jbias[n] & (num2 - 1))); } public static int stbi__jpeg_get_bits(stbi__jpeg j, int n) { uint num = 0u; if (j.code_bits < n) { stbi__grow_buffer_unsafe(j); } if (j.code_bits < n) { return 0; } num = CRuntime._lrotl(j.code_buffer, n); j.code_buffer = num & ~stbi__bmask[n]; num &= stbi__bmask[n]; j.code_bits -= n; return (int)num; } public static int stbi__jpeg_get_bit(stbi__jpeg j) { if (j.code_bits < 1) { stbi__grow_buffer_unsafe(j); } if (j.code_bits < 1) { return 0; } uint code_buffer = j.code_buffer; j.code_buffer <<= 1; j.code_bits--; return (int)code_buffer & int.MinValue; } public unsafe static int stbi__jpeg_decode_block(stbi__jpeg j, short* data, stbi__huffman* hdc, stbi__huffman* hac, short[] fac, int b, ushort[] dequant) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } num4 = stbi__jpeg_huff_decode(j, hdc); if (num4 < 0 || num4 > 15) { return stbi__err("bad huffman code"); } CRuntime.memset(data, 0, 128uL); num = ((num4 != 0) ? stbi__extend_receive(j, num4) : 0); if (stbi__addints_valid(j.img_comp[b].dc_pred, num) == 0) { return stbi__err("bad delta"); } num2 = j.img_comp[b].dc_pred + num; j.img_comp[b].dc_pred = num2; if (stbi__mul2shorts_valid(num2, dequant[0]) == 0) { return stbi__err("can't merge dc and ac"); } *data = (short)(num2 * dequant[0]); num3 = 1; do { uint num5 = 0u; int num6 = 0; int num7 = 0; int num8 = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } num6 = (int)((j.code_buffer >> 23) & 0x1FF); num7 = fac[num6]; if (num7 != 0) { num3 += (num7 >> 4) & 0xF; num8 = num7 & 0xF; if (num8 > j.code_bits) { return stbi__err("bad huffman code"); } j.code_buffer <<= num8; j.code_bits -= num8; num5 = stbi__jpeg_dezigzag[num3++]; data[num5] = (short)((num7 >> 8) * dequant[num5]); continue; } int num9 = stbi__jpeg_huff_decode(j, hac); if (num9 < 0) { return stbi__err("bad huffman code"); } num8 = num9 & 0xF; num7 = num9 >> 4; if (num8 == 0) { if (num9 != 240) { break; } num3 += 16; } else { num3 += num7; num5 = stbi__jpeg_dezigzag[num3++]; data[num5] = (short)(stbi__extend_receive(j, num8) * dequant[num5]); } } while (num3 < 64); return 1; } public unsafe static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg j, short* data, stbi__huffman* hdc, int b) { int num = 0; int num2 = 0; int num3 = 0; if (j.spec_end != 0) { return stbi__err("can't merge dc and ac"); } if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } if (j.succ_high == 0) { CRuntime.memset(data, 0, 128uL); num3 = stbi__jpeg_huff_decode(j, hdc); int num4; switch (num3) { default: return stbi__err("can't merge dc and ac"); case 0: num4 = 0; break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: num4 = stbi__extend_receive(j, num3); break; } num = num4; if (stbi__addints_valid(j.img_comp[b].dc_pred, num) == 0) { return stbi__err("bad delta"); } num2 = j.img_comp[b].dc_pred + num; j.img_comp[b].dc_pred = num2; if (stbi__mul2shorts_valid(num2, 1 << j.succ_low) == 0) { return stbi__err("can't merge dc and ac"); } *data = (short)(num2 * (1 << j.succ_low)); } else if (stbi__jpeg_get_bit(j) != 0) { *data += (short)(1 << j.succ_low); } return 1; } public unsafe static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg j, short* data, stbi__huffman* hac, short[] fac) { int num = 0; if (j.spec_start == 0) { return stbi__err("can't merge dc and ac"); } if (j.succ_high == 0) { int succ_low = j.succ_low; if (j.eob_run != 0) { j.eob_run--; return 1; } num = j.spec_start; do { uint num2 = 0u; int num3 = 0; int num4 = 0; int num5 = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } num3 = (int)((j.code_buffer >> 23) & 0x1FF); num4 = fac[num3]; if (num4 != 0) { num += (num4 >> 4) & 0xF; num5 = num4 & 0xF; if (num5 > j.code_bits) { return stbi__err("bad huffman code"); } j.code_buffer <<= num5; j.code_bits -= num5; num2 = stbi__jpeg_dezigzag[num++]; data[num2] = (short)((num4 >> 8) * (1 << succ_low)); continue; } int num6 = stbi__jpeg_huff_decode(j, hac); if (num6 < 0) { return stbi__err("bad huffman code"); } num5 = num6 & 0xF; num4 = num6 >> 4; if (num5 == 0) { if (num4 < 15) { j.eob_run = 1 << num4; if (num4 != 0) { j.eob_run += stbi__jpeg_get_bits(j, num4); } j.eob_run--; break; } num += 16; } else { num += num4; num2 = stbi__jpeg_dezigzag[num++]; data[num2] = (short)(stbi__extend_receive(j, num5) * (1 << succ_low)); } } while (num <= j.spec_end); } else { short num7 = (short)(1 << j.succ_low); if (j.eob_run != 0) { j.eob_run--; for (num = j.spec_start; num <= j.spec_end; num++) { short* ptr = data + (int)stbi__jpeg_dezigzag[num]; if (*ptr != 0 && stbi__jpeg_get_bit(j) != 0 && (*ptr & num7) == 0) { if (*ptr > 0) { *ptr += num7; } else { *ptr -= num7; } } } } else { num = j.spec_start; do { int num8 = 0; int num9 = 0; int num10 = stbi__jpeg_huff_decode(j, hac); if (num10 < 0) { return stbi__err("bad huffman code"); } num9 = num10 & 0xF; num8 = num10 >> 4; switch (num9) { case 0: if (num8 < 15) { j.eob_run = (1 << num8) - 1; if (num8 != 0) { j.eob_run += stbi__jpeg_get_bits(j, num8); } num8 = 64; } break; default: return stbi__err("bad huffman code"); case 1: num9 = ((stbi__jpeg_get_bit(j) == 0) ? (-num7) : num7); break; } while (num <= j.spec_end) { short* ptr2 = data + (int)stbi__jpeg_dezigzag[num++]; if (*ptr2 != 0) { if (stbi__jpeg_get_bit(j) != 0 && (*ptr2 & num7) == 0) { if (*ptr2 > 0) { *ptr2 += num7; } else { *ptr2 -= num7; } } } else { if (num8 == 0) { *ptr2 = (short)num9; break; } num8--; } } } while (num <= j.spec_end); } } return 1; } public unsafe static void stbi__idct_block(byte* _out_, int out_stride, short* data) { int num = 0; int* ptr = stackalloc int[64]; int* ptr2 = ptr; short* ptr3 = data; num = 0; while (num < 8) { if (ptr3[8] == 0 && ptr3[16] == 0 && ptr3[24] == 0 && ptr3[32] == 0 && ptr3[40] == 0 && ptr3[48] == 0 && ptr3[56] == 0) { int num2 = *ptr3 * 4; *ptr2 = (ptr2[8] = (ptr2[16] = (ptr2[24] = (ptr2[32] = (ptr2[40] = (ptr2[48] = (ptr2[56] = num2))))))); } else { int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int num10 = 0; int num11 = 0; int num12 = 0; int num13 = 0; int num14 = 0; num8 = ptr3[16]; num9 = ptr3[48]; num7 = (num8 + num9) * 2217; num5 = num7 + num9 * -7567; num6 = num7 + num8 * 3135; num8 = *ptr3; num9 = ptr3[32]; num3 = (num8 + num9) * 4096; num4 = (num8 - num9) * 4096; num11 = num3 + num6; num14 = num3 - num6; num12 = num4 + num5; num13 = num4 - num5; num3 = ptr3[56]; num4 = ptr3[40]; num5 = ptr3[24]; num6 = ptr3[8]; num9 = num3 + num5; num10 = num4 + num6; num7 = num3 + num6; num8 = num4 + num5; int num15 = (num9 + num10) * 4816; num3 *= 1223; num4 *= 8410; num5 *= 12586; num6 *= 6149; num7 = num15 + num7 * -3685; num8 = num15 + num8 * -10497; num9 *= -8034; num10 *= -1597; num6 += num7 + num10; num5 += num8 + num9; num4 += num8 + num10; num3 += num7 + num9; num11 += 512; num12 += 512; num13 += 512; num14 += 512; *ptr2 = num11 + num6 >> 10; ptr2[56] = num11 - num6 >> 10; ptr2[8] = num12 + num5 >> 10; ptr2[48] = num12 - num5 >> 10; ptr2[16] = num13 + num4 >> 10; ptr2[40] = num13 - num4 >> 10; ptr2[24] = num14 + num3 >> 10; ptr2[32] = num14 - num3 >> 10; } num++; ptr3++; ptr2++; } num = 0; ptr2 = ptr; byte* ptr4 = _out_; while (num < 8) { int num16 = 0; int num17 = 0; int num18 = 0; int num19 = 0; int num20 = 0; int num21 = 0; int num22 = 0; int num23 = 0; int num24 = 0; int num25 = 0; int num26 = 0; int num27 = 0; num21 = ptr2[2]; num22 = ptr2[6]; num20 = (num21 + num22) * 2217; num18 = num20 + num22 * -7567; num19 = num20 + num21 * 3135; num21 = *ptr2; num22 = ptr2[4]; num16 = (num21 + num22) * 4096; num17 = (num21 - num22) * 4096; num24 = num16 + num19; num27 = num16 - num19; num25 = num17 + num18; num26 = num17 - num18; num16 = ptr2[7]; num17 = ptr2[5]; num18 = ptr2[3]; num19 = ptr2[1]; num22 = num16 + num18; num23 = num17 + num19; num20 = num16 + num19; num21 = num17 + num18; int num28 = (num22 + num23) * 4816; num16 *= 1223; num17 *= 8410; num18 *= 12586; num19 *= 6149; num20 = num28 + num20 * -3685; num21 = num28 + num21 * -10497; num22 *= -8034; num23 *= -1597; num19 += num20 + num23; num18 += num21 + num22; num17 += num21 + num23; num16 += num20 + num22; num24 += 16842752; num25 += 16842752; num26 += 16842752; num27 += 16842752; *ptr4 = stbi__clamp(num24 + num19 >> 17); ptr4[7] = stbi__clamp(num24 - num19 >> 17); ptr4[1] = stbi__clamp(num25 + num18 >> 17); ptr4[6] = stbi__clamp(num25 - num18 >> 17); ptr4[2] = stbi__clamp(num26 + num17 >> 17); ptr4[5] = stbi__clamp(num26 - num17 >> 17); ptr4[3] = stbi__clamp(num27 + num16 >> 17); ptr4[4] = stbi__clamp(num27 - num16 >> 17); num++; ptr2 += 8; ptr4 += out_stride; } } public static byte stbi__get_marker(stbi__jpeg j) { byte b = 0; if (j.marker != byte.MaxValue) { b = j.marker; j.marker = byte.MaxValue; return b; } b = stbi__get8(j.s); if (b != byte.MaxValue) { return byte.MaxValue; } while (b == byte.MaxValue) { b = stbi__get8(j.s); } return b; } public static void stbi__jpeg_reset(stbi__jpeg j) { j.code_bits = 0; j.code_buffer = 0u; j.nomore = 0; j.img_comp[0].dc_pred = (j.img_comp[1].dc_pred = (j.img_comp[2].dc_pred = (j.img_comp[3].dc_pred = 0))); j.marker = byte.MaxValue; j.todo = ((j.restart_interval != 0) ? j.restart_interval : int.MaxValue); j.eob_run = 0; } public unsafe static int stbi__parse_entropy_coded_data(stbi__jpeg z) { stbi__jpeg_reset(z); if (z.progressive == 0) { if (z.scan_n == 1) { int num = 0; int num2 = 0; short* ptr = stackalloc short[64]; int num3 = z.order[0]; int num4 = z.img_comp[num3].x + 7 >> 3; int num5 = z.img_comp[num3].y + 7 >> 3; for (num2 = 0; num2 < num5; num2++) { for (num = 0; num < num4; num++) { int ha = z.img_comp[num3].ha; fixed (stbi__huffman* hdc = &z.huff_dc[z.img_comp[num3].hd]) { fixed (stbi__huffman* hac = &z.huff_ac[ha]) { if (stbi__jpeg_decode_block(z, ptr, hdc, hac, z.fast_ac[ha], num3, z.dequant[z.img_comp[num3].tq]) == 0) { return 0; } } } z.idct_block_kernel(z.img_comp[num3].data + z.img_comp[num3].w2 * num2 * 8 + num * 8, z.img_comp[num3].w2, ptr); if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (z.marker < 208 || z.marker > 215) { return 1; } stbi__jpeg_reset(z); } } } return 1; } int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int num10 = 0; short* ptr2 = stackalloc short[64]; for (num7 = 0; num7 < z.img_mcu_y; num7++) { for (num6 = 0; num6 < z.img_mcu_x; num6++) { for (num8 = 0; num8 < z.scan_n; num8++) { int num11 = z.order[num8]; for (num10 = 0; num10 < z.img_comp[num11].v; num10++) { for (num9 = 0; num9 < z.img_comp[num11].h; num9++) { int num12 = (num6 * z.img_comp[num11].h + num9) * 8; int num13 = (num7 * z.img_comp[num11].v + num10) * 8; int ha2 = z.img_comp[num11].ha; fixed (stbi__huffman* hdc2 = &z.huff_dc[z.img_comp[num11].hd]) { fixed (stbi__huffman* hac2 = &z.huff_ac[ha2]) { if (stbi__jpeg_decode_block(z, ptr2, hdc2, hac2, z.fast_ac[ha2], num11, z.dequant[z.img_comp[num11].tq]) == 0) { return 0; } } } z.idct_block_kernel(z.img_comp[num11].data + z.img_comp[num11].w2 * num13 + num12, z.img_comp[num11].w2, ptr2); } } } if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (z.marker < 208 || z.marker > 215) { return 1; } stbi__jpeg_reset(z); } } } return 1; } if (z.scan_n == 1) { int num14 = 0; int num15 = 0; int num16 = z.order[0]; int num17 = z.img_comp[num16].x + 7 >> 3; int num18 = z.img_comp[num16].y + 7 >> 3; for (num15 = 0; num15 < num18; num15++) { for (num14 = 0; num14 < num17; num14++) { short* data = z.img_comp[num16].coeff + 64 * (num14 + num15 * z.img_comp[num16].coeff_w); if (z.spec_start == 0) { fixed (stbi__huffman* hdc3 = &z.huff_dc[z.img_comp[num16].hd]) { if (stbi__jpeg_decode_block_prog_dc(z, data, hdc3, num16) == 0) { return 0; } } } else { int ha3 = z.img_comp[num16].ha; fixed (stbi__huffman* hac3 = &z.huff_ac[ha3]) { if (stbi__jpeg_decode_block_prog_ac(z, data, hac3, z.fast_ac[ha3]) == 0) { return 0; } } } if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (z.marker < 208 || z.marker > 215) { return 1; } stbi__jpeg_reset(z); } } } return 1; } int num19 = 0; int num20 = 0; int num21 = 0; int num22 = 0; int num23 = 0; for (num20 = 0; num20 < z.img_mcu_y; num20++) { for (num19 = 0; num19 < z.img_mcu_x; num19++) { for (num21 = 0; num21 < z.scan_n; num21++) { int num24 = z.order[num21]; for (num23 = 0; num23 < z.img_comp[num24].v; num23++) { for (num22 = 0; num22 < z.img_comp[num24].h; num22++) { int num25 = num19 * z.img_comp[num24].h + num22; int num26 = num20 * z.img_comp[num24].v + num23; short* data2 = z.img_comp[num24].coeff + 64 * (num25 + num26 * z.img_comp[num24].coeff_w); fixed (stbi__huffman* hdc4 = &z.huff_dc[z.img_comp[num24].hd]) { if (stbi__jpeg_decode_block_prog_dc(z, data2, hdc4, num24) == 0) { return 0; } } } } } if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (z.marker < 208 || z.marker > 215) { return 1; } stbi__jpeg_reset(z); } } } return 1; } public unsafe static void stbi__jpeg_dequantize(short* data, ushort[] dequant) { int num = 0; for (num = 0; num < 64; num++) { data[num] *= (short)dequant[num]; } } public unsafe static void stbi__jpeg_finish(stbi__jpeg z) { if (z.progressive == 0) { return; } int num = 0; int num2 = 0; int num3 = 0; for (num3 = 0; num3 < z.s.img_n; num3++) { int num4 = z.img_comp[num3].x + 7 >> 3; int num5 = z.img_comp[num3].y + 7 >> 3; for (num2 = 0; num2 < num5; num2++) { for (num = 0; num < num4; num++) { short* ptr = z.img_comp[num3].coeff + 64 * (num + num2 * z.img_comp[num3].coeff_w); stbi__jpeg_dequantize(ptr, z.dequant[z.img_comp[num3].tq]); z.idct_block_kernel(z.img_comp[num3].data + z.img_comp[num3].w2 * num2 * 8 + num * 8, z.img_comp[num3].w2, ptr); } } } } public unsafe static int stbi__process_marker(stbi__jpeg z, int m) { int num = 0; switch (m) { case 255: return stbi__err("expected marker"); case 221: if (stbi__get16be(z.s) != 4) { return stbi__err("bad DRI len"); } z.restart_interval = stbi__get16be(z.s); return 1; case 219: num = stbi__get16be(z.s) - 2; while (num > 0) { byte num11 = stbi__get8(z.s); int num12 = num11 >> 4; int num13 = ((num12 != 0) ? 1 : 0); int num14 = num11 & 0xF; int num15 = 0; if (num12 != 0 && num12 != 1) { return stbi__err("bad DQT type"); } if (num14 > 3) { return stbi__err("bad DQT table"); } for (num15 = 0; num15 < 64; num15++) { z.dequant[num14][stbi__jpeg_dezigzag[num15]] = (ushort)((num13 != 0) ? stbi__get16be(z.s) : stbi__get8(z.s)); } num -= ((num13 != 0) ? 129 : 65); } return (num == 0) ? 1 : 0; case 196: { num = stbi__get16be(z.s) - 2; int* ptr = stackalloc int[16]; while (num > 0) { int num6 = 0; int num7 = 0; byte num8 = stbi__get8(z.s); int num9 = num8 >> 4; int num10 = num8 & 0xF; if (num9 > 1 || num10 > 3) { return stbi__err("bad DHT header"); } for (num6 = 0; num6 < 16; num6++) { ptr[num6] = stbi__get8(z.s); num7 += ptr[num6]; } if (num7 > 256) { return stbi__err("bad DHT header"); } num -= 17; if (num9 == 0) { fixed (stbi__huffman* ptr2 = &z.huff_dc[num10]) { if (stbi__build_huffman(ptr2, ptr) == 0) { return 0; } byte* ptr3 = ptr2->values; for (num6 = 0; num6 < num7; num6++) { ptr3[num6] = stbi__get8(z.s); } } } else { fixed (stbi__huffman* ptr4 = &z.huff_ac[num10]) { if (stbi__build_huffman(ptr4, ptr) == 0) { return 0; } byte* ptr5 = ptr4->values; for (num6 = 0; num6 < num7; num6++) { ptr5[num6] = stbi__get8(z.s); } } } if (num9 != 0) { fixed (stbi__huffman* h = &z.huff_ac[num10]) { stbi__build_fast_ac(z.fast_ac[num10], h); } } num -= num7; } return (num == 0) ? 1 : 0; } default: if ((m >= 224 && m <= 239) || m == 254) { num = stbi__get16be(z.s); if (num < 2) { if (m == 254) { return stbi__err("bad COM len"); } return stbi__err("bad APP len"); } num -= 2; if (m == 224 && num >= 5) { int num2 = 1; int num3 = 0; for (num3 = 0; num3 < 5; num3++) { if (stbi__get8(z.s) != stbi__process_marker_tag[num3]) { num2 = 0; } } num -= 5; if (num2 != 0) { z.jfif = 1; } } else if (m == 238 && num >= 12) { int num4 = 1; int num5 = 0; for (num5 = 0; num5 < 6; num5++) { if (stbi__get8(z.s) != stbi__process_marker_tag[num5]) { num4 = 0; } } num -= 6; if (num4 != 0) { stbi__get8(z.s); stbi__get16be(z.s); stbi__get16be(z.s); z.app14_color_transform = stbi__get8(z.s); num -= 6; } } stbi__skip(z.s, num); return 1; } return stbi__err("unknown marker"); } } public static int stbi__process_scan_header(stbi__jpeg z) { int num = 0; int num2 = stbi__get16be(z.s); z.scan_n = stbi__get8(z.s); if (z.scan_n < 1 || z.scan_n > 4 || z.scan_n > z.s.img_n) { return stbi__err("bad SOS component count"); } if (num2 != 6 + 2 * z.scan_n) { return stbi__err("bad SOS len"); } for (num = 0; num < z.scan_n; num++) { int num3 = stbi__get8(z.s); int num4 = 0; int num5 = stbi__get8(z.s); for (num4 = 0; num4 < z.s.img_n && z.img_comp[num4].id != num3; num4++) { } if (num4 == z.s.img_n) { return 0; } z.img_comp[num4].hd = num5 >> 4; if (z.img_comp[num4].hd > 3) { return stbi__err("bad DC huff"); } z.img_comp[num4].ha = num5 & 0xF; if (z.img_comp[num4].ha > 3) { return stbi__err("bad AC huff"); } z.order[num] = num4; } int num6 = 0; z.spec_start = stbi__get8(z.s); z.spec_end = stbi__get8(z.s); num6 = stbi__get8(z.s); z.succ_high = num6 >> 4; z.succ_low = num6 & 0xF; if (z.progressive != 0) { if (z.spec_start > 63 || z.spec_end > 63 || z.spec_start > z.spec_end || z.succ_high > 13 || z.succ_low > 13) { return stbi__err("bad SOS"); } } else { if (z.spec_start != 0) { return stbi__err("bad SOS"); } if (z.succ_high != 0 || z.succ_low != 0) { return stbi__err("bad SOS"); } z.spec_end = 63; } return 1; } public unsafe static int stbi__free_jpeg_components(stbi__jpeg z, int ncomp, int why) { int num = 0; for (num = 0; num < ncomp; num++) { if (z.img_comp[num].raw_data != null) { CRuntime.free(z.img_comp[num].raw_data); z.img_comp[num].raw_data = null; z.img_comp[num].data = null; } if (z.img_comp[num].raw_coeff != null) { CRuntime.free(z.img_comp[num].raw_coeff); z.img_comp[num].raw_coeff = null; z.img_comp[num].coeff = null; } if (z.img_comp[num].linebuf != null) { CRuntime.free(z.img_comp[num].linebuf); z.img_comp[num].linebuf = null; } } return why; } public unsafe static int stbi__process_frame_header(stbi__jpeg z, int scan) { stbi__context s = z.s; int num = 0; int num2 = 0; int num3 = 0; int num4 = 1; int num5 = 1; int num6 = 0; num = stbi__get16be(s); if (num < 11) { return stbi__err("bad SOF len"); } if (stbi__get8(s) != 8) { return stbi__err("only 8-bit"); } s.img_y = (uint)stbi__get16be(s); if (s.img_y == 0) { return stbi__err("no header height"); } s.img_x = (uint)stbi__get16be(s); if (s.img_x == 0) { return stbi__err("0 width"); } if (s.img_y > 16777216) { return stbi__err("too large"); } if (s.img_x > 16777216) { return stbi__err("too large"); } num6 = stbi__get8(s); if (num6 != 3 && num6 != 1 && num6 != 4) { return stbi__err("bad component count"); } s.img_n = num6; for (num2 = 0; num2 < num6; num2++) { z.img_comp[num2].data = null; z.img_comp[num2].linebuf = null; } if (num != 8 + 3 * s.img_n) { return stbi__err("bad SOF len"); } z.rgb = 0; for (num2 = 0; num2 < s.img_n; num2++) { z.img_comp[num2].id = stbi__get8(s); if (s.img_n == 3 && z.img_comp[num2].id == stbi__process_frame_header_rgb[num2]) { z.rgb++; } num3 = stbi__get8(s); z.img_comp[num2].h = num3 >> 4; if (z.img_comp[num2].h == 0 || z.img_comp[num2].h > 4) { return stbi__err("bad H"); } z.img_comp[num2].v = num3 & 0xF; if (z.img_comp[num2].v == 0 || z.img_comp[num2].v > 4) { return stbi__err("bad V"); } z.img_comp[num2].tq = stbi__get8(s); if (z.img_comp[num2].tq > 3)