Ejemplo n.º 1
0
        public DDS(DDSType Type)
        {
            switch (Type)
            {
                case DDSType.DXT1:
                    this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                    this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT1;
                    this.Header.Pitch /= 2;
                    return;

                case DDSType.DXT1a:
                    this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                    this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT1;
                    this.Header.Pitch /= 2;
                    return;

                case DDSType.DXT3:
                    this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                    this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT3;
                    this.Header.Pitch /= 2;
                    return;

                case DDSType.DXT5:
                    this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                    this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT5;
                    this.Header.Pitch /= 2;
                    return;

                case DDSType.b4444:
                case DDSType.b565:
                    break;

                case DDSType.b1555:
                    this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_RGB | DDSPixelFormatFlags.DDPF_ALPHAPIXELS;
                    this.Header.PixelFormat.RGBBitCount = 0x10;
                    this.Header.PixelFormat.BitMaskRed = 0x7c00;
                    this.Header.PixelFormat.BitMaskGreen = 0x3e0;
                    this.Header.PixelFormat.BitMaskBlue = 0x1f;
                    this.Header.PixelFormat.BitMaskRGBAlpha = 0x8000;
                    break;

                case DDSType.ARGB:
                    this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_RGB | DDSPixelFormatFlags.DDPF_ALPHAPIXELS;
                    this.Header.PixelFormat.RGBBitCount = 0x20;
                    this.Header.PixelFormat.BitMaskRed = 0xff0000;
                    this.Header.PixelFormat.BitMaskGreen = 0xff00;
                    this.Header.PixelFormat.BitMaskBlue = 0xff;
                    this.Header.PixelFormat.BitMaskRGBAlpha = 0xff000000;
                    this.Header.Pitch *= 4;
                    return;

                default:
                    return;
            }
        }
Ejemplo n.º 2
0
        public DDS(DDSType Type)
        {
            switch (Type)
            {
            case DDSType.DXT1:
                this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT1;
                this.Header.Pitch /= 2;
                return;

            case DDSType.DXT1a:
                this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT1;
                this.Header.Pitch /= 2;
                return;

            case DDSType.DXT3:
                this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT3;
                this.Header.Pitch /= 2;
                return;

            case DDSType.DXT5:
                this.Header.PixelFormat.Flags |= DDSPixelFormatFlags.DDPF_FOURCC;
                this.Header.PixelFormat.FourCC = DDSPixelFormatFourCC.DXT5;
                this.Header.Pitch /= 2;
                return;

            case DDSType.b4444:
            case DDSType.b565:
                break;

            case DDSType.b1555:
                this.Header.PixelFormat.Flags          |= DDSPixelFormatFlags.DDPF_RGB | DDSPixelFormatFlags.DDPF_ALPHAPIXELS;
                this.Header.PixelFormat.RGBBitCount     = 0x10;
                this.Header.PixelFormat.BitMaskRed      = 0x7c00;
                this.Header.PixelFormat.BitMaskGreen    = 0x3e0;
                this.Header.PixelFormat.BitMaskBlue     = 0x1f;
                this.Header.PixelFormat.BitMaskRGBAlpha = 0x8000;
                break;

            case DDSType.ARGB:
                this.Header.PixelFormat.Flags          |= DDSPixelFormatFlags.DDPF_RGB | DDSPixelFormatFlags.DDPF_ALPHAPIXELS;
                this.Header.PixelFormat.RGBBitCount     = 0x20;
                this.Header.PixelFormat.BitMaskRed      = 0xff0000;
                this.Header.PixelFormat.BitMaskGreen    = 0xff00;
                this.Header.PixelFormat.BitMaskBlue     = 0xff;
                this.Header.PixelFormat.BitMaskRGBAlpha = 0xff000000;
                this.Header.Pitch *= 4;
                return;

            default:
                return;
            }
        }
Ejemplo n.º 3
0
        public File(byte[] source, bool isNormalMap = false)
        {
            header = new byte[0x80];
            Array.Copy(source, header, 0x80);
            Header  = new Header(header);
            content = new byte[source.Length - 0x80];
            Array.Copy(source, 0x80, content, 0x00, content.Length);
            DDSType = GetDDSType();
            ARGBMask mask = new ARGBMask(new uint[] { Header.DDSPF.ABitMask, Header.DDSPF.RBitMask, Header.DDSPF.GBitMask, Header.DDSPF.BBitMask });

            switch (DDSType)
            {
            case DDS.DDSType.A8R8G8B8:
                Content = new ColorA8R8G8B8(content, mask, isNormalMap);
                break;

            case DDS.DDSType.R8G8B8:
                Content = new ColorR8G8B8(content, mask, isNormalMap);
                break;

            case DDS.DDSType.A1R5G5B5:
                Content = new ColorA1R5G5B5(content, mask, isNormalMap);
                break;

            case DDS.DDSType.A4R4G4B4:
                Content = new ColorA4R4G4B4(content, mask, isNormalMap);
                break;

            case DDS.DDSType.R5G6B5:
                Content = new ColorR5G6B5(content, mask, isNormalMap);
                break;

            case DDS.DDSType.R5G5B5:
                Content = new ColorR5G5B5(content, mask, isNormalMap);
                break;

            case DDS.DDSType.DXT1:
                Content = new ColorDXT1(content, null, isNormalMap);
                break;

            case DDS.DDSType.DXT3:
                Content = new ColorDXT3(content, null, isNormalMap);
                break;

            case DDS.DDSType.DXT5:
                Content = new ColorDXT5(content, null, isNormalMap);
                break;
            }
        }
Ejemplo n.º 4
0
        public Image GetImage(DDSType Type)
        {
            Image   img  = new Bitmap(this.Header.Width, this.Header.Height);
            DDSType type = Type;

            if (type != DDSType.DXT1)
            {
                if (type != DDSType.ARGB)
                {
                    return(img);
                }
            }
            else
            {
                this.blockDecompressImageDXT1((ulong)this.Header.Width, (ulong)this.Header.Height, this.Data, img);
                return(img);
            }
            this.rgbaDecompressImage(img);
            return(img);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the raw Colorset data list from a dds file.
        /// </summary>
        /// <param name="ddsFileDirectory"></param>
        /// <returns></returns>
        public static List <Half> GetColorsetDataFromDDS(DirectoryInfo ddsFileDirectory)
        {
            using (var br = new BinaryReader(File.OpenRead(ddsFileDirectory.FullName)))
            {
                // Check DDS type
                br.BaseStream.Seek(84, SeekOrigin.Begin);

                var          texType = br.ReadInt32();
                XivTexFormat textureType;

                if (DDSType.ContainsKey(texType))
                {
                    textureType = DDSType[texType];
                }
                else
                {
                    throw new Exception($"DDS Type ({texType}) not recognized. Expecting A16B16G16R16F.");
                }

                if (textureType != XivTexFormat.A16B16G16R16F)
                {
                    throw new Exception($"Incorrect file type. Expected: A16B16G16R16F  Given: {textureType}");
                }
                var colorSetData = new List <Half>(256);

                // skip DDS header
                br.BaseStream.Seek(128, SeekOrigin.Begin);

                // color data is always 512 (4w x 16h = 64 x 8bpp = 512)
                // this reads 256 ushort values which is 256 x 2 = 512
                for (var i = 0; i < 256; i++)
                {
                    colorSetData.Add((new Half(br.ReadUInt16())));
                }

                return(colorSetData);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Converts a DDS file into a TEX file then returns the raw data
        /// </summary>
        /// <param name="xivTex">The texture data</param>
        /// <param name="item">The item who's texture we are importing</param>
        /// <param name="ddsFileDirectory">The directory of the dds file being imported</param>
        /// <returns>The offset to the new imported data</returns>
        public async Task <byte[]> DDStoTexData(XivTex xivTex, IItem item, DirectoryInfo ddsFileDirectory)
        {
            if (File.Exists(ddsFileDirectory.FullName))
            {
                using (var br = new BinaryReader(File.OpenRead(ddsFileDirectory.FullName)))
                {
                    br.BaseStream.Seek(12, SeekOrigin.Begin);

                    var newHeight = br.ReadInt32();
                    var newWidth  = br.ReadInt32();
                    br.ReadBytes(8);
                    var newMipCount = br.ReadInt32();

                    if (newHeight % 2 != 0 || newWidth % 2 != 0)
                    {
                        throw new Exception("Resolution must be a multiple of 2");
                    }

                    br.BaseStream.Seek(80, SeekOrigin.Begin);

                    var          textureFlags = br.ReadInt32();
                    var          texType      = br.ReadInt32();
                    XivTexFormat textureType;

                    if (DDSType.ContainsKey(texType))
                    {
                        textureType = DDSType[texType];
                    }
                    else
                    {
                        throw new Exception($"DDS Type ({texType}) not recognized.");
                    }

                    switch (textureFlags)
                    {
                    case 2 when textureType == XivTexFormat.A8R8G8B8:
                        textureType = XivTexFormat.A8;
                        break;

                    case 65 when textureType == XivTexFormat.A8R8G8B8:
                        var bpp = br.ReadInt32();
                        if (bpp == 32)
                        {
                            textureType = XivTexFormat.A8R8G8B8;
                        }
                        else
                        {
                            var red = br.ReadInt32();

                            switch (red)
                            {
                            case 31744:
                                textureType = XivTexFormat.A1R5G5B5;
                                break;

                            case 3840:
                                textureType = XivTexFormat.A4R4G4B4;
                                break;
                            }
                        }

                        break;
                    }

                    if (textureType == xivTex.TextureFormat)
                    {
                        var uncompressedLength = (int)new FileInfo(ddsFileDirectory.FullName).Length - 128;
                        var newTex             = new List <byte>();

                        if (!xivTex.TextureTypeAndPath.Path.Contains(".atex"))
                        {
                            var DDSInfo = await DDS.ReadDDS(br, xivTex, newWidth, newHeight, newMipCount);

                            newTex.AddRange(_dat.MakeType4DatHeader(xivTex, DDSInfo.mipPartOffsets, DDSInfo.mipPartCounts, uncompressedLength, newMipCount, newWidth, newHeight));
                            newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                            newTex.AddRange(DDSInfo.compressedDDS);

                            return(newTex.ToArray());
                        }
                        else
                        {
                            br.BaseStream.Seek(128, SeekOrigin.Begin);
                            newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                            newTex.AddRange(br.ReadBytes(uncompressedLength));

                            return(newTex.ToArray());
                        }
                    }
                    else
                    {
                        throw new Exception($"Incorrect file type. Expected: {xivTex.TextureFormat}  Given: {textureType}");
                    }
                }
            }
            else
            {
                throw new IOException($"Could not find file: {ddsFileDirectory.FullName}");
            }
        }
Ejemplo n.º 7
0
        public async Task <int> TexBMPImporter(XivTex xivTex, IItem item, DirectoryInfo bmpFileDirectory, string source)
        {
            var offset = 0;

            var modding = new Modding(_gameDirectory);

            if (File.Exists(bmpFileDirectory.FullName))
            {
                // Check if the texture being imported has been imported before
                var modEntry = await modding.TryGetModEntry(xivTex.TextureTypeAndPath.Path);

                var ddsContainer = new DDSContainer();
                CompressionFormat compressionFormat;

                switch (xivTex.TextureFormat)
                {
                case XivTexFormat.DXT1:
                    compressionFormat = CompressionFormat.BC1;
                    break;

                case XivTexFormat.DXT5:
                    compressionFormat = CompressionFormat.BC3;
                    break;

                case XivTexFormat.A8R8G8B8:
                    compressionFormat = CompressionFormat.BGRA;
                    break;

                default:
                    throw new Exception($"Format {xivTex.TextureFormat} is not currently supported for BMP import\n\nPlease use the DDS import option instead.");
                }

                using (var surface = Surface.LoadFromFile(bmpFileDirectory.FullName))
                {
                    surface.FlipVertically();

                    using (var compressor = new Compressor())
                    {
                        compressor.Input.GenerateMipmaps = true;
                        compressor.Input.SetData(surface);
                        compressor.Compression.Format = compressionFormat;
                        compressor.Compression.SetBGRAPixelFormat();

                        compressor.Process(out ddsContainer);
                    }
                }

                using (var ddsMemoryStream = new MemoryStream())
                {
                    ddsContainer.Write(ddsMemoryStream, DDSFlags.None);

                    using (var br = new BinaryReader(ddsMemoryStream))
                    {
                        br.BaseStream.Seek(12, SeekOrigin.Begin);

                        var newHeight = br.ReadInt32();
                        var newWidth  = br.ReadInt32();
                        br.ReadBytes(8);
                        var newMipCount = br.ReadInt32();

                        if (newHeight % 2 != 0 || newWidth % 2 != 0)
                        {
                            throw new Exception("Resolution must be a multiple of 2");
                        }

                        br.BaseStream.Seek(80, SeekOrigin.Begin);

                        var          textureFlags = br.ReadInt32();
                        var          texType      = br.ReadInt32();
                        XivTexFormat textureType;

                        if (DDSType.ContainsKey(texType))
                        {
                            textureType = DDSType[texType];
                        }
                        else
                        {
                            throw new Exception($"DDS Type ({texType}) not recognized.");
                        }

                        switch (textureFlags)
                        {
                        case 2 when textureType == XivTexFormat.A8R8G8B8:
                            textureType = XivTexFormat.A8;
                            break;

                        case 65 when textureType == XivTexFormat.A8R8G8B8:
                            var bpp = br.ReadInt32();
                            if (bpp == 32)
                            {
                                textureType = XivTexFormat.A8R8G8B8;
                            }
                            else
                            {
                                var red = br.ReadInt32();

                                switch (red)
                                {
                                case 31744:
                                    textureType = XivTexFormat.A1R5G5B5;
                                    break;

                                case 3840:
                                    textureType = XivTexFormat.A4R4G4B4;
                                    break;
                                }
                            }

                            break;
                        }

                        if (textureType == xivTex.TextureFormat)
                        {
                            var uncompressedLength = ddsMemoryStream.Length;
                            var newTex             = new List <byte>();

                            if (!xivTex.TextureTypeAndPath.Path.Contains(".atex"))
                            {
                                var DDSInfo = await DDS.ReadDDS(br, xivTex, newWidth, newHeight, newMipCount);

                                newTex.AddRange(_dat.MakeType4DatHeader(xivTex, DDSInfo.mipPartOffsets, DDSInfo.mipPartCounts, (int)uncompressedLength, newMipCount, newWidth, newHeight));
                                newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                                newTex.AddRange(DDSInfo.compressedDDS);

                                offset = await _dat.WriteToDat(newTex, modEntry, xivTex.TextureTypeAndPath.Path,
                                                               item.ItemCategory, item.Name, xivTex.TextureTypeAndPath.DataFile, source, 4);
                            }
                            else
                            {
                                br.BaseStream.Seek(128, SeekOrigin.Begin);
                                newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                                newTex.AddRange(br.ReadBytes((int)uncompressedLength));

                                offset = await _dat.ImportType2Data(newTex.ToArray(), item.Name, xivTex.TextureTypeAndPath.Path,
                                                                    item.ItemCategory, source);
                            }
                        }
                        else
                        {
                            throw new Exception($"Incorrect file type. Expected: {xivTex.TextureFormat}  Given: {textureType}");
                        }
                    }
                }

                ddsContainer.Dispose();
            }
            else
            {
                throw new IOException($"Could not find file: {bmpFileDirectory.FullName}");
            }

            return(offset);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Converts a DDS file into a TEX file then imports it
        /// </summary>
        /// <param name="xivTex">The texture data</param>
        /// <param name="item">The item who's texture we are importing</param>
        /// <param name="ddsFileDirectory">The directory of the dds file being imported</param>
        /// <returns>The offset to the new imported data</returns>
        public async Task <int> TexDDSImporter(XivTex xivTex, IItem item, DirectoryInfo ddsFileDirectory, string source)
        {
            var offset = 0;

            var modding = new Modding(_gameDirectory);

            if (File.Exists(ddsFileDirectory.FullName))
            {
                // Check if the texture being imported has been imported before
                var modEntry = await modding.TryGetModEntry(xivTex.TextureTypeAndPath.Path);

                using (var br = new BinaryReader(File.OpenRead(ddsFileDirectory.FullName)))
                {
                    br.BaseStream.Seek(12, SeekOrigin.Begin);

                    var newHeight = br.ReadInt32();
                    var newWidth  = br.ReadInt32();
                    br.ReadBytes(8);
                    var newMipCount = br.ReadInt32();

                    if (newHeight % 2 != 0 || newWidth % 2 != 0)
                    {
                        throw new Exception("Resolution must be a multiple of 2");
                    }

                    br.BaseStream.Seek(80, SeekOrigin.Begin);

                    var          textureFlags = br.ReadInt32();
                    var          texType      = br.ReadInt32();
                    XivTexFormat textureType;

                    if (DDSType.ContainsKey(texType))
                    {
                        textureType = DDSType[texType];
                    }
                    else
                    {
                        throw new Exception($"DDS Type ({texType}) not recognized.");
                    }

                    switch (textureFlags)
                    {
                    case 2 when textureType == XivTexFormat.A8R8G8B8:
                        textureType = XivTexFormat.A8;
                        break;

                    case 65 when textureType == XivTexFormat.A8R8G8B8:
                        var bpp = br.ReadInt32();
                        if (bpp == 32)
                        {
                            textureType = XivTexFormat.A8R8G8B8;
                        }
                        else
                        {
                            var red = br.ReadInt32();

                            switch (red)
                            {
                            case 31744:
                                textureType = XivTexFormat.A1R5G5B5;
                                break;

                            case 3840:
                                textureType = XivTexFormat.A4R4G4B4;
                                break;
                            }
                        }

                        break;
                    }

                    if (textureType == xivTex.TextureFormat)
                    {
                        var uncompressedLength = (int)new FileInfo(ddsFileDirectory.FullName).Length - 128;
                        var newTex             = new List <byte>();

                        if (!xivTex.TextureTypeAndPath.Path.Contains(".atex"))
                        {
                            var DDSInfo = await DDS.ReadDDS(br, xivTex, newWidth, newHeight, newMipCount);

                            newTex.AddRange(_dat.MakeType4DatHeader(xivTex, DDSInfo.mipPartOffsets, DDSInfo.mipPartCounts, uncompressedLength, newMipCount, newWidth, newHeight));
                            newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                            newTex.AddRange(DDSInfo.compressedDDS);

                            offset = await _dat.WriteToDat(newTex, modEntry, xivTex.TextureTypeAndPath.Path,
                                                           item.ItemCategory, item.Name, xivTex.TextureTypeAndPath.DataFile, source, 4);
                        }
                        else
                        {
                            br.BaseStream.Seek(128, SeekOrigin.Begin);
                            newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                            newTex.AddRange(br.ReadBytes(uncompressedLength));

                            offset = await _dat.ImportType2Data(newTex.ToArray(), item.Name, xivTex.TextureTypeAndPath.Path,
                                                                item.ItemCategory, source);
                        }
                    }
                    else
                    {
                        throw new Exception($"Incorrect file type. Expected: {xivTex.TextureFormat}  Given: {textureType}");
                    }
                }
            }
            else
            {
                throw new IOException($"Could not find file: {ddsFileDirectory.FullName}");
            }

            return(offset);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Retrieves the texture format information from a DDS file stream.
        /// </summary>
        /// <param name="ddsStream"></param>
        /// <returns></returns>
        public XivTexFormat GetDDSTexFormat(BinaryReader ddsStream)
        {
            ddsStream.BaseStream.Seek(12, SeekOrigin.Begin);

            var newHeight = ddsStream.ReadInt32();
            var newWidth  = ddsStream.ReadInt32();

            ddsStream.ReadBytes(8);
            var newMipCount = ddsStream.ReadInt32();

            if (newHeight % 2 != 0 || newWidth % 2 != 0)
            {
                throw new Exception("Resolution must be a multiple of 2");
            }

            ddsStream.BaseStream.Seek(80, SeekOrigin.Begin);

            var          textureFlags = ddsStream.ReadInt32();
            var          texType      = ddsStream.ReadInt32();
            XivTexFormat textureType;

            if (DDSType.ContainsKey(texType))
            {
                textureType = DDSType[texType];
            }
            else
            {
                throw new Exception($"DDS Type ({texType}) not recognized.");
            }

            switch (textureFlags)
            {
            case 2 when textureType == XivTexFormat.A8R8G8B8:
                textureType = XivTexFormat.A8;
                break;

            case 65 when textureType == XivTexFormat.A8R8G8B8:
                var bpp = ddsStream.ReadInt32();
                if (bpp == 32)
                {
                    textureType = XivTexFormat.A8R8G8B8;
                }
                else
                {
                    var red = ddsStream.ReadInt32();

                    switch (red)
                    {
                    case 31744:
                        textureType = XivTexFormat.A1R5G5B5;
                        break;

                    case 3840:
                        textureType = XivTexFormat.A4R4G4B4;
                        break;
                    }
                }

                break;
            }
            return(textureType);
        }
Ejemplo n.º 10
0
 public Image GetImage(DDSType Type)
 {
     Image img = new Bitmap(this.Header.Width, this.Header.Height);
     DDSType type = Type;
     if (type != DDSType.DXT1)
     {
         if (type != DDSType.ARGB)
         {
             return img;
         }
     }
     else
     {
         this.blockDecompressImageDXT1((ulong) this.Header.Width, (ulong) this.Header.Height, this.Data, img);
         return img;
     }
     this.rgbaDecompressImage(img);
     return img;
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Converts a DDS file into a TEX file then imports it
        /// </summary>
        /// <param name="xivTex">The texture data</param>
        /// <param name="item">The item who's texture we are importing</param>
        /// <param name="ddsFileDirectory">The directory of the dds file being imported</param>
        /// <returns>The offset to the new imported data</returns>
        public long TexDDSImporter(XivTex xivTex, IItem item, DirectoryInfo ddsFileDirectory)
        {
            int     lineNum = 0, offset = 0;
            var     inModList = false;
            ModInfo modInfo   = null;

            var dat = new Dat(_gameDirectory);

            if (File.Exists(ddsFileDirectory.FullName))
            {
                // Check if the texture being imported has been imported before
                using (var sr = new StreamReader(_modListDirectory.FullName))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        modInfo = JsonConvert.DeserializeObject <ModInfo>(line);
                        if (modInfo.fullPath.Equals(xivTex.TextureTypeAndPath.Path))
                        {
                            inModList = true;
                            break;
                        }
                        lineNum++;
                    }
                }

                using (var br = new BinaryReader(File.OpenRead(ddsFileDirectory.FullName)))
                {
                    br.BaseStream.Seek(12, SeekOrigin.Begin);

                    var newHeight = br.ReadInt32();
                    var newWidth  = br.ReadInt32();
                    br.ReadBytes(8);
                    var newMipCount = br.ReadInt32();

                    if (newHeight % 2 != 0 || newWidth % 2 != 0)
                    {
                        throw new Exception("Resolution must be a multiple of 2");
                    }

                    br.BaseStream.Seek(80, SeekOrigin.Begin);

                    var          textureFlags = br.ReadInt32();
                    var          texType      = br.ReadInt32();
                    XivTexFormat textureType;

                    if (DDSType.ContainsKey(texType))
                    {
                        textureType = DDSType[texType];
                    }
                    else
                    {
                        throw new Exception($"DDS Type ({texType}) not recognized.");
                    }

                    switch (textureFlags)
                    {
                    case 2 when textureType == XivTexFormat.A8R8G8B8:
                        textureType = XivTexFormat.A8;
                        break;

                    case 65 when textureType == XivTexFormat.A8R8G8B8:
                        var bpp = br.ReadInt32();
                        if (bpp == 32)
                        {
                            textureType = XivTexFormat.A8R8G8B8;
                        }
                        else
                        {
                            var red = br.ReadInt32();

                            switch (red)
                            {
                            case 31744:
                                textureType = XivTexFormat.A1R5G5B5;
                                break;

                            case 3840:
                                textureType = XivTexFormat.A4R4G4B4;
                                break;
                            }
                        }

                        break;
                    }

                    if (textureType == xivTex.TextureFormat)
                    {
                        var newTex = new List <byte>();

                        var uncompressedLength = (int)new FileInfo(ddsFileDirectory.FullName).Length - 128;

                        var DDSInfo = DDS.ReadDDS(br, xivTex, newWidth, newHeight, newMipCount);

                        newTex.AddRange(dat.MakeType4DatHeader(xivTex, DDSInfo.mipPartOffsets, DDSInfo.mipPartCounts, uncompressedLength, newMipCount, newWidth, newHeight));
                        newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                        newTex.AddRange(DDSInfo.compressedDDS);

                        offset = dat.WriteToDat(newTex, modInfo, inModList, xivTex.TextureTypeAndPath.Path,
                                                item.ItemCategory, item.Name, lineNum, xivTex.TextureTypeAndPath.DataFile);
                    }
                    else
                    {
                        throw new Exception($"Incorrect file type. Expected: {xivTex.TextureFormat}  Given: {textureType}");
                    }
                }
            }
            else
            {
                throw new IOException($"Could not find file: {ddsFileDirectory.FullName}");
            }

            return(offset);
        }
Ejemplo n.º 12
0
        public async Task <int> TexBMPImporter(XivTex xivTex, IItem item, DirectoryInfo bmpFileDirectory, string source)
        {
            var offset = 0;

            var modding = new Modding(_gameDirectory);

            if (File.Exists(bmpFileDirectory.FullName))
            {
                // Check if the texture being imported has been imported before
                var modEntry = await modding.TryGetModEntry(xivTex.TextureTypeAndPath.Path);

                using (var magickImage = new MagickImage(bmpFileDirectory.FullName))
                {
                    switch (xivTex.TextureFormat)
                    {
                    case XivTexFormat.DXT1:
                        magickImage.Format = MagickFormat.Dxt1;
                        break;

                    case XivTexFormat.DXT5:
                        magickImage.Format = MagickFormat.Dxt5;
                        break;

                    case XivTexFormat.A8R8G8B8:
                        magickImage.Format = MagickFormat.Dds;
                        magickImage.Settings.SetDefines(new DdsWriteDefines
                        {
                            Compression = DdsCompression.None
                        });
                        break;

                    default:
                        throw new Exception($"Format {xivTex.TextureFormat} is not currently supported for BMP import\n\nPlease use the DDS import option instead.");
                    }

                    var data = magickImage.ToByteArray();

                    using (var br = new BinaryReader(new MemoryStream(data)))
                    {
                        br.BaseStream.Seek(12, SeekOrigin.Begin);

                        var newHeight = br.ReadInt32();
                        var newWidth  = br.ReadInt32();
                        br.ReadBytes(8);
                        var newMipCount = br.ReadInt32();

                        if (newHeight % 2 != 0 || newWidth % 2 != 0)
                        {
                            throw new Exception("Resolution must be a multiple of 2");
                        }

                        br.BaseStream.Seek(80, SeekOrigin.Begin);

                        var          textureFlags = br.ReadInt32();
                        var          texType      = br.ReadInt32();
                        XivTexFormat textureType;

                        if (DDSType.ContainsKey(texType))
                        {
                            textureType = DDSType[texType];
                        }
                        else
                        {
                            throw new Exception($"DDS Type ({texType}) not recognized.");
                        }

                        switch (textureFlags)
                        {
                        case 2 when textureType == XivTexFormat.A8R8G8B8:
                            textureType = XivTexFormat.A8;
                            break;

                        case 65 when textureType == XivTexFormat.A8R8G8B8:
                            var bpp = br.ReadInt32();
                            if (bpp == 32)
                            {
                                textureType = XivTexFormat.A8R8G8B8;
                            }
                            else
                            {
                                var red = br.ReadInt32();

                                switch (red)
                                {
                                case 31744:
                                    textureType = XivTexFormat.A1R5G5B5;
                                    break;

                                case 3840:
                                    textureType = XivTexFormat.A4R4G4B4;
                                    break;
                                }
                            }

                            break;
                        }

                        if (textureType == xivTex.TextureFormat)
                        {
                            var uncompressedLength = data.Length;
                            var newTex             = new List <byte>();

                            if (!xivTex.TextureTypeAndPath.Path.Contains(".atex"))
                            {
                                var DDSInfo = await DDS.ReadDDS(br, xivTex, newWidth, newHeight, newMipCount);

                                newTex.AddRange(_dat.MakeType4DatHeader(xivTex, DDSInfo.mipPartOffsets, DDSInfo.mipPartCounts, uncompressedLength, newMipCount, newWidth, newHeight));
                                newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                                newTex.AddRange(DDSInfo.compressedDDS);

                                offset = await _dat.WriteToDat(newTex, modEntry, xivTex.TextureTypeAndPath.Path,
                                                               item.ItemCategory, item.Name, xivTex.TextureTypeAndPath.DataFile, source, 4);
                            }
                            else
                            {
                                br.BaseStream.Seek(128, SeekOrigin.Begin);
                                newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount));
                                newTex.AddRange(br.ReadBytes(uncompressedLength));

                                offset = await _dat.ImportType2Data(newTex.ToArray(), item.Name, xivTex.TextureTypeAndPath.Path,
                                                                    item.ItemCategory, source);
                            }
                        }
                        else
                        {
                            throw new Exception($"Incorrect file type. Expected: {xivTex.TextureFormat}  Given: {textureType}");
                        }
                    }
                }
            }
            else
            {
                throw new IOException($"Could not find file: {bmpFileDirectory.FullName}");
            }

            return(offset);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Imports a ColorSet file
        /// </summary>
        /// <param name="xivMtrl">The XivMtrl data of the original</param>
        /// <param name="ddsFileDirectory">The dds directory of the new ColorSet</param>
        /// <param name="item">The item</param>
        /// <param name="source">The source importing the file</param>
        /// <returns>The new offset</returns>
        public async Task <int> TexColorImporter(XivMtrl xivMtrl, DirectoryInfo ddsFileDirectory, IItem item, string source, XivLanguage lang)
        {
            var colorSetData = new List <Half>();

            byte[] colorSetExtraData = null;

            using (var br = new BinaryReader(File.OpenRead(ddsFileDirectory.FullName)))
            {
                // Check DDS type
                br.BaseStream.Seek(84, SeekOrigin.Begin);

                var          texType = br.ReadInt32();
                XivTexFormat textureType;

                if (DDSType.ContainsKey(texType))
                {
                    textureType = DDSType[texType];
                }
                else
                {
                    throw new Exception($"DDS Type ({texType}) not recognized. Expecting A16B16G16R16F.");
                }

                if (textureType != XivTexFormat.A16B16G16R16F)
                {
                    throw new Exception($"Incorrect file type. Expected: A16B16G16R16F  Given: {textureType}");
                }

                // Skip past rest of the DDS header
                br.BaseStream.Seek(128, SeekOrigin.Begin);

                // color data is always 512 (4w x 16h = 64 x 8bpp = 512)
                // this reads 256 ushort values which is 256 x 2 = 512
                for (var i = 0; i < 256; i++)
                {
                    colorSetData.Add(new Half(br.ReadUInt16()));
                }
            }

            // If the colorset size is 544, it contains extra data that must be imported
            if (xivMtrl.ColorSetDataSize == 544)
            {
                var flagsPath = Path.Combine(Path.GetDirectoryName(ddsFileDirectory.FullName), (Path.GetFileNameWithoutExtension(ddsFileDirectory.FullName) + ".dat"));

                if (File.Exists(flagsPath))
                {
                    // The extra data after the colorset is always 32 bytes
                    // This reads 16 ushort values which is 16 x 2 = 32
                    colorSetExtraData = File.ReadAllBytes(flagsPath);

                    // If for whatever reason there is a .dat file but it's missing data
                    if (colorSetExtraData.Length != 32)
                    {
                        // Set all dye modifiers to 0 (undyeable)
                        colorSetExtraData = new byte[32];
                    }
                }
                else
                {
                    // If .dat file is missing set all values to 0 (undyeable)
                    colorSetExtraData = new byte[32];
                }
            }

            // Replace the color set data with the imported data
            xivMtrl.ColorSetData      = colorSetData;
            xivMtrl.ColorSetExtraData = colorSetExtraData;

            var mtrl = new Mtrl(_gameDirectory, xivMtrl.TextureTypePathList[0].DataFile, lang);

            return(await mtrl.ImportMtrl(xivMtrl, item, source));
        }
Ejemplo n.º 14
0
        public File(uint width, uint height, int mipMaps, DDSType type, byte[] source, bool isNormalMap = false)
        {
            header = new byte[0x80];
            FileHelper.SetString(DDS_MAGIC, 0, header);
            Header            = new Header(header);
            Header.Size       = 0x7C;
            Header.Flags      = DDSFlags.CAPS | DDSFlags.HEIGHT | DDSFlags.WIDTH | DDSFlags.PIXELFORMAT;
            Header.Height     = height;
            Header.Width      = width;
            Header.Caps       = DDSCaps.TEXTURE;
            Header.DDSPF.Size = 0x20;
            switch (type)
            {
            case DDS.DDSType.A8R8G8B8:
                Header.DDSPF.Flags    = DDSPixelFormatFlags.ALPHAPIXELS | DDSPixelFormatFlags.RGB;
                Header.DDSPF.BitCount = 0x20;
                Header.DDSPF.RBitMask = 0x00FF0000;
                Header.DDSPF.GBitMask = 0x0000FF00;
                Header.DDSPF.BBitMask = 0x000000FF;
                Header.DDSPF.ABitMask = 0xFF000000;
                break;

            case DDS.DDSType.A1R5G5B5:
                Header.DDSPF.Flags    = DDSPixelFormatFlags.ALPHAPIXELS | DDSPixelFormatFlags.RGB;
                Header.DDSPF.BitCount = 0x10;
                Header.DDSPF.RBitMask = 0x00007C00;
                Header.DDSPF.GBitMask = 0x000003E0;
                Header.DDSPF.BBitMask = 0x0000001F;
                Header.DDSPF.ABitMask = 0x00008000;
                break;

            case DDS.DDSType.A4R4G4B4:
                Header.DDSPF.Flags    = DDSPixelFormatFlags.ALPHAPIXELS | DDSPixelFormatFlags.RGB;
                Header.DDSPF.BitCount = 0x10;
                Header.DDSPF.RBitMask = 0x00000F00;
                Header.DDSPF.GBitMask = 0x000000F0;
                Header.DDSPF.BBitMask = 0x0000000F;
                Header.DDSPF.ABitMask = 0x0000F000;
                break;

            case DDS.DDSType.R8G8B8:
                Header.DDSPF.Flags    = DDSPixelFormatFlags.RGB;
                Header.DDSPF.BitCount = 0x18;
                Header.DDSPF.RBitMask = 0x00FF0000;
                Header.DDSPF.GBitMask = 0x0000FF00;
                Header.DDSPF.BBitMask = 0x000000FF;
                Header.DDSPF.ABitMask = 0x00000000;
                break;

            case DDS.DDSType.R5G6B5:
                Header.DDSPF.Flags    = DDSPixelFormatFlags.RGB;
                Header.DDSPF.BitCount = 0x10;
                Header.DDSPF.RBitMask = 0x0000F800;
                Header.DDSPF.GBitMask = 0x000007E0;
                Header.DDSPF.BBitMask = 0x0000001F;
                Header.DDSPF.ABitMask = 0x00000000;
                break;

            case DDS.DDSType.R5G5B5:
                Header.DDSPF.Flags    = DDSPixelFormatFlags.RGB;
                Header.DDSPF.BitCount = 0x10;
                Header.DDSPF.RBitMask = 0x00007C00;
                Header.DDSPF.GBitMask = 0x000003E0;
                Header.DDSPF.BBitMask = 0x0000001F;
                Header.DDSPF.ABitMask = 0x00000000;
                break;

            case DDS.DDSType.DXT1:
                Header.DDSPF.Flags  = DDSPixelFormatFlags.FOURCC;
                Header.DDSPF.FourCC = "DXT1";
                break;

            case DDS.DDSType.DXT3:
                Header.DDSPF.Flags  = DDSPixelFormatFlags.FOURCC;
                Header.DDSPF.FourCC = "DXT3";
                break;

            case DDS.DDSType.DXT5:
                Header.DDSPF.Flags  = DDSPixelFormatFlags.FOURCC;
                Header.DDSPF.FourCC = "DXT5";
                break;
            }
            if (mipMaps > 1)
            {
                Header.Flags            |= DDSFlags.MIPMAPCOUNT | DDSFlags.LINEARSIZE;
                Header.PitchOrLinearSize = width * height * (Header.DDSPF.BitCount >> 3);
                Header.MipMapCount       = (uint)mipMaps;
                Header.Caps |= DDSCaps.COMPLEX | DDSCaps.MIPMAP;
            }
            ARGBMask mask = new ARGBMask(new uint[] { Header.DDSPF.ABitMask, Header.DDSPF.RBitMask, Header.DDSPF.GBitMask, Header.DDSPF.BBitMask });

            switch (type)
            {
            case DDS.DDSType.A8R8G8B8:
                Content = new ColorA8R8G8B8(mask, isNormalMap);
                break;

            case DDS.DDSType.A1R5G5B5:
                Content = new ColorA1R5G5B5(mask, isNormalMap);
                break;

            case DDS.DDSType.A4R4G4B4:
                Content = new ColorA4R4G4B4(mask, isNormalMap);
                break;

            case DDS.DDSType.R8G8B8:
                Content = new ColorR8G8B8(mask, isNormalMap);
                break;

            case DDS.DDSType.R5G6B5:
                Content = new ColorR5G6B5(mask, isNormalMap);
                break;

            case DDS.DDSType.R5G5B5:
                Content = new ColorR5G5B5(mask, isNormalMap);
                break;

            case DDS.DDSType.DXT1:
                Content = new ColorDXT1(mask, isNormalMap);
                break;

            case DDS.DDSType.DXT3:
                Content = new ColorDXT3(mask, isNormalMap);
                break;

            case DDS.DDSType.DXT5:
                Content = new ColorDXT5(mask, isNormalMap);
                break;
            }
            content = Content.CompressColor(source, width, height, mipMaps);
        }