kiwidog

Frostbite 2 ITexture to DDS Converter

Dec 30th, 2013
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.33 KB | None | 0 0
  1. /*
  2.  * CTexture.cs
  3.  * By: kiwidog
  4.  * Generation of RAW/DDS file formats from the Frostbite 2 ITexture/Chunk Data
  5.  * http://allenthinks.com
  6.  * kiwidoggie productions (c) 2012-2013
  7.  */
  8.  
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.IO;
  15. using zlib;
  16.  
  17. namespace IceEditor.Editor
  18. {
  19.     class CTexture
  20.     {
  21.         #region D3D DDS MSDN Definitions
  22.         // Credits: MSDN
  23.         enum D3DFORMAT : uint
  24.         {
  25.             D3DFMT_UNKNOWN              =  0,
  26.  
  27.             D3DFMT_R8G8B8               = 20,
  28.             D3DFMT_A8R8G8B8             = 21,
  29.             D3DFMT_X8R8G8B8             = 22,
  30.             D3DFMT_R5G6B5               = 23,
  31.             D3DFMT_X1R5G5B5             = 24,
  32.             D3DFMT_A1R5G5B5             = 25,
  33.             D3DFMT_A4R4G4B4             = 26,
  34.             D3DFMT_R3G3B2               = 27,
  35.             D3DFMT_A8                   = 28,
  36.             D3DFMT_A8R3G3B2             = 29,
  37.             D3DFMT_X4R4G4B4             = 30,
  38.             D3DFMT_A2B10G10R10          = 31,
  39.             D3DFMT_A8B8G8R8             = 32,
  40.             D3DFMT_X8B8G8R8             = 33,
  41.             D3DFMT_G16R16               = 34,
  42.             D3DFMT_A2R10G10B10          = 35,
  43.             D3DFMT_A16B16G16R16         = 36,
  44.  
  45.             D3DFMT_A8P8                 = 40,
  46.             D3DFMT_P8                   = 41,
  47.  
  48.             D3DFMT_L8                   = 50,
  49.             D3DFMT_A8L8                 = 51,
  50.             D3DFMT_A4L4                 = 52,
  51.  
  52.             D3DFMT_V8U8                 = 60,
  53.             D3DFMT_L6V5U5               = 61,
  54.             D3DFMT_X8L8V8U8             = 62,
  55.             D3DFMT_Q8W8V8U8             = 63,
  56.             D3DFMT_V16U16               = 64,
  57.             D3DFMT_A2W10V10U10          = 67,
  58.  
  59.             D3DFMT_UYVY                 = 0x59565955,
  60.             D3DFMT_R8G8_B8G8            = 0x47424752,
  61.             D3DFMT_YUY2                 = 0x32595559,
  62.             D3DFMT_G8R8_G8B8            = 0x42475247,
  63.             D3DFMT_DXT1                 = 0x31545844,
  64.             D3DFMT_DXT2                 = 0x32545844,
  65.             D3DFMT_DXT3                 = 0x33545844,
  66.             D3DFMT_DXT4                 = 0x34545844,
  67.             D3DFMT_DXT5                 = 0x35545844,
  68.  
  69.             D3DFMT_D16_LOCKABLE         = 70,
  70.             D3DFMT_D32                  = 71,
  71.             D3DFMT_D15S1                = 73,
  72.             D3DFMT_D24S8                = 75,
  73.             D3DFMT_D24X8                = 77,
  74.             D3DFMT_D24X4S4              = 79,
  75.             D3DFMT_D16                  = 80,
  76.  
  77.             D3DFMT_D32F_LOCKABLE        = 82,
  78.             D3DFMT_D24FS8               = 83,
  79.  
  80.             D3DFMT_D32_LOCKABLE         = 84,
  81.             D3DFMT_S8_LOCKABLE          = 85,
  82.  
  83.             D3DFMT_L16                  = 81,
  84.  
  85.             D3DFMT_VERTEXDATA           =100,
  86.             D3DFMT_INDEX16              =101,
  87.             D3DFMT_INDEX32              =102,
  88.  
  89.             D3DFMT_Q16W16V16U16         =110,
  90.  
  91.             D3DFMT_MULTI2_ARGB8         = 0x3154454D,
  92.  
  93.             D3DFMT_R16F                 = 111,
  94.             D3DFMT_G16R16F              = 112,
  95.             D3DFMT_A16B16G16R16F        = 113,
  96.  
  97.             D3DFMT_R32F                 = 114,
  98.             D3DFMT_G32R32F              = 115,
  99.             D3DFMT_A32B32G32R32F        = 116,
  100.  
  101.             D3DFMT_CxV8U8               = 117,
  102.  
  103.             D3DFMT_A1                   = 118,
  104.             D3DFMT_A2B10G10R10_XR_BIAS  = 119,
  105.             D3DFMT_BINARYBUFFER         = 199,
  106.  
  107.             D3DFMT_FORCE_DWORD          =0x7fffffff
  108.         }
  109.        
  110.         // MSDN
  111.         enum DDSFLAGS : uint
  112.         {
  113.             DDSD_CAPS = 0x1,
  114.             DDSD_HEIGHT = 0x2,
  115.             DDSD_WIDTH = 0x4,
  116.             DDSD_PITCH = 0x8,
  117.             DDSD_PIXELFORMAT = 0x1000,
  118.             DDSD_MIPMAPCOUNT = 0x20000,
  119.             DDSD_LINEARSIZE = 0x80000,
  120.             DDSD_DEPTH = 0x800000
  121.         }
  122.  
  123.         // MSDN
  124.         enum DDSCAPS : uint
  125.         {
  126.             DDSCAPS_COMPLEX = 0x8,
  127.             DDSCAPS_MIPMAP = 0x400000,
  128.             DDSCAPS_TEXTURE = 0x1000 // Required
  129.         }
  130.  
  131.         // MSDN
  132.         enum DDSCAPS2 : uint
  133.         {
  134.             DDSCAPS2_CUBEMAP = 0x200,
  135.             DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
  136.             DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
  137.             DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
  138.             DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
  139.             DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
  140.             DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
  141.             DDSCAPS2_VOLUME = 0x200000
  142.         }
  143.  
  144.         // MSDN
  145.         enum DDSPXLFMTFLAGS : uint
  146.         {
  147.             DDPF_ALPHAPIXELS = 0x1,
  148.             DDPF_ALPHA = 0x2,
  149.             DDPF_FOURCC = 0x4,
  150.             DDPF_RGB = 0x40,
  151.             DDPF_YUV = 0x200,
  152.             DDPF_LUMINANCE = 0x20000
  153.         }
  154.         #endregion
  155.  
  156.         class DDSPixelFormat
  157.         {
  158.             public uint m_size;
  159.             public DDSPXLFMTFLAGS m_flags;
  160.             public D3DFORMAT m_fourCC; // DXT1
  161.             public uint m_rgbBitCount;
  162.             public uint m_rBitMask; // Red
  163.             public uint m_gBitMask; // Green
  164.             public uint m_bBitMask; // Blue
  165.             public uint m_aBitMask; // Alpha
  166.  
  167.             /// <summary>
  168.             /// Default Constructor
  169.             /// Works for Generation or Reading out; Sets static data
  170.             /// </summary>
  171.             public DDSPixelFormat()
  172.             {
  173.                 m_size = 32;
  174.             }
  175.         }
  176.  
  177.         class DDSHeader
  178.         {
  179.             public uint m_magic; // "DDS " or 0x44445320
  180.             public uint m_size; // Always 124
  181.             public uint m_flags; //
  182.             public uint m_height;
  183.             public uint m_width;
  184.             public uint m_pitchOrLinearSize; // Big Endian
  185.             public uint m_depth; // 0?
  186.             public uint m_mipMapCount; // 1?
  187.             public byte[] m_reserved; // Size=0x2C, its unused so we can put text here
  188.             public DDSPixelFormat m_fmt;
  189.             public DDSCAPS m_caps;
  190.             public uint m_caps2;
  191.             public uint m_caps3;
  192.             public uint m_caps4;
  193.             public uint m_reserved2; // Unused
  194.  
  195.             /// <summary>
  196.             /// DDSHeader Generation/Reading
  197.             /// Sets static data
  198.             /// </summary>
  199.             public DDSHeader()
  200.             {
  201.                 m_magic = 0x20534444; // "DDS "
  202.                 m_size = 124;
  203.                 m_reserved2 = 0;
  204.                 m_fmt = new DDSPixelFormat();
  205.             }
  206.         }
  207.  
  208.         class ImageChunk
  209.         {
  210.             public uint m_uncompressedSize; // Non Compressed Size
  211.             public uint m_compressedSize;
  212.             public byte[] m_data;
  213.  
  214.             /// <summary>
  215.             /// Reads out an image chunk (if there are multiple mip-maps then there will be multiple chunk data)
  216.             /// </summary>
  217.             /// <param name="stream"></param>
  218.             public ImageChunk(Stream stream)
  219.             {
  220.                 IceReader br = new IceReader(stream, Endianness.BigEndian, WuTangStyle.LiveStream);
  221.                 m_uncompressedSize = br.ReadUInt32();
  222.                 m_compressedSize = br.ReadUInt32();
  223.                 m_data = br.ReadBytes((int)m_compressedSize);
  224.                 br.Dispose();
  225.             }
  226.         }
  227.  
  228.         List<ImageChunk> m_chunks = new List<ImageChunk>();
  229.  
  230.         /// <summary>
  231.         /// Reads out of a chunk file, uses the resource data to generate a working DDS file
  232.         /// Assumes that the only type used in Frostbite 2 is DXT1
  233.         /// </summary>
  234.         /// <param name="chunkFile">File path to the chunk file (resource.id chunk)</param>
  235.         /// <param name="outputFile">File path to the final output .dds file</param>
  236.         public void GenerateDDSFile(string chunkFile, string outputFile, ITexture info)
  237.         {
  238.             IceReader br = new IceReader(new FileStream(chunkFile, FileMode.Open, FileAccess.Read), Endianness.BigEndian);
  239.             while (br.BaseStream.Position < br.BaseStream.Length)
  240.                 m_chunks.Add(new ImageChunk(br.BaseStream));
  241.             br.Close();
  242.  
  243.             IceWriter bw = new IceWriter(new FileStream(outputFile, FileMode.Create, FileAccess.Write));
  244.             // Generate the Header and PixelFormatData
  245.             DDSHeader dds = new DDSHeader();
  246.             dds.m_flags = (uint)(DDSFLAGS.DDSD_CAPS | DDSFLAGS.DDSD_HEIGHT | DDSFLAGS.DDSD_WIDTH | DDSFLAGS.DDSD_PIXELFORMAT); // Default, others can be added later
  247.             dds.m_height = info.m_height;
  248.             dds.m_width = info.m_width;
  249.             dds.m_pitchOrLinearSize = info.m_pitch;
  250.             dds.m_depth = info.m_depth;
  251.             dds.m_mipMapCount = 15;
  252.             dds.m_reserved = new byte[4*11];
  253.             dds.m_fmt.m_flags = DDSPXLFMTFLAGS.DDPF_FOURCC;
  254.  
  255.             // Texture Specific Settings
  256.             switch ((TextureFormat)info.m_format)
  257.             {
  258.                 case TextureFormat.TextureFormat_DXT1:
  259.                     dds.m_fmt.m_fourCC = D3DFORMAT.D3DFMT_DXT1;
  260.                     break;
  261.                 case TextureFormat.TextureFormat_DXT3:
  262.                     dds.m_fmt.m_fourCC = D3DFORMAT.D3DFMT_DXT3;
  263.                     break;
  264.                 case TextureFormat.TextureFormat_DXT5:
  265.                     dds.m_fmt.m_fourCC = D3DFORMAT.D3DFMT_DXT5;
  266.                    
  267.                     break;
  268.                 default:
  269.                     break;
  270.             }
  271.             // General Texture Settings
  272.             switch ((TextureFormat)info.m_format)
  273.             {
  274.                 case TextureFormat.TextureFormat_DXT1:
  275.                 case TextureFormat.TextureFormat_DXT3:
  276.                 case TextureFormat.TextureFormat_DXT5:
  277.                     dds.m_fmt.m_flags |= DDSPXLFMTFLAGS.DDPF_RGB;
  278.                     dds.m_fmt.m_rgbBitCount = 32;
  279.                     dds.m_fmt.m_rBitMask = 0x000000FF;
  280.                     dds.m_fmt.m_gBitMask = 0x0000FF00;
  281.                     dds.m_fmt.m_bBitMask = 0x00FF0000;
  282.                     dds.m_fmt.m_aBitMask = 0xFF000000;
  283.                     break;
  284.                 default:
  285.                     break;
  286.             }            
  287.  
  288.             dds.m_caps = DDSCAPS.DDSCAPS_TEXTURE;
  289.             dds.m_caps2 = 0;
  290.             dds.m_caps3 = 0;
  291.             dds.m_caps4 = 0;
  292.  
  293.             bw.Write(dds.m_magic);
  294.             bw.Write(dds.m_size);
  295.             bw.Write(dds.m_flags);
  296.             bw.Write(dds.m_height);
  297.             bw.Write(dds.m_width);
  298.             bw.Write(dds.m_pitchOrLinearSize);
  299.             bw.Write(dds.m_depth);
  300.             bw.Write(dds.m_mipMapCount);
  301.             bw.Write(dds.m_reserved);
  302.             bw.Write(dds.m_fmt.m_size);
  303.             bw.Write((uint)dds.m_fmt.m_flags);
  304.             bw.Write((uint)dds.m_fmt.m_fourCC);
  305.             bw.Write(dds.m_fmt.m_rgbBitCount);
  306.             bw.Write(dds.m_fmt.m_rBitMask);
  307.             bw.Write(dds.m_fmt.m_gBitMask);
  308.             bw.Write(dds.m_fmt.m_bBitMask);
  309.             bw.Write(dds.m_fmt.m_aBitMask);
  310.             bw.Write((uint)dds.m_caps);
  311.             bw.Write(dds.m_caps2);
  312.             bw.Write(dds.m_caps3);
  313.             bw.Write(dds.m_caps4);
  314.             bw.Write(dds.m_reserved2);
  315.  
  316.             // Loop through all the chunks
  317.             foreach (ImageChunk img in m_chunks)
  318.             {
  319.                 if (img.m_compressedSize == img.m_uncompressedSize)
  320.                     bw.Write(img.m_data);
  321.                 else
  322.                 {
  323.                     Stream m_final = new MemoryStream();
  324.                     ZOutputStream outStream = new ZOutputStream(m_final);
  325.                     MemoryStream compressedData = new MemoryStream(img.m_data);
  326.                     try
  327.                     {
  328.                         CResource.CopyStream(compressedData, outStream);
  329.                     }
  330.                     finally
  331.                     {
  332.                         compressedData.Close();
  333.                         //outStream.Close();
  334.                     }
  335.                     m_final.Position = 0;
  336.                     IceReader brx = new IceReader(m_final);
  337.                     bw.Write(brx.ReadBytes((int)brx.BaseStream.Length));
  338.                     brx.Close();
  339.                 }
  340.             }
  341.             bw.Close();
  342.         }
  343.     }
  344. }
Advertisement
Add Comment
Please, Sign In to add comment