using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using Toolbox.Library.IO; using Toolbox.Library.Forms; using System.Drawing; namespace Toolbox.Library { public class ASTC : STGenericTexture, IEditor, IFileFormat { public FileType FileType { get; set; } = FileType.Image; public override TEX_FORMAT[] SupportedFormats { get { return new TEX_FORMAT[] { TEX_FORMAT.ASTC_10x10_SRGB, TEX_FORMAT.ASTC_10x10_UNORM, TEX_FORMAT.ASTC_10x5_SRGB, TEX_FORMAT.ASTC_10x5_UNORM, TEX_FORMAT.ASTC_10x6_SRGB, TEX_FORMAT.ASTC_10x6_UNORM, TEX_FORMAT.ASTC_10x8_SRGB, TEX_FORMAT.ASTC_10x8_UNORM, TEX_FORMAT.ASTC_12x10_SRGB, TEX_FORMAT.ASTC_12x10_UNORM, TEX_FORMAT.ASTC_12x12_SRGB, TEX_FORMAT.ASTC_12x12_UNORM, TEX_FORMAT.ASTC_4x4_SRGB, TEX_FORMAT.ASTC_4x4_UNORM, TEX_FORMAT.ASTC_5x4_SRGB, TEX_FORMAT.ASTC_5x4_UNORM, TEX_FORMAT.ASTC_5x5_SRGB, TEX_FORMAT.ASTC_5x5_UNORM, TEX_FORMAT.ASTC_6x5_SRGB, TEX_FORMAT.ASTC_6x5_UNORM, TEX_FORMAT.ASTC_6x6_SRGB, TEX_FORMAT.ASTC_6x6_UNORM, TEX_FORMAT.ASTC_8x5_SRGB, TEX_FORMAT.ASTC_8x5_UNORM, TEX_FORMAT.ASTC_8x6_SRGB, TEX_FORMAT.ASTC_8x6_UNORM, TEX_FORMAT.ASTC_8x8_SRGB, TEX_FORMAT.ASTC_8x8_UNORM, }; } } const int MagicFileConstant = 0x5CA1AB13; public override bool CanEdit { get; set; } = false; public bool CanSave { get; set; } public string[] Description { get; set; } = new string[] { "Adaptive Scalable Texture" }; public string[] Extension { get; set; } = new string[] { "*.astc" }; public string FileName { get; set; } public string FilePath { get; set; } public IFileInfo IFileInfo { get; set; } public bool Identify(System.IO.Stream stream) { using (var reader = new Toolbox.Library.IO.FileReader(stream, true)) { return reader.ReadInt32() == MagicFileConstant; } } public Type[] Types { get { List types = new List(); return types.ToArray(); } } public ImageEditorBase OpenForm() { bool IsDialog = IFileInfo != null && IFileInfo.InArchive; ImageEditorBase form = new ImageEditorBase(); form.Text = Text; form.Dock = DockStyle.Fill; form.LoadImage(this); form.LoadProperties(GenericProperties); return form; } public void FillEditor(UserControl control) { ((ImageEditorBase)control).LoadImage(this); ((ImageEditorBase)control).LoadProperties(GenericProperties); } //https://github.com/ARM-software/astc-encoder/blob/a47b80f081f10c43d96bd10bcb713c71708041b9/Source/astc_toplevel.cpp public byte[] magic; public byte BlockDimX; public byte BlockDimY; public byte BlockDimZ; public byte[] xsize; public byte[] ysize; public byte[] zsize; public byte[] DataBlock; public void Load(System.IO.Stream stream) { using (FileReader reader = new FileReader(stream)) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; magic = reader.ReadBytes(4); uint magicval = magic[0] + 256 * (uint)(magic[1]) + 65536 * (uint)(magic[2]) + 16777216 * (uint)(magic[3]); if (magicval != MagicFileConstant) throw new Exception("Invalid identifier"); BlockDimX = reader.ReadByte(); BlockDimY = reader.ReadByte(); BlockDimZ = reader.ReadByte(); xsize = reader.ReadBytes(3); ysize = reader.ReadBytes(3); zsize = reader.ReadBytes(3); Width = (uint)(xsize[0] + 256 * xsize[1] + 65536 * xsize[2]); Height = (uint)(ysize[0] + 256 * ysize[1] + 65536 * ysize[2]); Depth = (uint)(zsize[0] + 256 * zsize[1] + 65536 * zsize[2]); reader.Seek(0x10, System.IO.SeekOrigin.Begin); DataBlock = reader.ReadBytes((int)(reader.BaseStream.Length - reader.Position)); Console.WriteLine(Width); Console.WriteLine(Height); Console.WriteLine(Depth); if (BlockDimX == 4 && BlockDimY == 4) Format = TEX_FORMAT.ASTC_4x4_UNORM; else if (BlockDimX == 5 && BlockDimY == 4) Format = TEX_FORMAT.ASTC_5x4_UNORM; else if (BlockDimX == 5 && BlockDimY == 5) Format = TEX_FORMAT.ASTC_5x5_UNORM; else if (BlockDimX == 6 && BlockDimY == 5) Format = TEX_FORMAT.ASTC_6x5_UNORM; else if (BlockDimX == 6 && BlockDimY == 6) Format = TEX_FORMAT.ASTC_6x6_UNORM; else if (BlockDimX == 8 && BlockDimY == 5) Format = TEX_FORMAT.ASTC_8x5_UNORM; else if (BlockDimX == 8 && BlockDimY == 6) Format = TEX_FORMAT.ASTC_8x6_UNORM; else if (BlockDimX == 8 && BlockDimY == 8) Format = TEX_FORMAT.ASTC_8x8_UNORM; else if (BlockDimX == 10 && BlockDimY == 10) Format = TEX_FORMAT.ASTC_10x10_UNORM; else if (BlockDimX == 10 && BlockDimY == 5) Format = TEX_FORMAT.ASTC_10x5_UNORM; else if (BlockDimX == 10 && BlockDimY == 6) Format = TEX_FORMAT.ASTC_10x6_UNORM; else if (BlockDimX == 10 && BlockDimY == 8) Format = TEX_FORMAT.ASTC_10x8_UNORM; else throw new Exception($"Unsupported block dims! ({BlockDimX} x {BlockDimY})"); } stream.Dispose(); stream.Close(); } public void Unload() { } public void Save(System.IO.Stream stream) { using (FileWriter writer = new FileWriter(stream, true)) { if (Depth == 0) Depth = 1; writer.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; writer.Write(MagicFileConstant); writer.Write(BlockDimX); writer.Write(BlockDimY); writer.Write(BlockDimZ); writer.Write(IntTo3Bytes((int)Width)); writer.Write(IntTo3Bytes((int)Height)); writer.Write(IntTo3Bytes((int)Depth)); writer.Write(DataBlock); writer.Close(); writer.Dispose(); } } private static byte[] IntTo3Bytes(int value) { byte[] newValue = new byte[3]; newValue[0] = (byte)(value & 0xFF); newValue[1] = (byte)((value >> 8) & 0xFF); newValue[2] = (byte)((value >> 16) & 0xFF); return newValue; } public override void SetImageData(Bitmap bitmap, int ArrayLevel) { throw new NotImplementedException("Cannot set image data! Operation not implemented!"); } public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0) { return DataBlock; } } }