using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Windows.Forms; namespace AssetStudio { class Texture2D { public AssetPreloadData preloadData; public string m_Name; public int m_Width; public int m_Height; public int m_CompleteImageSize; public TextureFormat m_TextureFormat; public bool m_MipMap; public int m_MipCount; public bool m_IsReadable; public bool m_ReadAllowed; public int m_ImageCount; public int m_TextureDimension; //m_TextureSettings public int m_FilterMode; public int m_Aniso; public float m_MipBias; public int m_WrapMode; public int m_LightmapFormat; public int m_ColorSpace; //image dataa public int image_data_size; public byte[] image_data; //m_StreamData public uint offset; public uint size; public string path; public Texture2D(AssetPreloadData preloadData, bool readSwitch) { this.preloadData = preloadData; var sourceFile = preloadData.sourceFile; var reader = preloadData.InitReader(); var version = sourceFile.version; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = reader.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = reader.ReadAlignedString(); if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3))//2017.3 and up { var m_ForcedFallbackFormat = reader.ReadInt32(); var m_DownscaleFallback = reader.ReadBoolean(); reader.AlignStream(4); } m_Width = reader.ReadInt32(); m_Height = reader.ReadInt32(); m_CompleteImageSize = reader.ReadInt32(); m_TextureFormat = (TextureFormat)reader.ReadInt32(); if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) { m_MipMap = reader.ReadBoolean(); } else { m_MipCount = reader.ReadInt32(); } m_IsReadable = reader.ReadBoolean(); //2.6.0 and up m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4 reader.AlignStream(4); m_ImageCount = reader.ReadInt32(); m_TextureDimension = reader.ReadInt32(); //m_TextureSettings m_FilterMode = reader.ReadInt32(); m_Aniso = reader.ReadInt32(); m_MipBias = reader.ReadSingle(); if (version[0] >= 2017)//2017.x and up { int m_WrapU = reader.ReadInt32(); int m_WrapV = reader.ReadInt32(); int m_WrapW = reader.ReadInt32(); } else { m_WrapMode = reader.ReadInt32(); } if (version[0] >= 3) { m_LightmapFormat = reader.ReadInt32(); if (version[0] >= 4 || version[1] >= 5)//3.5.0 and up { m_ColorSpace = reader.ReadInt32(); } } image_data_size = reader.ReadInt32(); if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up { offset = reader.ReadUInt32(); size = reader.ReadUInt32(); image_data_size = (int)size; path = reader.ReadAlignedString(); } if (readSwitch) { if (!string.IsNullOrEmpty(path)) { var resourceFileName = Path.GetFileName(path); var resourceFilePath = Path.GetDirectoryName(sourceFile.filePath) + "\\" + resourceFileName; if (!File.Exists(resourceFilePath)) { var findFiles = Directory.GetFiles(Path.GetDirectoryName(sourceFile.filePath), resourceFileName, SearchOption.AllDirectories); if (findFiles.Length > 0) { resourceFilePath = findFiles[0]; } } if (File.Exists(resourceFilePath)) { using (var resourceReader = new BinaryReader(File.OpenRead(resourceFilePath))) { resourceReader.BaseStream.Position = offset; image_data = resourceReader.ReadBytes(image_data_size); } } else { if (Studio.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var resourceReader)) { resourceReader.Position = offset; image_data = resourceReader.ReadBytes(image_data_size); } else { MessageBox.Show($"can't find the resource file {resourceFileName}"); } } } else { image_data = reader.ReadBytes(image_data_size); } } else { preloadData.InfoText = $"Width: {m_Width}\nHeight: {m_Height}\nFormat: {m_TextureFormat}"; switch (m_FilterMode) { case 0: preloadData.InfoText += "\nFilter Mode: Point "; break; case 1: preloadData.InfoText += "\nFilter Mode: Bilinear "; break; case 2: preloadData.InfoText += "\nFilter Mode: Trilinear "; break; } preloadData.InfoText += $"\nAnisotropic level: {m_Aniso}\nMip map bias: {m_MipBias}"; switch (m_WrapMode) { case 0: preloadData.InfoText += "\nWrap mode: Repeat"; break; case 1: preloadData.InfoText += "\nWrap mode: Clamp"; break; } preloadData.Text = m_Name; if (!string.IsNullOrEmpty(path)) preloadData.fullSize = preloadData.Size + (int)size; } } } public enum TextureFormat { Alpha8 = 1, ARGB4444, RGB24, RGBA32, ARGB32, RGB565 = 7, R16 = 9, DXT1, DXT5 = 12, RGBA4444, BGRA32, RHalf, RGHalf, RGBAHalf, RFloat, RGFloat, RGBAFloat, YUY2, RGB9e5Float, BC4 = 26, BC5, BC6H = 24, BC7, DXT1Crunched = 28, DXT5Crunched, PVRTC_RGB2, PVRTC_RGBA2, PVRTC_RGB4, PVRTC_RGBA4, ETC_RGB4, ATC_RGB4, ATC_RGBA8, EAC_R = 41, EAC_R_SIGNED, EAC_RG, EAC_RG_SIGNED, ETC2_RGB, ETC2_RGBA1, ETC2_RGBA8, ASTC_RGB_4x4, ASTC_RGB_5x5, ASTC_RGB_6x6, ASTC_RGB_8x8, ASTC_RGB_10x10, ASTC_RGB_12x12, ASTC_RGBA_4x4, ASTC_RGBA_5x5, ASTC_RGBA_6x6, ASTC_RGBA_8x8, ASTC_RGBA_10x10, ASTC_RGBA_12x12, ETC_RGB4_3DS, ETC_RGBA8_3DS, RG16, R8, ETC_RGB4Crunched, ETC2_RGBA8Crunched, } }