Advertisement
waelwindows92

TxpTools.cs

Jan 27th, 2018
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.30 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using BinarySerialization;
  6. using DIVALib.DSCUtils;
  7. using DIVALib.IO;
  8.  
  9. namespace DIVALib.ImageUtils
  10. {
  11.     public static class EnumExtension
  12.     {
  13.         public static T CastTo<T>(this Enum oldEnum) => (T)Enum.Parse(typeof(T).IsEnum ? typeof(T) : throw new InvalidOperationException("Tried to cast enum to invalid type."), oldEnum.ToString());
  14.     }
  15.  
  16.     public static class DdsExtension
  17.     {
  18.         public static TxpMipmap ToTxp(this DdsMipMap mip, DdsPixelFormat pf, int id = 0)
  19.         {
  20.             if (mip == null) throw new NullReferenceException("Tried to create TXP Mipmap from null DDS mipmap");
  21.             var tex = new TxpMipmap
  22.             {
  23.                 Width = mip.Width,
  24.                 Height = mip.Height,
  25.                 Format = pf.Format.CastTo<TxpMipmap.TexFormat>(),
  26.                 ByteSize = mip.ByteSize,
  27.                 Id = id,
  28.                 Data = mip.Data
  29.             };
  30.             return tex;
  31.         }
  32.  
  33.         public static TxpMipmap ToTxpMip(this DdsFile dds)
  34.         {
  35.             if (dds == null) throw new NullReferenceException("Tried to create TXP Mipmap from null DDS file");
  36.             var tex = new TxpMipmap
  37.             {
  38.                 Width = dds.Width,
  39.                 Height = dds.Height,
  40.                 Format = dds.PixelFormat.Format.CastTo<TxpMipmap.TexFormat>(),
  41.                 ByteSize = dds.PitchOrLinearSize,
  42.                 Data = dds.Data
  43.             };
  44.             return tex;
  45.         }
  46.  
  47.         public static TxpTexture ToTxp(this DdsFile dds)
  48.         {
  49.             var tex = new TxpTexture { MipMapCount = dds.MipMapCount == 0 ? 1 : dds.MipMapCount };
  50.             int mipNum = 1;
  51.             var mips = new List<TxpMipmap>(tex.MipMapCount) { dds.ToTxpMip() };
  52.             if(dds.MipMapCount > 0) dds.MipMaps.ForEach(mip => mips.Add(mip.ToTxp(dds.PixelFormat, mipNum++)));
  53.             mips.ForEach(mip => tex.Mipmaps.Add(mip));
  54.             return tex;
  55.         }
  56.     }  
  57.  
  58.     public class TxpMipmap : TxpBase
  59.     {
  60.         public enum TexFormat : uint
  61.         {
  62.             RGB = 1,
  63.             RGBA = 2,
  64.             DXT1 = 6,
  65.             DXT3 = 7,
  66.             DXT5 = 9,
  67.             ATI2n = 11
  68.         }
  69.  
  70.         public TxpMipmap() => Magic = "TXP"; //TXP2
  71.         [FieldOrder(1)]                         public int        Width = 512;
  72.         [FieldOrder(2)]                         public int        Height = 512;
  73.         [FieldOrder(3)]                         public TexFormat  Format = TexFormat.RGB;
  74.         [FieldOrder(4)]                         public int        Id;
  75.         [FieldOrder(5)]                         public int        ByteSize = 512 * 512;
  76.         [FieldOrder(6), FieldCount("ByteSize")] public List<byte> Data;
  77.         [Ignore] public int Size => 24 + Data.Count;
  78.  
  79.         public TxpMipmap(int width, int height, TexFormat format = TexFormat.RGB, int byteSize = 0)// : this()
  80.         {
  81.             Width = width;
  82.             Height = height;
  83.             Format = format;
  84.             ByteSize = byteSize == 0 ? width * height : byteSize;
  85.         }
  86.  
  87.         public static explicit operator DdsMipMap(TxpMipmap mip)
  88.         {
  89.             var ddsMipMap = new DdsMipMap
  90.             {
  91.                 Width = mip.Width,
  92.                 Height = mip.Height,
  93.                 ByteSize = mip.ByteSize,
  94.                 Data = mip.Data
  95.             };
  96.             return ddsMipMap;
  97.         }
  98.  
  99.         public static explicit operator DdsFile(TxpMipmap mip)
  100.         {
  101.             var ddsMipMap = new DdsFile
  102.             {
  103.                 Width = mip.Width,
  104.                 Height = mip.Height,
  105.                 PitchOrLinearSize = mip.ByteSize,
  106.                 PixelFormat = new DdsPixelFormat(mip.Format.CastTo<DdsPFType>()),
  107.                 Data = mip.Data
  108.             };
  109.             return ddsMipMap;  
  110.         }
  111.  
  112.         public override string ToString() => $"Mip #{Id}: {Width}x{Height} {Format} (BS:{ByteSize}, TS:{Size})";
  113.     }
  114.  
  115.     public class TxpTexture : TxpBase
  116.     {
  117.         public TxpTexture() => Magic = "TXP"; //TXP4
  118.         [FieldOrder(1)]                            public int             MipMapCount = 1;
  119.         [FieldOrder(2)]                            public int             Version = 0x1010101;
  120.         [FieldOrder(3), FieldCount("MipMapCount")] public List<int>       OffsetTable = new List<int>();
  121.         [FieldOrder(4), FieldCount("MipMapCount")] public List<TxpMipmap> Mipmaps = new List<TxpMipmap>();
  122.         [Ignore] public int Size => 12 + OffsetTable.Count * 4 + Mipmaps.Sum(mip => mip?.Size ?? 0);
  123.  
  124.         public void SetMipOffsets()
  125.         {
  126.             OffsetTable = new List<int>(MipMapCount);
  127.             var offset = 12 + MipMapCount * 4;
  128.             for (var counter = 0; counter < Mipmaps.Count; ++counter)
  129.             {
  130.                 offset += counter != 0 ? Mipmaps[counter - 1].Size : 0;
  131.                 OffsetTable.Add(offset);
  132.             }
  133.         }
  134.  
  135.         public static explicit operator DdsFile(TxpTexture tex)
  136.         {
  137.             var dds = new DdsFile
  138.             {
  139.                 Width = tex.Mipmaps[0].Width,
  140.                 Height = tex.Mipmaps[0].Height,
  141.                 PitchOrLinearSize = tex.Mipmaps[0].ByteSize,
  142.                 MipMapCount = tex.MipMapCount,
  143.                 PixelFormat = new DdsPixelFormat((DdsPFType)Enum.Parse(typeof(DdsPFType), tex.Mipmaps[0].Format.ToString()))
  144.             };
  145.             dds.Data = tex.Mipmaps[0].Data;
  146.             var mips = new List<DdsMipMap>();
  147.             tex.Mipmaps.GetRange(1, tex.MipMapCount-1).ForEach(mip => mips.Add((DdsMipMap)mip));
  148.             dds.MipMaps = mips;
  149.             return dds;
  150.         }
  151.  
  152.         public override string ToString() => $"TXP4: {MipMapCount} mips ( {Mipmaps[0].ToString().Substring(8)} )";
  153.     }
  154.  
  155.     public class TxpTextureAtlas : TxpBase
  156.     {
  157.         public TxpTextureAtlas() => Magic = "TXP"; //TXP3
  158.         [FieldOrder(1)]                             public int              TextureCount;
  159.         [FieldOrder(2)]                             public uint             Version = 0x1010112;
  160.         [FieldOrder(3), FieldCount("TextureCount")] public List<int>        OffsetTable = new List<int>();
  161.         [FieldOrder(4), FieldCount("TextureCount")] public List<TxpTexture> Textures = new List<TxpTexture>();
  162.  
  163.         public void SetTextureOffsets()
  164.         {
  165.             OffsetTable = new List<int>(TextureCount);
  166.             var offset = 12 + TextureCount * 4;
  167.             for (var counter = 0; counter < Textures.Count; ++counter)
  168.             {
  169.                 offset += counter != 0 ? Textures[counter - 1].Size : 0;
  170.                 OffsetTable.Add(offset);
  171.             }
  172.         }
  173.  
  174.         public void SetTextures(Stream file)
  175.         {
  176.             var serializer = new BinarySerializer();
  177.             Textures = new List<TxpTexture>(TextureCount);
  178.             file.Seek(OffsetTable[0], SeekOrigin.Begin);
  179.             OffsetTable.ForEach(offset => Textures.Add(serializer.Deserialize<TxpTexture>(file)));
  180.         }
  181.  
  182.         public static TxpTextureAtlas FromDds(DdsFile dds)
  183.         {
  184.             var file = new TxpTextureAtlas {Textures = new List<TxpTexture> {dds.ToTxp()}};
  185.             return file;
  186.         }
  187.  
  188.         public static TxpTextureAtlas FromDds(DdsFile[] ddsFiles)
  189.         {
  190.             var file = new TxpTextureAtlas {Textures = new List<TxpTexture>()};
  191.             foreach (var dds in ddsFiles)
  192.                 file.Textures.Add(dds.ToTxp());
  193.             return file;
  194.         }
  195.  
  196.         public static explicit operator List<DdsFile>(TxpTextureAtlas atlas)
  197.         {
  198.             var ddsTex = new List<DdsFile>(atlas.TextureCount);
  199.             atlas.Textures.ForEach(tex => ddsTex.Add((DdsFile)tex));
  200.             return ddsTex;
  201.         }
  202.  
  203.         public override string ToString() => $"TXP3: {TextureCount} textures, ({Textures.Count} serialized)";
  204.     }
  205.  
  206.     public abstract class TxpBase
  207.     {
  208.         [FieldCount(4), FieldLength(4)] public string Magic = "TXP0";
  209.     }
  210.  
  211.     public abstract class TxpFile
  212.     {
  213.         [FieldOrder(0)] public char[] Magic = { 'T', 'X', 'P' };
  214.         [FieldOrder(1)]
  215.         [Subtype("Magic", "TXP", typeof(TxpTexture))]
  216.         [Subtype("Magic", "TXP", typeof(TxpTextureAtlas))]
  217.         public TxpBase txp;
  218.     }
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement