コード例 #1
0
ファイル: TEX.cs プロジェクト: viion-misc/FFXIV_TexTools2
        public static TEXData GetVFX(int offset, string datName)
        {
            int datNum = ((offset / 8) & 0x0F) / 2;

            var VFXData = Helper.GetType2DecompressedData(offset, datNum, datName);

            TEXData texData = new TEXData();

            texData.TexOffset = offset;

            using (BinaryReader br = new BinaryReader(new MemoryStream(VFXData)))
            {
                br.BaseStream.Seek(4, SeekOrigin.Begin);

                texData.Type   = br.ReadInt32();
                texData.Width  = br.ReadInt16();
                texData.Height = br.ReadInt16();

                br.ReadBytes(2);

                texData.MipCount = br.ReadInt16();

                br.ReadBytes(64);

                var rawData = br.ReadBytes(VFXData.Length - 80);

                texData.TypeString = Info.TextureTypes[texData.Type];
                TextureToBitmap(rawData, texData);

                texData.TEXDatName = datName;
            }

            return(texData);
        }
コード例 #2
0
        /// <summary>
        /// Creates the header for the texture info from the data to be imported.
        /// </summary>
        /// <param name="texData">Data for the currently displayed texture.</param>
        /// <param name="newWidth">The width of the DDS texture to be imported.</param>
        /// <param name="newHeight">The height of the DDS texture to be imported.</param>
        /// <param name="newMipCount">The number of mipmaps the DDS texture to be imported contains.</param>
        /// <returns>The created header data.</returns>
        private static List <byte> MakeTextureInfoHeader(TEXData texData, int newWidth, int newHeight, int newMipCount)
        {
            List <byte> headerData = new List <byte>();

            headerData.AddRange(BitConverter.GetBytes((short)0));
            headerData.AddRange(BitConverter.GetBytes((short)128));
            headerData.AddRange(BitConverter.GetBytes((short)texData.Type));
            headerData.AddRange(BitConverter.GetBytes((short)0));
            headerData.AddRange(BitConverter.GetBytes((short)newWidth));
            headerData.AddRange(BitConverter.GetBytes((short)newHeight));
            headerData.AddRange(BitConverter.GetBytes((short)1));
            headerData.AddRange(BitConverter.GetBytes((short)newMipCount));


            headerData.AddRange(BitConverter.GetBytes(0));
            headerData.AddRange(BitConverter.GetBytes(1));
            headerData.AddRange(BitConverter.GetBytes(2));

            int mipLength;

            if (texData.Type == TextureTypes.DXT1)
            {
                mipLength = (newWidth * newHeight) / 2;
            }
            else if (texData.Type == TextureTypes.DXT5 || texData.Type == TextureTypes.A8)
            {
                mipLength = newWidth * newHeight;
            }
            else if (texData.Type == TextureTypes.A1R5G5B5 || texData.Type == TextureTypes.A4R4G4B4)
            {
                mipLength = (newWidth * newHeight) * 2;
            }
            else
            {
                mipLength = (newWidth * newHeight) * 4;
            }

            int combinedLength = 80;

            for (int i = 0; i < newMipCount; i++)
            {
                headerData.AddRange(BitConverter.GetBytes(combinedLength));
                combinedLength = combinedLength + mipLength;

                if (mipLength > 16)
                {
                    mipLength = mipLength / 4;
                }
                else
                {
                    mipLength = 16;
                }
            }

            int padding = 80 - headerData.Count;

            headerData.AddRange(new byte[padding]);

            return(headerData);
        }
コード例 #3
0
ファイル: TEX.cs プロジェクト: viion-misc/FFXIV_TexTools2
        /// <summary>
        /// Creates a bitmap from the texture data.
        /// </summary>
        /// <param name="decompressedData">The decompressed data of the texture.</param>
        /// <param name="textureType">The textures type.</param>
        /// <param name="width">The textures width.</param>
        /// <param name="height">The textures height.</param>
        /// <returns>The created bitmap.</returns>
        //public static Bitmap TextureToBitmap(byte[] decompressedData, int textureType, int width, int height)
        public static void TextureToBitmap(byte[] decompressedData, TEXData texData)
        {
            BitmapSource bmpSource;
            var          width  = texData.Width;
            var          height = texData.Height;
            Tuple <BitmapSource, BitmapSource> bmps = null;

            byte[] decompressedTextureData;

            switch (texData.Type)
            {
            case TextureTypes.DXT1:
                decompressedTextureData = DxtUtil.DecompressDxt1(decompressedData, width, height);
                bmps = Read32bitBitmapImageAlphaDXT(decompressedTextureData, width, height);
                break;

            case TextureTypes.DXT3:
                decompressedTextureData = DxtUtil.DecompressDxt3(decompressedData, width, height);
                bmps = Read32bitBitmapImageAlphaDXT(decompressedTextureData, width, height);
                break;

            case TextureTypes.DXT5:
                decompressedTextureData = DxtUtil.DecompressDxt5(decompressedData, width, height);
                bmps = Read32bitBitmapImageAlphaDXT(decompressedTextureData, width, height);
                break;

            case TextureTypes.A8:
            case TextureTypes.L8:
                bmpSource = Read8bitBitmapImage(decompressedData, width, height);
                bmps      = new Tuple <BitmapSource, BitmapSource>(bmpSource, bmpSource);
                break;

            case TextureTypes.A4R4G4B4:
                bmps = Read4444BMPSource(decompressedData, width, height);
                break;

            case TextureTypes.A1R5G5B5:
                bmps = Read5551BMPSource(decompressedData, width, height);
                break;

            case TextureTypes.A8R8G8B8:
            case TextureTypes.X8R8G8B8:
                bmps = Read32bitBitmapImageAlpha(decompressedData, width, height);
                break;
                //case TextureTypes.A16B16G16R16F:
                //    bmp = ReadRGBAFImage(decompressedData, width, height);
                //    break;
            }

            texData.BMPSouceAlpha   = bmps.Item1;
            texData.BMPSouceNoAlpha = bmps.Item2;
        }
コード例 #4
0
        /// <summary>
        /// Updates the displayed image
        /// </summary>
        /// <remarks>
        /// This is called when an image has either been imported or enabled/disabled
        /// </remarks>
        /// <param name="offset">The new offset for the image.</param>
        /// <param name="isColor">Is the image being udpated a color set.</param>
        public void UpdateImage(int offset, bool isColor)
        {
            if (isColor)
            {
                var colorBMP = MTRL.GetColorBitmap(offset);

                TextureType       = "A16B16G16R16F";
                TextureDimensions = "(4 x 16)";

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                var removeAlphaBitmap = SetAlpha(colorBMP, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                colorBMP.Dispose();
                removeAlphaBitmap.Dispose();
            }
            else
            {
                if (SelectedMap.ID.Contains("vfx"))
                {
                    texData = TEX.GetVFX(offset);
                }
                else
                {
                    texData = TEX.GetTex(offset);
                }

                TextureType       = texData.TypeString;
                TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")";

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                var removeAlphaBitmap = SetAlpha(texData.BMP, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                texData.Dispose();
                removeAlphaBitmap.Dispose();
            }

            if (AlphaChecked)
            {
                ImageSource = alphaBitmap;
            }
            else
            {
                ImageSource = noAlphaBitmap;
            }
        }
コード例 #5
0
ファイル: TEX.cs プロジェクト: viion-misc/FFXIV_TexTools2
        public static byte[] GetRawVFX(TEXData td)
        {
            int datNum = ((td.TexOffset / 8) & 0x0F) / 2;

            var VFXData = Helper.GetType2DecompressedData(td.TexOffset, datNum, td.TEXDatName);

            using (BinaryReader br = new BinaryReader(new MemoryStream(VFXData)))
            {
                br.BaseStream.Seek(4, SeekOrigin.Begin);

                var type   = br.ReadInt32();
                var width  = br.ReadInt16();
                var height = br.ReadInt16();

                br.ReadBytes(2);

                var mipCount = br.ReadInt16();

                br.ReadBytes(64);

                return(br.ReadBytes(VFXData.Length - 80));
            }
        }
コード例 #6
0
        /// <summary>
        /// Reads and parses data from the DDS file to be imported.
        /// </summary>
        /// <param name="br">The currently active BinaryReader.</param>
        /// <param name="texData">Data for the currently displayed texture.</param>
        /// <param name="newWidth">The width of the DDS texture to be imported.</param>
        /// <param name="newHeight">The height of the DDS texture to be imported.</param>
        /// <param name="newMipCount">The number of mipmaps the DDS texture to be imported contains.</param>
        /// <returns>A tuple containing the compressed DDS data, a list of offsets to the mipmap parts, a list with the number of parts per mipmap.</returns>
        private static Tuple <List <byte>, List <short>, List <short> > ReadDDS(BinaryReader br, TEXData texData, int newWidth, int newHeight, int newMipCount)
        {
            List <byte>  compressedDDS  = new List <byte>();
            List <short> mipPartOffsets = new List <short>();
            List <short> mipPartCount   = new List <short>();

            int mipLength;

            if (texData.Type == TextureTypes.DXT1)
            {
                mipLength = (newWidth * newHeight) / 2;
            }
            else if (texData.Type == TextureTypes.DXT5 || texData.Type == TextureTypes.A8)
            {
                mipLength = newWidth * newHeight;
            }
            else if (texData.Type == TextureTypes.A1R5G5B5 || texData.Type == TextureTypes.A4R4G4B4)
            {
                mipLength = (newWidth * newHeight) * 2;
            }
            else
            {
                mipLength = (newWidth * newHeight) * 4;
            }


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

            for (int i = 0; i < newMipCount; i++)
            {
                int mipParts = (int)Math.Ceiling(mipLength / 16000f);
                mipPartCount.Add((short)mipParts);

                if (mipParts > 1)
                {
                    for (int j = 0; j < mipParts; j++)
                    {
                        int    uncompLength;
                        byte[] compressed;
                        bool   comp = true;

                        if (j == mipParts - 1)
                        {
                            uncompLength = mipLength % 16000;
                        }
                        else
                        {
                            uncompLength = 16000;
                        }

                        var uncompBytes = br.ReadBytes(uncompLength);
                        compressed = Compressor(uncompBytes);

                        if (compressed.Length > uncompLength)
                        {
                            compressed = uncompBytes;
                            comp       = false;
                        }

                        compressedDDS.AddRange(BitConverter.GetBytes(16));
                        compressedDDS.AddRange(BitConverter.GetBytes(0));

                        if (!comp)
                        {
                            compressedDDS.AddRange(BitConverter.GetBytes(32000));
                        }
                        else
                        {
                            compressedDDS.AddRange(BitConverter.GetBytes(compressed.Length));
                        }

                        compressedDDS.AddRange(BitConverter.GetBytes(uncompLength));
                        compressedDDS.AddRange(compressed);

                        int padding = 128 - (compressed.Length % 128);

                        compressedDDS.AddRange(new byte[padding]);

                        mipPartOffsets.Add((short)(compressed.Length + padding + 16));
                    }
                }
                else
                {
                    int    uncompLength;
                    byte[] compressed;
                    bool   comp = true;

                    if (mipLength != 16000)
                    {
                        uncompLength = mipLength % 16000;
                    }
                    else
                    {
                        uncompLength = 16000;
                    }

                    var uncompBytes = br.ReadBytes(uncompLength);
                    compressed = Compressor(uncompBytes);

                    if (compressed.Length > uncompLength)
                    {
                        compressed = uncompBytes;
                        comp       = false;
                    }

                    compressedDDS.AddRange(BitConverter.GetBytes(16));
                    compressedDDS.AddRange(BitConverter.GetBytes(0));

                    if (!comp)
                    {
                        compressedDDS.AddRange(BitConverter.GetBytes(32000));
                    }
                    else
                    {
                        compressedDDS.AddRange(BitConverter.GetBytes(compressed.Length));
                    }

                    compressedDDS.AddRange(BitConverter.GetBytes(uncompLength));
                    compressedDDS.AddRange(compressed);

                    int padding = 128 - (compressed.Length % 128);

                    compressedDDS.AddRange(new byte[padding]);

                    mipPartOffsets.Add((short)(compressed.Length + padding + 16));
                }

                if (mipLength > 32)
                {
                    mipLength = mipLength / 4;
                }
                else
                {
                    mipLength = 8;
                }
            }

            return(new Tuple <List <byte>, List <short>, List <short> >(compressedDDS, mipPartOffsets, mipPartCount));
        }
コード例 #7
0
        /// <summary>
        /// Imports the items texture into a dat file
        /// </summary>
        /// <param name="texData">Data for the currently displayed texture</param>
        /// <param name="category">The items category</param>
        /// <param name="itemName">The items name</param>
        /// <param name="internalFilePath">The internal file path of the texture map</param>
        /// <returns>The offset in which the data was placed</returns>
        public static int ImportTexture(TEXData texData, string category, string subCategory, string itemName, string internalFilePath)
        {
            int       textureType, lineNum = 0, offset = 0;
            bool      inModList = false;
            JsonEntry modEntry  = null;

            string dxPath   = Path.GetFileNameWithoutExtension(internalFilePath);
            var    savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + dxPath + ".dds";

            if (category.Equals("UI"))
            {
                savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + subCategory + "/" + dxPath + ".dds";
            }


            if (File.Exists(savePath))
            {
                try
                {
                    using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                            if (modEntry.fullPath.Equals(internalFilePath))
                            {
                                inModList = true;
                                break;
                            }
                            lineNum++;
                        }
                    }
                }
                catch (Exception ex)
                {
                    FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

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

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

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

                    var textureFlags = br.ReadInt32();
                    var texType      = br.ReadInt32();
                    try
                    {
                        textureType = Info.DDSType[texType];
                    }
                    catch (Exception e)
                    {
                        FlexibleMessageBox.Show("DDS Type (" + texType + ") not recognized \n" + e.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return(0);
                    }

                    if (textureFlags == 2 && textureType == 5200)
                    {
                        textureType = TextureTypes.A8;
                    }
                    else if (textureFlags == 65 && textureType == 5200)
                    {
                        int bpp = br.ReadInt32();
                        if (bpp == 32)
                        {
                            textureType = TextureTypes.A8R8G8B8;
                        }
                        else
                        {
                            int red = br.ReadInt32();

                            if (red == 31744)
                            {
                                textureType = TextureTypes.A1R5G5B5;
                            }
                            else if (red == 3840)
                            {
                                textureType = TextureTypes.A4R4G4B4;
                            }
                        }
                    }

                    if (textureType == texData.Type)
                    {
                        List <byte> newTEX = new List <byte>();

                        int uncompressedLength = (int)new FileInfo(savePath).Length - 128;

                        var DDSInfo = ReadDDS(br, texData, newWidth, newHeight, newMipCount);

                        newTEX.AddRange(MakeType4DATHeader(texData, DDSInfo.Item2, DDSInfo.Item3, uncompressedLength, newMipCount, newWidth, newHeight));
                        newTEX.AddRange(MakeTextureInfoHeader(texData, newWidth, newHeight, newMipCount));
                        newTEX.AddRange(DDSInfo.Item1);

                        offset = WriteToDat(newTEX, modEntry, inModList, internalFilePath, category, itemName, lineNum, texData.TEXDatName);
                    }
                    else
                    {
                        FlexibleMessageBox.Show("Incorrect file type \nExpected: " + Info.TextureTypes[texData.Type] + " Given: " + Info.TextureTypes[textureType], "Texture format error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            else
            {
                FlexibleMessageBox.Show("Could not find file \n" + savePath, "File read Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return(offset);
        }
コード例 #8
0
        /// <summary>
        /// Imports VFX files
        /// </summary>
        /// <param name="category">The category of the item</param>
        /// <param name="itemName">The selected items name</param>
        /// <param name="internalFilePath">The full path of the internal file</param>
        public static int ImportVFX(TEXData texData, string category, string itemName, string internalFilePath)
        {
            JsonEntry modEntry = null;
            int       textureType, newHeight, newWidth, newMipCount;
            int       lineNum   = 0;
            int       newOffset = 0;
            bool      inModList = false;

            string dxPath   = Path.GetFileNameWithoutExtension(internalFilePath);
            var    savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + dxPath + ".dds";

            if (File.Exists(savePath))
            {
                List <byte> newVFX          = new List <byte>();
                List <byte> uncompressedVFX = new List <byte>();
                List <byte> headerData      = new List <byte>();
                List <byte> dataBlocks      = new List <byte>();

                try
                {
                    using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                            if (modEntry.fullPath.Equals(internalFilePath))
                            {
                                inModList = true;
                                break;
                            }
                            lineNum++;
                        }
                    }
                }
                catch (Exception ex)
                {
                    FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }


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

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

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

                    var textureFlags = br.ReadInt32();

                    textureType = Info.DDSType[br.ReadInt32()];

                    if (textureFlags == 2 && textureType == 5200)
                    {
                        textureType = TextureTypes.A8;
                    }

                    if (textureType == texData.Type)
                    {
                        br.BaseStream.Seek(128, SeekOrigin.Begin);

                        uncompressedVFX.AddRange(MakeTextureInfoHeader(texData, newWidth, newHeight, newMipCount));

                        int dataLength = (int)new FileInfo(savePath).Length - 128;

                        uncompressedVFX.AddRange(br.ReadBytes(dataLength));
                    }
                    else
                    {
                        FlexibleMessageBox.Show("Incorrect file type \nExpected: " + Info.TextureTypes[texData.Type] + " Given: " + Info.TextureTypes[textureType], "Texture format error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return(0);
                    }
                }

                headerData.AddRange(BitConverter.GetBytes(128));
                headerData.AddRange(BitConverter.GetBytes(2));
                headerData.AddRange(BitConverter.GetBytes(uncompressedVFX.Count));

                int dataOffset         = 0;
                int totalCompSize      = 0;
                int uncompressedLength = uncompressedVFX.Count;

                int partCount = (int)Math.Ceiling(uncompressedLength / 16000f);

                headerData.AddRange(BitConverter.GetBytes(partCount));

                int remainder = uncompressedLength;

                using (BinaryReader br = new BinaryReader(new MemoryStream(uncompressedVFX.ToArray())))
                {
                    br.BaseStream.Seek(0, SeekOrigin.Begin);

                    for (int i = 1; i <= partCount; i++)
                    {
                        if (i == partCount)
                        {
                            var compData = Compressor(br.ReadBytes(remainder));
                            int padding  = 128 - ((compData.Length + 16) % 128);

                            dataBlocks.AddRange(BitConverter.GetBytes(16));
                            dataBlocks.AddRange(BitConverter.GetBytes(0));
                            dataBlocks.AddRange(BitConverter.GetBytes(compData.Length));
                            dataBlocks.AddRange(BitConverter.GetBytes(remainder));
                            dataBlocks.AddRange(compData);
                            dataBlocks.AddRange(new byte[padding]);

                            headerData.AddRange(BitConverter.GetBytes(dataOffset));
                            headerData.AddRange(BitConverter.GetBytes((short)((compData.Length + 16) + padding)));
                            headerData.AddRange(BitConverter.GetBytes((short)remainder));

                            totalCompSize = dataOffset + ((compData.Length + 16) + padding);
                        }
                        else
                        {
                            var compData = Compressor(br.ReadBytes(16000));
                            int padding  = 128 - ((compData.Length + 16) % 128);

                            dataBlocks.AddRange(BitConverter.GetBytes(16));
                            dataBlocks.AddRange(BitConverter.GetBytes(0));
                            dataBlocks.AddRange(BitConverter.GetBytes(compData.Length));
                            dataBlocks.AddRange(BitConverter.GetBytes(16000));
                            dataBlocks.AddRange(compData);
                            dataBlocks.AddRange(new byte[padding]);

                            headerData.AddRange(BitConverter.GetBytes(dataOffset));
                            headerData.AddRange(BitConverter.GetBytes((short)((compData.Length + 16) + padding)));
                            headerData.AddRange(BitConverter.GetBytes((short)16000));

                            dataOffset += ((compData.Length + 16) + padding);
                            remainder  -= 16000;
                        }
                    }
                }

                headerData.InsertRange(12, BitConverter.GetBytes(totalCompSize / 128));
                headerData.InsertRange(16, BitConverter.GetBytes(totalCompSize / 128));

                int headerPadding = 128 - headerData.Count;

                headerData.AddRange(new byte[headerPadding]);

                newVFX.AddRange(headerData);
                newVFX.AddRange(dataBlocks);

                newOffset = WriteToDat(newVFX, modEntry, inModList, internalFilePath, category, itemName, lineNum, texData.TEXDatName);
            }
            return(newOffset);
        }
コード例 #9
0
        /// <summary>
        /// Gets the texture data and displays it for the currently selected item given a specified race, part, type(if applicable), and map
        /// </summary>
        private void MapComboBoxChanged()
        {
            if (saveClone != null)
            {
                //saveClone.UnlockBits(cloneLock);
                saveClone.Dispose();
            }

            Bitmap colorBmp = null;
            int    offset   = 0;
            bool   isVFX    = false;
            bool   isUI     = false;

            if (selectedMap.Name.Equals(Strings.Normal))
            {
                fullPath       = mtrlData.NormalPath;
                offset         = mtrlData.NormalOffset;
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.Specular))
            {
                fullPath       = mtrlData.SpecularPath;
                offset         = mtrlData.SpecularOffset;
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.Diffuse))
            {
                fullPath       = mtrlData.DiffusePath;
                offset         = mtrlData.DiffuseOffset;
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.Mask) || selectedMap.Name.Equals(Strings.Skin))
            {
                if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                {
                    string part;
                    if (selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                    {
                        if (!SelectedPart.Name.Contains("stigma"))
                        {
                            part = selectedPart.Name.PadLeft(3, '0');
                        }
                        else
                        {
                            part = SelectedPart.Name;
                        }
                    }
                    else
                    {
                        part = selectedPart.Name;
                    }

                    fullPath = String.Format(mtrlData.MaskPath, part);
                    offset   = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name);
                }
                else
                {
                    fullPath = mtrlData.MaskPath;
                    offset   = mtrlData.MaskOffset;
                }
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.ColorSet))
            {
                colorBmp       = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                fullPath       = mtrlData.MTRLPath;
                FullPathString = fullPath;
            }
            else if (SelectedMap.Name.Contains("Icon"))
            {
                if (SelectedMap.Name.Contains("HQ"))
                {
                    fullPath = mtrlData.UIHQPath;
                    offset   = mtrlData.UIHQOffset;
                }
                else
                {
                    fullPath = mtrlData.UIPath;
                    offset   = mtrlData.UIOffset;
                }
                FullPathString = fullPath;
                isUI           = true;
            }
            else if (selectedItem.ItemCategory.Equals(Strings.Maps))
            {
                if (selectedMap.Name.Contains("HighRes Map"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "_m");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("LowRes Map"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "_s");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("PoI"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "d");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("HighRes Mask"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "m_m");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("LowRes Mask"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "m_s");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                FullPathString = fullPath;
                isUI           = true;
            }
            else if (selectedItem.ItemCategory.Equals("HUD") || selectedItem.ItemCategory.Equals("LoadingImage"))
            {
                fullPath       = mtrlData.UIPath;
                offset         = mtrlData.UIOffset;
                FullPathString = fullPath;

                isUI = true;
            }
            else
            {
                fullPath = SelectedMap.ID;
                var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/"));
                var VFXFile   = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                offset = Helper.GetDataOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile), Strings.ItemsDat);

                FullPathString = fullPath;

                isVFX = true;
            }

            string    line;
            JsonEntry modEntry  = null;
            bool      inModList = false;

            try
            {
                using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory))
                {
                    while ((line = sr.ReadLine()) != null)
                    {
                        modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                        if (modEntry.fullPath.Equals(fullPath))
                        {
                            inModList = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("[TVM] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            if (inModList)
            {
                var currOffset = Helper.GetDataOffset(FFCRC.GetHash(modEntry.fullPath.Substring(0, modEntry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(modEntry.fullPath)), modEntry.datFile);

                if (currOffset == modEntry.modOffset)
                {
                    ActiveToggle = "Disable";
                }
                else if (currOffset == modEntry.originalOffset)
                {
                    ActiveToggle = "Enable";
                }
                else
                {
                    ActiveToggle = "Error";
                }

                ActiveEnabled = true;
            }
            else
            {
                ActiveEnabled = false;
                ActiveToggle  = "Enable/Disable";
            }

            if (offset == 0)
            {
                TextureType = "Type: 16.16.16.16f ABGR\nMipMaps: None";

                TextureDimensions = "(4 x 16)";

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                alphaBitmap.Freeze();

                var removeAlphaBitmap = SetAlpha(colorBmp, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                noAlphaBitmap.Freeze();

                colorBmp.Dispose();
                removeAlphaBitmap.Dispose();
            }
            else
            {
                if (!isVFX)
                {
                    if (!isUI)
                    {
                        texData = TEX.GetTex(offset, Strings.ItemsDat);
                    }
                    else
                    {
                        texData = TEX.GetTex(offset, Strings.UIDat);
                    }
                }
                else
                {
                    texData = TEX.GetVFX(offset, Strings.ItemsDat);
                }

                string mipMaps = "Yes (" + texData.MipCount + ")";
                if (texData.MipCount < 1)
                {
                    mipMaps = "None";
                }
                TextureType = "Type: " + texData.TypeString + "\nMipMaps: " + mipMaps;

                TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")";

                var clonerect = new Rectangle(0, 0, texData.Width, texData.Height);
                saveClone = texData.BMP.Clone(new Rectangle(0, 0, texData.Width, texData.Height), PixelFormat.Format32bppArgb);

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                alphaBitmap.Freeze();

                if (!isUI)
                {
                    var removeAlphaBitmap = SetAlpha(texData.BMP, 255);

                    noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                    noAlphaBitmap.Freeze();

                    removeAlphaBitmap.Dispose();
                }
            }


            try
            {
                ImageEffect = new ColorChannels()
                {
                    Channel = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f)
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
            }

            if (!isUI)
            {
                ImageSource = noAlphaBitmap;

                SetColorChannelFilter(imageEffect);

                ChannelsEnabled = true;
            }
            else
            {
                ImageSource = alphaBitmap;

                SetColorChannelFilter(imageEffect);

                ChannelsEnabled = true;
            }

            SaveEnabled = true;

            texData.Dispose();

            string dxPath = Path.GetFileNameWithoutExtension(fullPath);

            string savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName + "/" + dxPath + ".dds";

            if (selectedCategory.Equals("UI"))
            {
                savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemCategory + "/" + dxPath + ".dds";
            }

            if (File.Exists(savePath))
            {
                ImportEnabled = true;
            }
            else
            {
                ImportEnabled = false;
            }

            string folderPath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName;

            if (selectedCategory.Equals("UI"))
            {
                folderPath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemCategory;
            }

            if (Directory.Exists(folderPath))
            {
                OpenEnabled = true;
            }
            else
            {
                OpenEnabled = false;
            }
        }
コード例 #10
0
        public void SaveAllDDS()
        {
            foreach (var m in MapComboBox)
            {
                int offset = 0;

                if (m.Name.Equals(Strings.Normal))
                {
                    fullPath = mtrlData.NormalPath;
                    offset   = mtrlData.NormalOffset;
                }
                else if (m.Name.Equals(Strings.Specular))
                {
                    fullPath = mtrlData.SpecularPath;
                    offset   = mtrlData.SpecularOffset;
                }
                else if (m.Name.Equals(Strings.Diffuse))
                {
                    fullPath = mtrlData.DiffusePath;
                    offset   = mtrlData.DiffuseOffset;
                }
                else if (m.Name.Equals(Strings.Mask) || m.Name.Equals(Strings.Skin))
                {
                    if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                    {
                        string part;
                        if (selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                        {
                            if (!SelectedPart.Name.Contains("stigma"))
                            {
                                part = selectedPart.Name.PadLeft(3, '0');
                            }
                            else
                            {
                                part = SelectedPart.Name;
                            }
                        }
                        else
                        {
                            part = selectedPart.Name;
                        }

                        fullPath = String.Format(mtrlData.MaskPath, part);
                        offset   = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name);
                    }
                    else
                    {
                        fullPath = mtrlData.MaskPath;
                        offset   = mtrlData.MaskOffset;
                    }
                }
                else if (m.Name.Equals(Strings.ColorSet))
                {
                    fullPath = mtrlData.MTRLPath;
                }
                else if (m.Name.Contains("Icon"))
                {
                    if (m.Name.Contains("HQ"))
                    {
                        fullPath = mtrlData.UIHQPath;
                        offset   = mtrlData.UIHQOffset;
                    }
                    else
                    {
                        fullPath = mtrlData.UIPath;
                        offset   = mtrlData.UIOffset;
                    }
                }
                else if (selectedItem.ItemCategory.Equals(Strings.Maps))
                {
                    if (selectedMap.Name.Contains("HighRes Map"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "_m");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("LowRes Map"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "_s");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("PoI"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "d");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("HighRes Mask"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "m_m");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("LowRes Mask"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "m_s");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                }
                else if (selectedItem.ItemCategory.Equals("HUD"))
                {
                    fullPath = mtrlData.UIPath;
                    offset   = mtrlData.UIOffset;
                }
                else
                {
                    fullPath = SelectedMap.ID;
                    var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/"));
                    var VFXFile   = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                    offset = Helper.GetDataOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile), Strings.ItemsDat);
                }

                if (offset != 0)
                {
                    if (m.ID.Contains("vfx"))
                    {
                        texData = TEX.GetVFX(offset, Strings.ItemsDat);
                    }
                    else
                    {
                        if (selectedCategory.Equals("UI"))
                        {
                            texData = TEX.GetTex(offset, Strings.UIDat);
                        }
                        else
                        {
                            texData = TEX.GetTex(offset, Strings.ItemsDat);
                        }
                    }
                }


                SaveTex.SaveDDS(selectedCategory, selectedItem.ItemName, fullPath, m.Name, mtrlData, texData, selectedItem.ItemCategory);
            }
        }
コード例 #11
0
        /// <summary>
        /// Updates the displayed image
        /// </summary>
        /// <remarks>
        /// This is called when an image has either been imported or enabled/disabled
        /// </remarks>
        /// <param name="offset">The new offset for the image.</param>
        /// <param name="isColor">Is the image being udpated a color set.</param>
        public void UpdateImage(int offset, bool isColor)
        {
            try
            {
                if (isColor)
                {
                    var colorBMP = MTRL.GetColorBitmap(offset);

                    TextureType       = "Type: 16.16.16.16f ABGR\nMipMaps: 0";
                    TextureDimensions = "(4 x 16)";

                    alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBMP.Item1.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                    alphaBitmap.Freeze();

                    var removeAlphaBitmap = SetAlpha(colorBMP.Item1, 255);

                    noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                    noAlphaBitmap.Freeze();

                    mtrlData.ColorData = colorBMP.Item2;

                    colorBMP.Item1.Dispose();
                    removeAlphaBitmap.Dispose();
                }
                else
                {
                    if (SelectedMap.ID.Contains("vfx"))
                    {
                        texData = TEX.GetVFX(offset, Strings.ItemsDat);
                    }
                    else
                    {
                        if (selectedCategory.Equals("UI"))
                        {
                            texData = TEX.GetTex(offset, Strings.UIDat);
                        }
                        else
                        {
                            texData = TEX.GetTex(offset, Strings.ItemsDat);
                        }
                    }

                    string mipMaps = "Yes (" + texData.MipCount + ")";
                    if (texData.MipCount < 1)
                    {
                        mipMaps = "None";
                    }
                    TextureType       = "Type: " + texData.TypeString + "\nMipMaps: " + mipMaps;
                    TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")";

                    alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                    var removeAlphaBitmap = SetAlpha(texData.BMP, 255);

                    noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                    texData.Dispose();
                    removeAlphaBitmap.Dispose();
                }

                if (AlphaChecked)
                {
                    ImageSource = alphaBitmap;
                }
                else
                {
                    ImageSource = noAlphaBitmap;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("[TVM] There was an error updating the image.\n" + e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
コード例 #12
0
        /// <summary>
        /// Creates the bitmap data for the model
        /// </summary>
        /// <remarks>
        /// Because the original textures use channel packing, this method gets the pixel data of each texture
        /// and then recombines them to create the unpacked textures to use in the 3D model.
        /// <see cref="http://wiki.polycount.com/wiki/ChannelPacking"/>
        /// </remarks>
        /// <param name="normalTexData">The texture data of the normal map</param>
        /// <param name="diffuseTexData">The texture data of the diffuse map</param>
        /// <param name="maskTexData">The texture data of the mask map</param>
        /// <param name="specularTexData">The texture data of the specular map</param>
        /// <param name="colorMap">The bitmap of the color map</param>
        /// <returns>An array of bitmaps to be used on the model</returns>
        public static BitmapSource[] MakeModelTextureMaps(TEXData normalTexData, TEXData diffuseTexData, TEXData maskTexData, TEXData specularTexData, MTRLData mtrlData)
        {
            int height       = normalTexData.Height;
            int width        = normalTexData.Width;
            int tSize        = height * width;
            var normalBitmap = normalTexData.BMPSouceAlpha;

            if (diffuseTexData != null && (diffuseTexData.Height * diffuseTexData.Width) > tSize)
            {
                height = diffuseTexData.Height;
                width  = diffuseTexData.Width;
                tSize  = height * width;
            }

            if (maskTexData != null && (maskTexData.Height * maskTexData.Width) > tSize)
            {
                height = maskTexData.Height;
                width  = maskTexData.Width;
                tSize  = height * width;
            }

            if (specularTexData != null && (specularTexData.Height * specularTexData.Width) > tSize)
            {
                height = specularTexData.Height;
                width  = specularTexData.Width;
                tSize  = height * width;
            }

            byte[] maskPixels     = null;
            byte[] specularPixels = null;
            byte[] normalPixels   = null;
            byte[] diffusePixels  = null;

            List <System.Drawing.Color> colorList    = new List <System.Drawing.Color>();
            List <System.Drawing.Color> specularList = new List <System.Drawing.Color>();
            List <System.Drawing.Color> emissiveList = new List <System.Drawing.Color>();

            BitmapSource[] texBitmaps = new BitmapSource[5];

            if (mtrlData.ColorData != null)
            {
                BitmapSource colorMap1;
                using (var colorBitmap = TEX.ColorSetToBitmap(mtrlData.ColorData))
                {
                    SetAlpha(colorBitmap, 255);
                    colorMap1 = CreateBitmapSource(colorBitmap);
                }

                int    colorSetStride = colorMap1.PixelWidth * (colorMap1.Format.BitsPerPixel / 8);
                byte[] colorPixels    = new byte[colorMap1.PixelHeight * colorSetStride];

                colorMap1.CopyPixels(colorPixels, colorSetStride, 0);

                for (int i = 0; i < colorPixels.Length; i += 16)
                {
                    int red   = colorPixels[i + 2];
                    int green = colorPixels[i + 1];
                    int blue  = colorPixels[i];
                    int alpha = colorPixels[i + 3];

                    colorList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    red   = colorPixels[i + 6];
                    green = colorPixels[i + 5];
                    blue  = colorPixels[i + 4];
                    alpha = colorPixels[i + 7];

                    specularList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    var r1 = colorPixels[i + 10];
                    var g1 = colorPixels[i + 9];
                    var b1 = colorPixels[i + 8];
                    var a1 = colorPixels[i + 11];

                    emissiveList.Add(System.Drawing.Color.FromArgb(255, r1, g1, b1));
                }
            }
            else if (mtrlData.ColorData == null)
            {
                for (int i = 0; i < 1024; i += 16)
                {
                    colorList.Add(System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    specularList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                    emissiveList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                }
            }

            if (maskTexData != null)
            {
                if (tSize > (maskTexData.Height * maskTexData.Width))
                {
                    var resized = CreateResizedImage(maskTexData.BMPSouceAlpha, width, height);
                    maskPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    maskPixels = GetBytesFromBitmapSource(maskTexData.BMPSouceAlpha);
                }
            }

            if (diffuseTexData != null)
            {
                if (tSize > (diffuseTexData.Height * diffuseTexData.Width))
                {
                    var resized = CreateResizedImage(diffuseTexData.BMPSouceAlpha, width, height);
                    diffusePixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    diffusePixels = GetBytesFromBitmapSource(diffuseTexData.BMPSouceAlpha);
                }
            }

            if (specularTexData != null)
            {
                if (tSize > (specularTexData.Height * specularTexData.Width))
                {
                    var resized = CreateResizedImage(specularTexData.BMPSouceAlpha, width, height);
                    specularPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    specularPixels = GetBytesFromBitmapSource(specularTexData.BMPSouceAlpha);
                }
            }

            if (normalTexData != null)
            {
                if (tSize > (normalTexData.Height * normalTexData.Width))
                {
                    var resized = CreateResizedImage(normalTexData.BMPSouceAlpha, width, height);
                    normalBitmap = (BitmapSource)resized;
                    normalPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    normalPixels = GetBytesFromBitmapSource(normalTexData.BMPSouceAlpha);
                }
            }

            List <byte> diffuseMap  = new List <byte>();
            List <byte> specularMap = new List <byte>();
            List <byte> emissiveMap = new List <byte>();
            List <byte> alphaMap    = new List <byte>();

            float R  = 1;
            float G  = 1;
            float B  = 1;
            float R1 = 1;
            float G1 = 1;
            float B1 = 1;

            for (int i = 3; i < normalPixels.Length; i += 4)
            {
                int alpha = normalPixels[i - 3];

                if (maskTexData != null)
                {
                    B = maskPixels[i - 1];
                    R = maskPixels[i - 1];
                    G = maskPixels[i - 1];

                    B1 = maskPixels[i - 3];
                    R1 = maskPixels[i - 3];
                    G1 = maskPixels[i - 3];
                }
                else
                {
                    if (diffusePixels != null)
                    {
                        B = diffusePixels[i - 3];
                        G = diffusePixels[i - 2];
                        R = diffusePixels[i - 1];
                    }
                    else
                    {
                        B = 255;
                        G = 255;
                        R = 255;
                    }

                    if (specularPixels != null)
                    {
                        B1 = specularPixels[i - 2];
                        G1 = specularPixels[i - 2];
                        R1 = specularPixels[i - 2];
                    }
                    else
                    {
                        B1 = 255;
                        G1 = 255;
                        R1 = 255;
                    }
                }

                System.Drawing.Color diffuseColor;
                System.Drawing.Color specularColor;
                System.Drawing.Color emissiveColor;
                System.Drawing.Color alphaColor;


                float pixel = (normalPixels[i] / 255f) * 15f;
                //int colorLoc = (int)Math.Floor(pixel + 0.5f);
                float percent = (float)(pixel - Math.Truncate(pixel));

                if (percent != 0)
                {
                    var color2Loc = (int)(Math.Truncate(pixel));
                    var color1Loc = color2Loc + 1;

                    var color1 = System.Drawing.Color.FromArgb(alpha, colorList[color1Loc].R, colorList[color1Loc].G, colorList[color1Loc].B);
                    var color2 = System.Drawing.Color.FromArgb(alpha, colorList[color2Loc].R, colorList[color2Loc].G, colorList[color2Loc].B);

                    var diffuseBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, specularList[color1Loc].R, specularList[color1Loc].G, specularList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, specularList[color2Loc].R, specularList[color2Loc].G, specularList[color2Loc].B);

                    var specBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, emissiveList[color1Loc].R, emissiveList[color1Loc].G, emissiveList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, emissiveList[color2Loc].R, emissiveList[color2Loc].G, emissiveList[color2Loc].B);

                    var emisBlend = Blend(color1, color2, percent);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((diffuseBlend.R / 255f) * R), (int)((diffuseBlend.G / 255f) * G), (int)((diffuseBlend.B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specBlend.R / 255f) * R1), (int)((specBlend.G / 255f) * G1), (int)((specBlend.B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emisBlend.R, emisBlend.G, emisBlend.B);
                }
                else
                {
                    var colorLoc = (int)Math.Floor(pixel + 0.5f);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((colorList[colorLoc].R / 255f) * R), (int)((colorList[colorLoc].G / 255f) * G), (int)((colorList[colorLoc].B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specularList[colorLoc].R / 255f) * R1), (int)((specularList[colorLoc].G / 255f) * G1), (int)((specularList[colorLoc].B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emissiveList[colorLoc].R, emissiveList[colorLoc].G, emissiveList[colorLoc].B);
                }


                alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);

                diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));
                specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));
                emissiveMap.AddRange(BitConverter.GetBytes(emissiveColor.ToArgb()));
                alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
            }

            int stride = (int)normalBitmap.Width * (32 / 8);


            var scale = 1;

            if (width >= 4096 || height >= 4096)
            {
                scale = 4;
            }
            else if (width >= 2048 || height >= 2048)
            {
                scale = 2;
            }

            var nWidth  = width / scale;
            var nHeight = height / scale;

            BitmapSource bitmapSource = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);

            texBitmaps[0] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, specularMap.ToArray(), stride);
            texBitmaps[1] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            //texBitmaps[2] = normalTexData.BMPSouceNoAlpha;
            texBitmaps[2] = (BitmapSource)CreateResizedImage(normalTexData.BMPSouceNoAlpha, nWidth, nHeight);

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, alphaMap.ToArray(), stride);
            texBitmaps[3] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, emissiveMap.ToArray(), stride);
            texBitmaps[4] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            foreach (var tb in texBitmaps)
            {
                tb.Freeze();
            }

            return(texBitmaps);
        }
コード例 #13
0
        /// <summary>
        /// Gets the texture data and displays it for the currently selected item given a specified race, part, type(if applicable), and map
        /// </summary>
        private void MapComboBoxChanged()
        {
            Bitmap colorBmp = null;
            int    offset   = 0;
            bool   isVFX    = false;

            if (selectedMap.Name.Equals(Strings.Normal))
            {
                fullPath       = mtrlData.NormalPath;
                offset         = mtrlData.NormalOffset;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else if (selectedMap.Name.Equals(Strings.Specular))
            {
                fullPath       = mtrlData.SpecularPath;
                offset         = mtrlData.SpecularOffset;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else if (selectedMap.Name.Equals(Strings.Diffuse))
            {
                fullPath       = mtrlData.DiffusePath;
                offset         = mtrlData.DiffuseOffset;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else if (selectedMap.Name.Equals(Strings.Mask) || selectedMap.Name.Equals(Strings.Skin))
            {
                if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                {
                    string part;
                    if (selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                    {
                        part = selectedPart.Name.PadLeft(3, '0');
                    }
                    else
                    {
                        part = selectedPart.Name;
                    }

                    fullPath       = String.Format(mtrlData.MaskPath, part);
                    offset         = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name);
                    FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
                }
                else
                {
                    fullPath       = mtrlData.MaskPath;
                    offset         = mtrlData.MaskOffset;
                    FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
                }
            }
            else if (selectedMap.Name.Equals(Strings.ColorSet))
            {
                colorBmp       = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                fullPath       = mtrlData.MTRLPath;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else
            {
                fullPath = SelectedMap.ID;
                var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/"));
                var VFXFile   = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                offset = Helper.GetItemOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile));

                FullPathString = fullPath;

                isVFX = true;
            }

            if (Properties.Settings.Default.Mod_List == 0)
            {
                string    line;
                JsonEntry modEntry  = null;
                bool      inModList = false;
                try
                {
                    using (StreamReader sr = new StreamReader(Info.modListDir))
                    {
                        while ((line = sr.ReadLine()) != null)
                        {
                            modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                            if (modEntry.fullPath.Equals(fullPath))
                            {
                                inModList = true;
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("[Main] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }

                if (inModList)
                {
                    var currOffset = Helper.GetItemOffset(FFCRC.GetHash(modEntry.fullPath.Substring(0, modEntry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(modEntry.fullPath)));

                    if (currOffset == modEntry.modOffset)
                    {
                        ActiveToggle = "Disable";
                    }
                    else if (currOffset == modEntry.originalOffset)
                    {
                        ActiveToggle = "Enable";
                    }
                    else
                    {
                        ActiveToggle = "Error";
                    }

                    ActiveEnabled = true;
                }
                else
                {
                    ActiveEnabled = false;
                    ActiveToggle  = "Enable/Disable";
                }
            }
            else
            {
                ActiveEnabled = false;
                ActiveToggle  = "Enable/Disable";
            }

            if (offset == 0)
            {
                TextureType = "A16B16G16R16F";
                textureType = "A16B16G16R16F";

                TextureDimensions = "(4 x 16)";
                textureDimensions = "(4 x 16)";


                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                var removeAlphaBitmap = SetAlpha(colorBmp, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                colorBmp.Dispose();
                removeAlphaBitmap.Dispose();
            }
            else
            {
                if (!isVFX)
                {
                    texData = TEX.GetTex(offset);
                }
                else
                {
                    texData = TEX.GetVFX(offset);
                }

                TextureType = texData.TypeString;

                TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")";

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                var removeAlphaBitmap = SetAlpha(texData.BMP, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                removeAlphaBitmap.Dispose();
            }

            try
            {
                ImageEffect = new ColorChannels()
                {
                    Channel = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f)
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
            }

            ImageSource = noAlphaBitmap;

            SetColorChannelFilter();

            SaveEnabled = true;

            texData.Dispose();

            string dxPath = Path.GetFileNameWithoutExtension(fullPath);

            if (File.Exists(Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName + "/" + dxPath + ".dds"))
            {
                ImportEnabled = true;
            }
            else
            {
                ImportEnabled = false;
            }
        }
コード例 #14
0
        /// <summary>
        /// Saves the currently displayed texture map as a DDS file.
        /// </summary>
        /// <param name="selectedCategory">The items category.</param>
        /// <param name="selectedItem">The currently selected item.</param>
        /// <param name="internalFilePath">The internal file path of the texture map.</param>
        /// <param name="textureMap">The name of the currently selected texture map.</param>
        /// <param name="mtrlData">The items mtrl file data</param>
        /// <param name="texData">The items tex file data</param>
        public static void SaveDDS(string selectedCategory, string selectedItem, string internalFilePath, string textureMap, MTRLData mtrlData, TEXData texData)
        {
            string savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem;

            Directory.CreateDirectory(savePath);

            var fullSavePath = Path.Combine(savePath, (Path.GetFileNameWithoutExtension(internalFilePath) + ".dds"));

            List <byte> DDS = new List <byte>();

            if (textureMap.Equals(Strings.ColorSet))
            {
                if (mtrlData.ColorFlags != null)
                {
                    var colorFlagsDir = Path.Combine(savePath, (Path.GetFileNameWithoutExtension(internalFilePath) + ".dat"));
                    File.WriteAllBytes(colorFlagsDir, mtrlData.ColorFlags);
                }

                DDS.AddRange(CreateColorDDSHeader());
                DDS.AddRange(mtrlData.ColorData);
            }
            else
            {
                DDS.AddRange(CreateDDSHeader(texData));
                DDS.AddRange(texData.RawTexData);
            }

            File.WriteAllBytes(fullSavePath, DDS.ToArray());
        }
コード例 #15
0
        /// <summary>
        /// Gets the model data and sets the display viewmodel
        /// </summary>
        private void MeshComboBoxChanged()
        {
            if (!is3DLoaded)
            {
                disposing = false;

                meshData = new List <MDLTEXData>();

                for (int i = 0; i < meshList.Count; i++)
                {
                    BitmapSource specularBMP = null;
                    BitmapSource diffuseBMP  = null;
                    BitmapSource normalBMP   = null;
                    BitmapSource colorBMP    = null;
                    BitmapSource alphaBMP    = null;
                    BitmapSource maskBMP     = null;

                    TEXData specularData = null;
                    TEXData diffuseData  = null;
                    TEXData normalData   = null;
                    TEXData maskData     = null;

                    bool isBody = false;
                    bool isFace = false;

                    MTRLData mtrlData = MTRL3D(i);

                    if (selectedCategory.Equals(Strings.Character))
                    {
                        if (selectedItem.ItemName.Equals(Strings.Tail) || selectedItem.ItemName.Equals(Strings.Hair))
                        {
                            normalData   = TEX.GetTex(mtrlData.NormalOffset);
                            specularData = TEX.GetTex(mtrlData.SpecularOffset);

                            if (mtrlData.DiffusePath != null)
                            {
                                diffuseData = TEX.GetTex(mtrlData.DiffuseOffset);
                            }

                            var maps = TexHelper.MakeCharacterMaps(normalData, diffuseData, null, specularData);

                            diffuseBMP  = maps[0];
                            specularBMP = maps[1];
                            normalBMP   = maps[2];
                            alphaBMP    = maps[3];

                            specularData.Dispose();
                            normalData.Dispose();
                            if (diffuseData != null)
                            {
                                diffuseData.Dispose();
                            }
                        }

                        if (selectedItem.ItemName.Equals(Strings.Body))
                        {
                            normalData = TEX.GetTex(mtrlData.NormalOffset);
                            //specularTI = TEX.GetTex(mInfo.SpecularOffset);
                            diffuseData = TEX.GetTex(mtrlData.DiffuseOffset);

                            isBody     = true;
                            diffuseBMP = Imaging.CreateBitmapSourceFromHBitmap(diffuseData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                            normalBMP  = Imaging.CreateBitmapSourceFromHBitmap(normalData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (selectedItem.ItemName.Equals(Strings.Face))
                        {
                            normalData = TEX.GetTex(mtrlData.NormalOffset);

                            if (materialStrings[i].Contains("_fac_"))
                            {
                                specularData = TEX.GetTex(mtrlData.SpecularOffset);
                                diffuseData  = TEX.GetTex(mtrlData.DiffuseOffset);

                                var maps = TexHelper.MakeCharacterMaps(normalData, diffuseData, null, specularData);

                                diffuseBMP  = maps[0];
                                specularBMP = maps[1];
                                normalBMP   = maps[2];
                                alphaBMP    = maps[3];
                                isFace      = true;

                                specularData.Dispose();
                                diffuseData.Dispose();
                            }
                            else
                            {
                                specularData = TEX.GetTex(mtrlData.SpecularOffset);
                                var maps = TexHelper.MakeCharacterMaps(normalData, diffuseData, null, specularData);

                                diffuseBMP  = maps[0];
                                specularBMP = maps[1];
                                normalBMP   = maps[2];
                                alphaBMP    = maps[3];
                            }
                        }
                    }
                    else
                    {
                        if (mtrlData.ColorData != null)
                        {
                            var colorBmp = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                            colorBMP = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (mtrlData.NormalOffset != 0)
                        {
                            normalData = TEX.GetTex(mtrlData.NormalOffset);
                        }

                        if (mtrlData.MaskOffset != 0)
                        {
                            maskData = TEX.GetTex(mtrlData.MaskOffset);
                            maskBMP  = Imaging.CreateBitmapSourceFromHBitmap(maskData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (mtrlData.DiffuseOffset != 0)
                        {
                            diffuseData = TEX.GetTex(mtrlData.DiffuseOffset);
                            if (mtrlData.DiffusePath.Contains("human") && !mtrlData.DiffusePath.Contains("demi"))
                            {
                                isBody     = true;
                                diffuseBMP = Imaging.CreateBitmapSourceFromHBitmap(diffuseData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                                normalBMP  = Imaging.CreateBitmapSourceFromHBitmap(normalData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                            }
                        }

                        if (mtrlData.SpecularOffset != 0)
                        {
                            specularData = TEX.GetTex(mtrlData.SpecularOffset);
                            specularBMP  = Imaging.CreateBitmapSourceFromHBitmap(specularData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (!isBody && specularData == null)
                        {
                            var maps = TexHelper.MakeModelTextureMaps(normalData, diffuseData, maskData, null, colorBMP);
                            diffuseBMP  = maps[0];
                            specularBMP = maps[1];
                            normalBMP   = maps[2];
                            alphaBMP    = maps[3];
                        }
                        else if (!isBody && specularData != null)
                        {
                            var maps = TexHelper.MakeModelTextureMaps(normalData, diffuseData, null, specularData, colorBMP);
                            diffuseBMP  = maps[0];
                            specularBMP = maps[1];
                            normalBMP   = maps[2];
                            alphaBMP    = maps[3];
                        }

                        if (normalData != null)
                        {
                            normalData.Dispose();
                        }

                        if (maskData != null)
                        {
                            maskData.Dispose();
                        }

                        if (diffuseData != null)
                        {
                            diffuseData.Dispose();
                        }

                        if (specularData != null)
                        {
                            specularData.Dispose();
                        }
                    }

                    var mData = new MDLTEXData()
                    {
                        Specular   = specularBMP,
                        ColorTable = colorBMP,
                        Diffuse    = diffuseBMP,
                        Normal     = normalBMP,
                        Alpha      = alphaBMP,
                        Mask       = maskBMP,

                        IsBody = isBody,
                        IsFace = isFace,

                        Mesh = meshList[i]
                    };

                    meshData.Add(mData);
                }

                CompositeVM = new Composite3DViewModel(meshData);

                is3DLoaded = true;

                ReflectionAmount = String.Format("{0:.##}", CompositeVM.SecondModelMaterial.SpecularShininess);

                try
                {
                }
                catch (Exception ex)
                {
                    MessageBox.Show("[Main] mesh 3D Error \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                CompositeVM.Rendering(SelectedMesh.Name);
            }
        }
コード例 #16
0
ファイル: TexHelper.cs プロジェクト: kaedeair/FFXIV_TexTools2
        /// <summary>
        /// Creates the bitmap data for the model
        /// </summary>
        /// <remarks>
        /// Because the original textures use channel packing, this method gets the pixel data of each texture
        /// and then recombines them to create the unpacked textures to use in the 3D model.
        /// <see cref="http://wiki.polycount.com/wiki/ChannelPacking"/>
        /// </remarks>
        /// <param name="normalTexData">The texture data of the normal map</param>
        /// <param name="diffuseTexData">The texture data of the diffuse map</param>
        /// <param name="maskTexData">The texture data of the mask map</param>
        /// <param name="specularTexData">The texture data of the specular map</param>
        /// <param name="colorMap">The bitmap of the color map</param>
        /// <returns>An array of bitmaps to be used on the model</returns>
        public static BitmapSource[] MakeModelTextureMaps(TEXData normalTexData, TEXData diffuseTexData, TEXData maskTexData, TEXData specularTexData, MTRLData mtrlData)
        {
            int    height       = normalTexData.Height;
            int    width        = normalTexData.Width;
            int    tSize        = height * width;
            Bitmap normalBitmap = null;

            if (diffuseTexData != null && (diffuseTexData.Height * diffuseTexData.Width) > tSize)
            {
                height = diffuseTexData.Height;
                width  = diffuseTexData.Width;
                tSize  = height * width;
            }

            if (maskTexData != null && (maskTexData.Height * maskTexData.Width) > tSize)
            {
                height = maskTexData.Height;
                width  = maskTexData.Width;
                tSize  = height * width;
            }

            if (specularTexData != null && (specularTexData.Height * specularTexData.Width) > tSize)
            {
                height = specularTexData.Height;
                width  = specularTexData.Width;
                tSize  = height * width;
            }

            byte[] maskPixels     = null;
            byte[] specularPixels = null;
            byte[] normalPixels   = null;
            byte[] diffusePixels  = null;

            List <System.Drawing.Color> colorList    = new List <System.Drawing.Color>();
            List <System.Drawing.Color> specularList = new List <System.Drawing.Color>();
            List <System.Drawing.Color> emissiveList = new List <System.Drawing.Color>();

            BitmapSource[] texBitmaps = new BitmapSource[5];

            if (mtrlData.ColorData != null)
            {
                var colorBitmap = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                var cbmp        = SetAlpha(colorBitmap, 255);
                var colorMap1   = Imaging.CreateBitmapSourceFromHBitmap(cbmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                int    colorSetStride = colorMap1.PixelWidth * (colorMap1.Format.BitsPerPixel / 8);
                byte[] colorPixels    = new byte[colorMap1.PixelHeight * colorSetStride];

                colorMap1.CopyPixels(colorPixels, colorSetStride, 0);

                for (int i = 0; i < colorPixels.Length; i += 16)
                {
                    int red   = colorPixels[i + 2];
                    int green = colorPixels[i + 1];
                    int blue  = colorPixels[i];
                    int alpha = colorPixels[i + 3];

                    colorList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    red   = colorPixels[i + 6];
                    green = colorPixels[i + 5];
                    blue  = colorPixels[i + 4];
                    alpha = colorPixels[i + 7];

                    specularList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    var r1 = colorPixels[i + 10];
                    var g1 = colorPixels[i + 9];
                    var b1 = colorPixels[i + 8];
                    var a1 = colorPixels[i + 11];

                    emissiveList.Add(System.Drawing.Color.FromArgb(255, r1, g1, b1));
                }
            }
            else if (mtrlData.ColorData == null)
            {
                for (int i = 0; i < 1024; i += 16)
                {
                    colorList.Add(System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    specularList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                    emissiveList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                }
            }

            if (maskTexData != null)
            {
                if (tSize > (maskTexData.Height * maskTexData.Width))
                {
                    var maskBitmap   = ResizeImage(Image.FromHbitmap(maskTexData.BMP.GetHbitmap()), width, height);
                    var maskData     = maskBitmap.LockBits(new System.Drawing.Rectangle(0, 0, maskBitmap.Width, maskBitmap.Height), ImageLockMode.ReadOnly, maskBitmap.PixelFormat);
                    var bitmapLength = maskData.Stride * maskData.Height;
                    maskPixels = new byte[bitmapLength];
                    Marshal.Copy(maskData.Scan0, maskPixels, 0, bitmapLength);
                    maskBitmap.UnlockBits(maskData);
                }
                else
                {
                    var maskData     = maskTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, maskTexData.Width, maskTexData.Height), ImageLockMode.ReadOnly, maskTexData.BMP.PixelFormat);
                    var bitmapLength = maskData.Stride * maskData.Height;
                    maskPixels = new byte[bitmapLength];
                    Marshal.Copy(maskData.Scan0, maskPixels, 0, bitmapLength);
                    maskTexData.BMP.UnlockBits(maskData);
                }
            }

            if (diffuseTexData != null)
            {
                if (tSize > (diffuseTexData.Height * diffuseTexData.Width))
                {
                    var diffuseBitmap = ResizeImage(Image.FromHbitmap(diffuseTexData.BMP.GetHbitmap()), width, height);
                    var diffData      = diffuseBitmap.LockBits(new System.Drawing.Rectangle(0, 0, diffuseBitmap.Width, diffuseBitmap.Height), ImageLockMode.ReadOnly, diffuseBitmap.PixelFormat);
                    var bitmapLength  = diffData.Stride * diffData.Height;
                    diffusePixels = new byte[bitmapLength];
                    Marshal.Copy(diffData.Scan0, diffusePixels, 0, bitmapLength);
                    diffuseBitmap.UnlockBits(diffData);
                }
                else
                {
                    var diffData     = diffuseTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, diffuseTexData.Width, diffuseTexData.Height), ImageLockMode.ReadOnly, diffuseTexData.BMP.PixelFormat);
                    var bitmapLength = diffData.Stride * diffData.Height;
                    diffusePixels = new byte[bitmapLength];
                    Marshal.Copy(diffData.Scan0, diffusePixels, 0, bitmapLength);
                    diffuseTexData.BMP.UnlockBits(diffData);
                }
            }

            if (specularTexData != null)
            {
                if (tSize > (specularTexData.Height * specularTexData.Width))
                {
                    var specularBitmap = ResizeImage(Image.FromHbitmap(specularTexData.BMP.GetHbitmap()), width, height);
                    var specData       = specularBitmap.LockBits(new System.Drawing.Rectangle(0, 0, specularBitmap.Width, specularBitmap.Height), ImageLockMode.ReadOnly, specularBitmap.PixelFormat);
                    var bitmapLength   = specData.Stride * specData.Height;
                    specularPixels = new byte[bitmapLength];
                    Marshal.Copy(specData.Scan0, specularPixels, 0, bitmapLength);
                    specularBitmap.UnlockBits(specData);
                }
                else
                {
                    var specData     = specularTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, specularTexData.BMP.Width, specularTexData.BMP.Height), ImageLockMode.ReadOnly, specularTexData.BMP.PixelFormat);
                    var bitmapLength = specData.Stride * specData.Height;
                    specularPixels = new byte[bitmapLength];
                    Marshal.Copy(specData.Scan0, specularPixels, 0, bitmapLength);
                    specularTexData.BMP.UnlockBits(specData);
                }
            }

            if (normalTexData != null)
            {
                if (tSize > (normalTexData.Height * normalTexData.Width))
                {
                    var normBitmap   = ResizeImage(Image.FromHbitmap(normalTexData.BMP.GetHbitmap()), width, height);
                    var normalData   = normBitmap.LockBits(new System.Drawing.Rectangle(0, 0, normBitmap.Width, normBitmap.Height), ImageLockMode.ReadOnly, normBitmap.PixelFormat);
                    var bitmapLength = normalData.Stride * normalData.Height;
                    normalPixels = new byte[bitmapLength];
                    Marshal.Copy(normalData.Scan0, normalPixels, 0, bitmapLength);
                    normBitmap.UnlockBits(normalData);
                    normalBitmap = normBitmap;
                }
                else
                {
                    var normalData   = normalTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, normalTexData.Width, normalTexData.Height), ImageLockMode.ReadOnly, normalTexData.BMP.PixelFormat);
                    var bitmapLength = normalData.Stride * normalData.Height;
                    normalPixels = new byte[bitmapLength];
                    Marshal.Copy(normalData.Scan0, normalPixels, 0, bitmapLength);
                    normalTexData.BMP.UnlockBits(normalData);
                    normalBitmap = normalTexData.BMP;
                }
            }

            List <byte> diffuseMap  = new List <byte>();
            List <byte> specularMap = new List <byte>();
            List <byte> emissiveMap = new List <byte>();
            List <byte> alphaMap    = new List <byte>();

            float R  = 1;
            float G  = 1;
            float B  = 1;
            float R1 = 1;
            float G1 = 1;
            float B1 = 1;

            for (int i = 3; i < normalPixels.Length; i += 4)
            {
                int alpha = normalPixels[i - 3];

                if (maskTexData != null)
                {
                    B = maskPixels[i - 1];
                    R = maskPixels[i - 1];
                    G = maskPixels[i - 1];

                    B1 = maskPixels[i - 3];
                    R1 = maskPixels[i - 3];
                    G1 = maskPixels[i - 3];
                }
                else
                {
                    if (diffusePixels != null)
                    {
                        B = diffusePixels[i - 3];
                        G = diffusePixels[i - 2];
                        R = diffusePixels[i - 1];
                    }
                    else
                    {
                        B = 255;
                        G = 255;
                        R = 255;
                    }

                    if (specularPixels != null)
                    {
                        B1 = specularPixels[i - 2];
                        G1 = specularPixels[i - 2];
                        R1 = specularPixels[i - 2];
                    }
                    else
                    {
                        B1 = 255;
                        G1 = 255;
                        R1 = 255;
                    }
                }

                System.Drawing.Color diffuseColor;
                System.Drawing.Color specularColor;
                System.Drawing.Color emissiveColor;
                System.Drawing.Color alphaColor;


                float pixel = (normalPixels[i] / 255f) * 15f;
                //int colorLoc = (int)Math.Floor(pixel + 0.5f);
                float percent = (float)(pixel - Math.Truncate(pixel));

                if (percent != 0)
                {
                    var color2Loc = (int)(Math.Truncate(pixel));
                    var color1Loc = color2Loc + 1;

                    var color1 = System.Drawing.Color.FromArgb(alpha, colorList[color1Loc].R, colorList[color1Loc].G, colorList[color1Loc].B);
                    var color2 = System.Drawing.Color.FromArgb(alpha, colorList[color2Loc].R, colorList[color2Loc].G, colorList[color2Loc].B);

                    var diffuseBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, specularList[color1Loc].R, specularList[color1Loc].G, specularList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, specularList[color2Loc].R, specularList[color2Loc].G, specularList[color2Loc].B);

                    var specBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, emissiveList[color1Loc].R, emissiveList[color1Loc].G, emissiveList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, emissiveList[color2Loc].R, emissiveList[color2Loc].G, emissiveList[color2Loc].B);

                    var emisBlend = Blend(color1, color2, percent);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((diffuseBlend.R / 255f) * R), (int)((diffuseBlend.G / 255f) * G), (int)((diffuseBlend.B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specBlend.R / 255f) * R1), (int)((specBlend.G / 255f) * G1), (int)((specBlend.B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emisBlend.R, emisBlend.G, emisBlend.B);
                }
                else
                {
                    var colorLoc = (int)Math.Floor(pixel + 0.5f);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((colorList[colorLoc].R / 255f) * R), (int)((colorList[colorLoc].G / 255f) * G), (int)((colorList[colorLoc].B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specularList[colorLoc].R / 255f) * R1), (int)((specularList[colorLoc].G / 255f) * G1), (int)((specularList[colorLoc].B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emissiveList[colorLoc].R, emissiveList[colorLoc].G, emissiveList[colorLoc].B);
                }


                alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);

                diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));
                specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));
                emissiveMap.AddRange(BitConverter.GetBytes(emissiveColor.ToArgb()));
                alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
            }

            int stride = normalBitmap.Width * (32 / 8);

            BitmapSource bitmapSource = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);

            texBitmaps[0] = bitmapSource;

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, specularMap.ToArray(), stride);
            texBitmaps[1] = bitmapSource;

            var noAlphaNormal = SetAlpha(normalBitmap, 255);

            texBitmaps[2] = Imaging.CreateBitmapSourceFromHBitmap(noAlphaNormal.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, alphaMap.ToArray(), stride);
            texBitmaps[3] = bitmapSource;

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, emissiveMap.ToArray(), stride);
            texBitmaps[4] = bitmapSource;


            if (normalTexData != null)
            {
                normalTexData.Dispose();
            }

            if (normalBitmap != null)
            {
                normalBitmap.Dispose();
            }

            if (diffuseTexData != null)
            {
                diffuseTexData.Dispose();
            }

            if (maskTexData != null)
            {
                maskTexData.Dispose();
            }

            if (specularTexData != null)
            {
                specularTexData.Dispose();
            }

            foreach (var tb in texBitmaps)
            {
                tb.Freeze();
            }


            return(texBitmaps);
        }
コード例 #17
0
ファイル: TexHelper.cs プロジェクト: kaedeair/FFXIV_TexTools2
        /// <summary>
        /// Creates the bitmap data for the models in the character category
        /// </summary>
        /// <remarks>
        /// Because the original textures use channel packing, this method gets the pixel data of each texture
        /// and then recombines them to create the unpacked textures to use in the 3D model.
        /// <see cref="http://wiki.polycount.com/wiki/ChannelPacking"/>
        /// </remarks>
        /// <param name="normalTexData">The texture data of the normal map</param>
        /// <param name="diffuseTexData">The texture data of the diffuse map</param>
        /// <param name="maskTexData">The texture data of the mask map</param>
        /// <param name="specularTexData">The texture data of the normal map</param>
        /// <returns>An array of bitmaps to be used on the model</returns>
        public static BitmapSource[] MakeCharacterMaps(TEXData normalTexData, TEXData diffuseTexData, TEXData maskTexData, TEXData specularTexData)
        {
            int    height       = normalTexData.Height;
            int    width        = normalTexData.Width;
            int    tSize        = height * width;
            Bitmap normalBitmap = null;

            if (diffuseTexData != null && (diffuseTexData.Height * diffuseTexData.Width) > tSize)
            {
                height = diffuseTexData.Height;
                width  = diffuseTexData.Width;
                tSize  = height * width;
            }

            if (maskTexData != null && (maskTexData.Height * maskTexData.Width) > tSize)
            {
                height = maskTexData.Height;
                width  = maskTexData.Width;
                tSize  = height * width;
            }

            if (specularTexData != null && (specularTexData.Height * specularTexData.Width) > tSize)
            {
                height = specularTexData.Height;
                width  = specularTexData.Width;
                tSize  = height * width;
            }

            byte[] maskPixels     = null;
            byte[] specularPixels = null;
            byte[] normalPixels   = null;
            byte[] diffusePixels  = null;

            BitmapSource[] texBitmaps = new BitmapSource[4];

            if (maskTexData != null)
            {
                if (tSize > (maskTexData.Height * maskTexData.Width))
                {
                    var maskBitmap   = ResizeImage(Image.FromHbitmap(maskTexData.BMP.GetHbitmap()), width, height);
                    var maskData     = maskBitmap.LockBits(new System.Drawing.Rectangle(0, 0, maskBitmap.Width, maskBitmap.Height), ImageLockMode.ReadOnly, maskBitmap.PixelFormat);
                    var bitmapLength = maskData.Stride * maskData.Height;
                    maskPixels = new byte[bitmapLength];
                    Marshal.Copy(maskData.Scan0, maskPixels, 0, bitmapLength);
                    maskBitmap.UnlockBits(maskData);
                }
                else
                {
                    var maskData     = maskTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, maskTexData.Width, maskTexData.Height), ImageLockMode.ReadOnly, maskTexData.BMP.PixelFormat);
                    var bitmapLength = maskData.Stride * maskData.Height;
                    maskPixels = new byte[bitmapLength];
                    Marshal.Copy(maskData.Scan0, maskPixels, 0, bitmapLength);
                    maskTexData.BMP.UnlockBits(maskData);
                }
            }

            if (diffuseTexData != null)
            {
                try
                {
                    if (tSize > (diffuseTexData.Height * diffuseTexData.Width))
                    {
                        var diffuseBitmap = ResizeImage(Image.FromHbitmap(diffuseTexData.BMP.GetHbitmap()), width, height);
                        var diffuseData   = diffuseBitmap.LockBits(new System.Drawing.Rectangle(0, 0, diffuseBitmap.Width, diffuseBitmap.Height), ImageLockMode.ReadOnly, diffuseBitmap.PixelFormat);
                        var bitmapLength  = diffuseData.Stride * diffuseData.Height;
                        diffusePixels = new byte[bitmapLength];
                        Marshal.Copy(diffuseData.Scan0, diffusePixels, 0, bitmapLength);
                        diffuseBitmap.UnlockBits(diffuseData);
                    }
                    else
                    {
                        var diffuseData  = diffuseTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, diffuseTexData.Width, diffuseTexData.Height), ImageLockMode.ReadOnly, diffuseTexData.BMP.PixelFormat);
                        var bitmapLength = diffuseData.Stride * diffuseData.Height;
                        diffusePixels = new byte[bitmapLength];
                        Marshal.Copy(diffuseData.Scan0, diffusePixels, 0, bitmapLength);
                        diffuseTexData.BMP.UnlockBits(diffuseData);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    Debug.WriteLine(ex.StackTrace);
                }
            }

            if (specularTexData != null)
            {
                try
                {
                    if (tSize > (specularTexData.Height * specularTexData.Width))
                    {
                        var specularBitmap = ResizeImage(Image.FromHbitmap(specularTexData.BMP.GetHbitmap()), width, height);
                        var specularData   = specularBitmap.LockBits(new System.Drawing.Rectangle(0, 0, specularBitmap.Width, specularBitmap.Height), ImageLockMode.ReadOnly, specularBitmap.PixelFormat);
                        var bitmapLength   = specularData.Stride * specularData.Height;
                        specularPixels = new byte[bitmapLength];
                        Marshal.Copy(specularData.Scan0, specularPixels, 0, bitmapLength);
                        specularBitmap.UnlockBits(specularData);
                    }
                    else
                    {
                        var specularData = specularTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, specularTexData.BMP.Width, specularTexData.BMP.Height), ImageLockMode.ReadOnly, specularTexData.BMP.PixelFormat);
                        var bitmapLength = specularData.Stride * specularData.Height;
                        specularPixels = new byte[bitmapLength];
                        Marshal.Copy(specularData.Scan0, specularPixels, 0, bitmapLength);
                        specularTexData.BMP.UnlockBits(specularData);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    Debug.WriteLine(ex.StackTrace);
                }
            }


            if (normalTexData != null)
            {
                if (tSize > (normalTexData.Height * normalTexData.Width))
                {
                    var normBitmap   = ResizeImage(Image.FromHbitmap(normalTexData.BMP.GetHbitmap()), width, height);
                    var normData     = normBitmap.LockBits(new System.Drawing.Rectangle(0, 0, normBitmap.Width, normBitmap.Height), ImageLockMode.ReadOnly, normBitmap.PixelFormat);
                    var bitmapLength = normData.Stride * normData.Height;
                    normalPixels = new byte[bitmapLength];
                    Marshal.Copy(normData.Scan0, normalPixels, 0, bitmapLength);
                    normBitmap.UnlockBits(normData);
                    normalBitmap = normBitmap;
                }
                else
                {
                    var normData     = normalTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, normalTexData.Width, normalTexData.Height), ImageLockMode.ReadOnly, normalTexData.BMP.PixelFormat);
                    var bitmapLength = normData.Stride * normData.Height;
                    normalPixels = new byte[bitmapLength];
                    Marshal.Copy(normData.Scan0, normalPixels, 0, bitmapLength);
                    normalTexData.BMP.UnlockBits(normData);
                    normalBitmap = normalTexData.BMP;
                }
            }

            List <byte> diffuseMap  = new List <byte>();
            List <byte> specularMap = new List <byte>();
            List <byte> alphaMap    = new List <byte>();

            BitmapSource bitmapSource;

            System.Drawing.Color diffuseColor;
            System.Drawing.Color specularColor;
            System.Drawing.Color alphaColor;

            int stride = normalBitmap.Width * (32 / 8);

            if (diffuseTexData == null)
            {
                for (int i = 3; i < normalPixels.Length; i += 4)
                {
                    int alpha = normalPixels[i];

                    diffuseColor = System.Drawing.Color.FromArgb(alpha, (int)((96f / 255f) * specularPixels[i - 1]), (int)((57f / 255f) * specularPixels[i - 1]), (int)((19f / 255f) * specularPixels[i - 1]));

                    specularColor = System.Drawing.Color.FromArgb(255, specularPixels[i - 2], specularPixels[i - 2], specularPixels[i - 2]);

                    alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);

                    diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));
                    specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));
                    alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
                }

                bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);
                texBitmaps[0] = bitmapSource;
            }
            else
            {
                for (int i = 3; i < normalPixels.Length; i += 4)
                {
                    int alpha = normalPixels[i - 3];

                    diffuseColor = System.Drawing.Color.FromArgb(alpha, diffusePixels[i - 1], diffusePixels[i - 2], diffusePixels[i - 3]);
                    diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));

                    specularColor = System.Drawing.Color.FromArgb(255, specularPixels[i - 2], specularPixels[i - 2], specularPixels[i - 2]);
                    specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));

                    alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);
                    alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
                }

                bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);
                texBitmaps[0] = bitmapSource;
            }

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, specularMap.ToArray(), stride);
            texBitmaps[1] = bitmapSource;

            texBitmaps[2] = Imaging.CreateBitmapSourceFromHBitmap(normalBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, alphaMap.ToArray(), stride);
            texBitmaps[3] = bitmapSource;

            if (normalTexData != null)
            {
                normalTexData.Dispose();
            }

            if (normalBitmap != null)
            {
                normalBitmap.Dispose();
            }

            if (diffuseTexData != null)
            {
                diffuseTexData.Dispose();
            }

            if (maskTexData != null)
            {
                maskTexData.Dispose();
            }

            if (specularTexData != null)
            {
                specularTexData.Dispose();
            }

            foreach (var tb in texBitmaps)
            {
                tb.Freeze();
            }

            return(texBitmaps);
        }
コード例 #18
0
ファイル: SaveTex.cs プロジェクト: viion-misc/FFXIV_TexTools2
        /// <summary>
        /// Saves the currently displayed texture map as an image file.
        /// </summary>
        /// <param name="selectedCategory">The items category</param>
        /// <param name="selectedItem">The currently selected item</param>
        /// <param name="internalFilePath">The internal file path of the texture map</param>
        /// <param name="selectedBitmap">The bitmap of the texturemap currently being displayed</param>
        public static void SaveImage(string selectedCategory, string selectedItem, string internalFilePath, BitmapSource selectedBitmap, TEXData texData, string textureMap, string subCategory)
        {
            string savePath = "";

            if (selectedCategory.Equals("UI"))
            {
                savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + subCategory;
            }
            else
            {
                savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem;
            }
            Directory.CreateDirectory(savePath);

            var fullSavePath = Path.Combine(savePath, (Path.GetFileNameWithoutExtension(internalFilePath) + ".bmp"));

            if (textureMap.Equals(Strings.ColorSet))
            {
                using (var fileStream = new FileStream(fullSavePath, FileMode.Create))
                {
                    BitmapEncoder encoder = new BmpBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(selectedBitmap));
                    encoder.Save(fileStream);
                }
            }
            else
            {
                using (var fileStream = new FileStream(fullSavePath, FileMode.Create))
                {
                    BitmapEncoder encoder = new BmpBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(texData.BMPSouceAlpha));
                    encoder.Save(fileStream);
                }
            }
        }
コード例 #19
0
        /// <summary>
        /// Creates the header for the compressed texture data to be imported.
        /// </summary>
        /// <param name="texData">Data for the currently displayed texture.</param>
        /// <param name="mipPartOffsets">List of part offsets.</param>
        /// <param name="mipPartCount">List containing the amount of parts per mipmap.</param>
        /// <param name="uncompressedLength">Length of the uncompressed texture file.</param>
        /// <param name="newMipCount">The number of mipmaps the DDS texture to be imported contains.</param>
        /// <param name="newWidth">The width of the DDS texture to be imported.</param>
        /// <param name="newHeight">The height of the DDS texture to be imported.</param>
        /// <returns>The created header data.</returns>
        private static List <byte> MakeType4DATHeader(TEXData texData, List <short> mipPartOffsets, List <short> mipPartCount, int uncompressedLength, int newMipCount, int newWidth, int newHeight)
        {
            List <byte> headerData = new List <byte>();

            int headerSize    = 24 + (newMipCount * 20) + (mipPartOffsets.Count * 2);
            int headerPadding = 128 - (headerSize % 128);

            headerData.AddRange(BitConverter.GetBytes(headerSize + headerPadding));
            headerData.AddRange(BitConverter.GetBytes(4));
            headerData.AddRange(BitConverter.GetBytes(uncompressedLength));
            headerData.AddRange(BitConverter.GetBytes(0));
            headerData.AddRange(BitConverter.GetBytes(0));
            headerData.AddRange(BitConverter.GetBytes(newMipCount));


            int partIndex      = 0;
            int mipOffsetIndex = 80;
            int uncompMipSize  = newHeight * newWidth;

            if (texData.Type == TextureTypes.DXT1)
            {
                uncompMipSize = (newWidth * newHeight) / 2;
            }
            else if (texData.Type == TextureTypes.DXT5 || texData.Type == TextureTypes.A8)
            {
                uncompMipSize = newWidth * newHeight;
            }
            else if (texData.Type == TextureTypes.A1R5G5B5 || texData.Type == TextureTypes.A4R4G4B4)
            {
                uncompMipSize = (newWidth * newHeight) * 2;
            }
            else
            {
                uncompMipSize = (newWidth * newHeight) * 4;
            }

            for (int i = 0; i < newMipCount; i++)
            {
                headerData.AddRange(BitConverter.GetBytes(mipOffsetIndex));

                int paddedSize = 0;

                for (int j = 0; j < mipPartCount[i]; j++)
                {
                    paddedSize = paddedSize + mipPartOffsets[j + partIndex];
                }

                headerData.AddRange(BitConverter.GetBytes(paddedSize));

                if (uncompMipSize > 16)
                {
                    headerData.AddRange(BitConverter.GetBytes(uncompMipSize));
                }
                else
                {
                    headerData.AddRange(BitConverter.GetBytes(16));
                }

                uncompMipSize = uncompMipSize / 4;

                headerData.AddRange(BitConverter.GetBytes(partIndex));
                headerData.AddRange(BitConverter.GetBytes((int)mipPartCount[i]));

                partIndex      = partIndex + mipPartCount[i];
                mipOffsetIndex = mipOffsetIndex + paddedSize;
            }

            foreach (short part in mipPartOffsets)
            {
                headerData.AddRange(BitConverter.GetBytes(part));
            }

            headerData.AddRange(new byte[headerPadding]);

            return(headerData);
        }
コード例 #20
0
ファイル: TEX.cs プロジェクト: viion-misc/FFXIV_TexTools2
        /// <summary>
        /// Gets the texture data of an item
        /// </summary>
        /// <param name="offset">The offset of the item</param>
        /// <returns>The texture data</returns>
        public static TEXData GetTex(int offset, string datName)
        {
            int datNum = ((offset / 8) & 0x0F) / 2;

            var datPath = string.Format(Info.datDir, datName, datNum);

            var storeOffset = offset;

            offset = Helper.OffsetCorrection(datNum, offset);

            List <byte> decompressedData = new List <byte>();

            TEXData texData = new TEXData();

            using (BinaryReader br = new BinaryReader(File.OpenRead(datPath)))
            {
                br.BaseStream.Seek(offset, SeekOrigin.Begin);

                int headerLength         = br.ReadInt32();
                int fileType             = br.ReadInt32();
                int uncompressedFileSize = br.ReadInt32();
                br.ReadBytes(8);
                texData.MipCount = br.ReadInt32();

                int endOfHeader      = offset + headerLength;
                int mipMapInfoOffset = offset + 24;

                br.BaseStream.Seek(endOfHeader + 4, SeekOrigin.Begin);

                texData.Type   = br.ReadInt32();
                texData.Width  = br.ReadInt16();
                texData.Height = br.ReadInt16();

                for (int i = 0, j = 0; i < texData.MipCount; i++)
                {
                    br.BaseStream.Seek(mipMapInfoOffset + j, SeekOrigin.Begin);

                    int offsetFromHeaderEnd = br.ReadInt32();
                    int mipMapLength        = br.ReadInt32();
                    int mipMapSize          = br.ReadInt32();
                    int mipMapStart         = br.ReadInt32();
                    int mipMapParts         = br.ReadInt32();

                    int mipMapPartOffset = endOfHeader + offsetFromHeaderEnd;

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

                    br.ReadBytes(8);
                    int compressedSize   = br.ReadInt32();
                    int uncompressedSize = br.ReadInt32();

                    if (mipMapParts > 1)
                    {
                        byte[] compressedData       = br.ReadBytes(compressedSize);
                        byte[] decompressedPartData = new byte[uncompressedSize];

                        using (MemoryStream ms = new MemoryStream(compressedData))
                        {
                            using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress))
                            {
                                ds.Read(decompressedPartData, 0, uncompressedSize);
                            }
                        }

                        decompressedData.AddRange(decompressedPartData);

                        for (int k = 1; k < mipMapParts; k++)
                        {
                            byte check = br.ReadByte();
                            while (check != 0x10)
                            {
                                check = br.ReadByte();
                            }

                            br.ReadBytes(7);
                            compressedSize   = br.ReadInt32();
                            uncompressedSize = br.ReadInt32();

                            if (compressedSize != 32000)
                            {
                                compressedData       = br.ReadBytes(compressedSize);
                                decompressedPartData = new byte[uncompressedSize];
                                using (MemoryStream ms = new MemoryStream(compressedData))
                                {
                                    using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress))
                                    {
                                        ds.Read(decompressedPartData, 0, uncompressedSize);
                                    }
                                }
                                decompressedData.AddRange(decompressedPartData);
                            }
                            else
                            {
                                decompressedPartData = br.ReadBytes(uncompressedSize);
                                decompressedData.AddRange(decompressedPartData);
                            }
                        }
                    }
                    else
                    {
                        if (compressedSize != 32000)
                        {
                            var compressedData   = br.ReadBytes(compressedSize);
                            var uncompressedData = new byte[uncompressedSize];

                            using (MemoryStream ms = new MemoryStream(compressedData))
                            {
                                using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress))
                                {
                                    ds.Read(uncompressedData, 0, uncompressedSize);
                                }
                            }

                            decompressedData.AddRange(uncompressedData);
                        }
                        else
                        {
                            var decompressedPartData = br.ReadBytes(uncompressedSize);
                            decompressedData.AddRange(decompressedPartData);
                        }
                    }
                    j = j + 20;
                }

                if (decompressedData.Count < uncompressedFileSize)
                {
                    int    difference = uncompressedFileSize - decompressedData.Count;
                    byte[] padding    = new byte[difference];
                    Array.Clear(padding, 0, difference);
                    decompressedData.AddRange(padding);
                }
            }

            TextureToBitmap(decompressedData.ToArray(), texData);
            texData.TypeString = Info.TextureTypes[texData.Type];
            texData.TexOffset  = storeOffset;
            texData.TEXDatName = datName;

            return(texData);
        }
コード例 #21
0
        /// <summary>
        /// Creates the bitmap data for the models in the character category
        /// </summary>
        /// <remarks>
        /// Because the original textures use channel packing, this method gets the pixel data of each texture
        /// and then recombines them to create the unpacked textures to use in the 3D model.
        /// <see cref="http://wiki.polycount.com/wiki/ChannelPacking"/>
        /// </remarks>
        /// <param name="normalTexData">The texture data of the normal map</param>
        /// <param name="diffuseTexData">The texture data of the diffuse map</param>
        /// <param name="maskTexData">The texture data of the mask map</param>
        /// <param name="specularTexData">The texture data of the normal map</param>
        /// <returns>An array of bitmaps to be used on the model</returns>
        public static BitmapSource[] MakeCharacterMaps(TEXData normalTexData, TEXData diffuseTexData, TEXData maskTexData, TEXData specularTexData, string itemName, string path)
        {
            int   height       = normalTexData.Height;
            int   width        = normalTexData.Width;
            int   tSize        = height * width;
            var   normalBitmap = normalTexData.BMPSouceAlpha;
            Color charaColor;

            if (path.Contains("/body/b"))
            {
                charaColor = (Color)ColorConverter.ConvertFromString(Properties.Settings.Default.Skin_Color);
            }
            else if (path.Contains("/hair/h"))
            {
                charaColor = (Color)ColorConverter.ConvertFromString(Properties.Settings.Default.Hair_Color);
            }
            else if (path.Contains("/face/f"))
            {
                if (path.Contains("_etc_"))
                {
                    charaColor = (Color)ColorConverter.ConvertFromString(Properties.Settings.Default.Etc_Color);
                }
                else if (path.Contains("_iri_"))
                {
                    charaColor = (Color)ColorConverter.ConvertFromString(Properties.Settings.Default.Iris_Color);
                }
                else
                {
                    charaColor = (Color)ColorConverter.ConvertFromString(Properties.Settings.Default.Skin_Color);
                }
            }
            else if (path.Contains("tail/t"))
            {
                if (!path.Contains("c1401") && !path.Contains("c1301"))
                {
                    charaColor = (Color)ColorConverter.ConvertFromString(Properties.Settings.Default.Hair_Color);
                }
                else
                {
                    charaColor = Color.FromArgb(255, 255, 255, 255);
                }
            }
            else
            {
                charaColor = Color.FromArgb(255, 96, 57, 19);
            }

            if (diffuseTexData != null && (diffuseTexData.Height * diffuseTexData.Width) > tSize)
            {
                height = diffuseTexData.Height;
                width  = diffuseTexData.Width;
                tSize  = height * width;
            }

            if (maskTexData != null && (maskTexData.Height * maskTexData.Width) > tSize)
            {
                height = maskTexData.Height;
                width  = maskTexData.Width;
                tSize  = height * width;
            }

            if (specularTexData != null && (specularTexData.Height * specularTexData.Width) > tSize)
            {
                height = specularTexData.Height;
                width  = specularTexData.Width;
                tSize  = height * width;
            }

            byte[] maskPixels     = null;
            byte[] specularPixels = null;
            byte[] normalPixels   = null;
            byte[] diffusePixels  = null;

            BitmapSource[] texBitmaps = new BitmapSource[4];

            if (maskTexData != null)
            {
                if (tSize > (maskTexData.Height * maskTexData.Width))
                {
                    var resized = CreateResizedImage(maskTexData.BMPSouceAlpha, width, height);
                    maskPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    maskPixels = GetBytesFromBitmapSource(maskTexData.BMPSouceAlpha);
                }
            }

            if (diffuseTexData != null)
            {
                try
                {
                    if (tSize > (diffuseTexData.Height * diffuseTexData.Width))
                    {
                        var resized = CreateResizedImage(diffuseTexData.BMPSouceAlpha, width, height);
                        diffusePixels = GetBytesFromBitmapSource((BitmapSource)resized);
                    }
                    else
                    {
                        diffusePixels = GetBytesFromBitmapSource(diffuseTexData.BMPSouceAlpha);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    Debug.WriteLine(ex.StackTrace);
                }
            }

            if (specularTexData != null)
            {
                try
                {
                    if (tSize > (specularTexData.Height * specularTexData.Width))
                    {
                        var resized = CreateResizedImage(specularTexData.BMPSouceAlpha, width, height);
                        specularPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                    }
                    else
                    {
                        specularPixels = GetBytesFromBitmapSource(specularTexData.BMPSouceAlpha);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    Debug.WriteLine(ex.StackTrace);
                }
            }

            if (normalTexData != null)
            {
                if (tSize > (normalTexData.Height * normalTexData.Width))
                {
                    var resized = CreateResizedImage(normalTexData.BMPSouceAlpha, width, height);
                    normalBitmap = (BitmapSource)resized;
                    normalPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    normalPixels = GetBytesFromBitmapSource(normalTexData.BMPSouceAlpha);
                }
            }

            List <byte> diffuseMap  = new List <byte>();
            List <byte> specularMap = new List <byte>();
            List <byte> alphaMap    = new List <byte>();

            BitmapSource bitmapSource;

            System.Drawing.Color diffuseColor;
            System.Drawing.Color specularColor;
            System.Drawing.Color alphaColor;

            int stride = (int)normalBitmap.Width * (32 / 8);

            var scale = 1;

            if (width >= 4096 || height >= 4096)
            {
                scale = 4;
            }
            else if (width >= 2048 || height >= 2048)
            {
                scale = 2;
            }

            var nWidth  = width / scale;
            var nHeight = height / scale;

            if (diffuseTexData == null)
            {
                for (int i = 3; i < normalPixels.Length; i += 4)
                {
                    int alpha = normalPixels[i];

                    diffuseColor = System.Drawing.Color.FromArgb(alpha, (int)((charaColor.R / 255f) * specularPixels[i - 1]), (int)((charaColor.G / 255f) * specularPixels[i - 1]), (int)((charaColor.B / 255f) * specularPixels[i - 1]));

                    specularColor = System.Drawing.Color.FromArgb(255, (int)(specularPixels[i - 2] * 0.1), (int)(specularPixels[i - 2] * 0.1), (int)(specularPixels[i - 2] * 0.1));

                    alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);

                    diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));
                    specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));
                    alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
                }

                bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);
                texBitmaps[0] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);
            }
            else
            {
                for (int i = 3; i < normalPixels.Length; i += 4)
                {
                    int alpha = normalPixels[i - 3];

                    diffuseColor = System.Drawing.Color.FromArgb(alpha, (int)((charaColor.R / 255f) * diffusePixels[i - 1]), (int)((charaColor.G / 255f) * diffusePixels[i - 2]), (int)((charaColor.B / 255f) * diffusePixels[i - 3]));
                    diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));

                    specularColor = System.Drawing.Color.FromArgb(255, (int)(specularPixels[i - 2] * 0.1), (int)(specularPixels[i - 2] * 0.1), (int)(specularPixels[i - 2] * 0.1));
                    specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));

                    alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);
                    alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
                }

                bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);
                texBitmaps[0] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);
            }

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, specularMap.ToArray(), stride);
            texBitmaps[1] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            texBitmaps[2] = (BitmapSource)CreateResizedImage(normalTexData.BMPSouceNoAlpha, nWidth, nHeight);

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, alphaMap.ToArray(), stride);
            texBitmaps[3] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            foreach (var tb in texBitmaps)
            {
                tb.Freeze();
            }

            return(texBitmaps);
        }
コード例 #22
0
        /// <summary>
        /// Creates the DDS header for given texture data.
        /// <see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/bb943982(v=vs.85).aspx"/>
        /// </summary>
        /// <param name="texData">The texture data.</param>
        /// <returns>Byte array containing DDS header</returns>
        public static byte[] CreateDDSHeader(TEXData texData)
        {
            uint        dwPitchOrLinearSize, pfFlags, dwFourCC;
            List <byte> header = new List <byte>();

            // DDS header magic number
            uint dwMagic = 0x20534444;

            header.AddRange(BitConverter.GetBytes(dwMagic));

            // Size of structure. This member must be set to 124.
            uint dwSize = 124;

            header.AddRange(BitConverter.GetBytes(dwSize));

            // Flags to indicate which members contain valid data.
            uint dwFlags = 528391;

            header.AddRange(BitConverter.GetBytes(dwFlags));

            // Surface height (in pixels).
            uint dwHeight = (uint)texData.Height;

            header.AddRange(BitConverter.GetBytes(dwHeight));

            // Surface width (in pixels).
            uint dwWidth = (uint)texData.Width;

            header.AddRange(BitConverter.GetBytes(dwWidth));

            // The pitch or number of bytes per scan line in an uncompressed texture; the total number of bytes in the top level texture for a compressed texture.
            if (texData.Type == 9312)
            {
                dwPitchOrLinearSize = 512;
            }
            else if (texData.Type == 5200)
            {
                dwPitchOrLinearSize = (uint)((dwHeight * dwWidth) * 4);
            }
            else if (texData.Type == 13344)
            {
                dwPitchOrLinearSize = (uint)((dwHeight * dwWidth) / 2);
            }
            else
            {
                dwPitchOrLinearSize = (uint)(dwHeight * dwWidth);
            }
            header.AddRange(BitConverter.GetBytes(dwPitchOrLinearSize));


            // Depth of a volume texture (in pixels), otherwise unused.
            uint dwDepth = 0;

            header.AddRange(BitConverter.GetBytes(dwDepth));

            // Number of mipmap levels, otherwise unused.
            uint dwMipMapCount = (uint)texData.MipCount;

            header.AddRange(BitConverter.GetBytes(dwMipMapCount));

            // Unused.
            byte[] dwReserved1 = new byte[44];
            Array.Clear(dwReserved1, 0, 44);
            header.AddRange(dwReserved1);

            // DDS_PIXELFORMAT start

            // Structure size; set to 32 (bytes).
            uint pfSize = 32;

            header.AddRange(BitConverter.GetBytes(pfSize));

            // Values which indicate what type of data is in the surface.
            if (texData.Type == 5200)
            {
                pfFlags = 65;
            }
            else
            {
                pfFlags = 4;
            }
            header.AddRange(BitConverter.GetBytes(pfFlags));

            // Four-character codes for specifying compressed or custom formats.
            if (texData.Type == 13344)
            {
                dwFourCC = 0x31545844;
            }
            else if (texData.Type == 13361)
            {
                dwFourCC = 0x35545844;
            }
            else if (texData.Type == 13360)
            {
                dwFourCC = 0x33545844;
            }
            else if (texData.Type == 9312)
            {
                dwFourCC = 0x71;
            }
            else if (texData.Type == 5200)
            {
                dwFourCC = 0;
            }
            else
            {
                return(null);
            }
            header.AddRange(BitConverter.GetBytes(dwFourCC));

            if (texData.Type == 5200)
            {
                // Number of bits in an RGB (possibly including alpha) format.
                uint dwRGBBitCount = 32;
                header.AddRange(BitConverter.GetBytes(dwRGBBitCount));

                // Red (or lumiannce or Y) mask for reading color data.
                uint dwRBitMask = 16711680;
                header.AddRange(BitConverter.GetBytes(dwRBitMask));

                // Green (or U) mask for reading color data.
                uint dwGBitMask = 65280;
                header.AddRange(BitConverter.GetBytes(dwGBitMask));

                // Blue (or V) mask for reading color data.
                uint dwBBitMask = 255;
                header.AddRange(BitConverter.GetBytes(dwBBitMask));

                // Alpha mask for reading alpha data.
                uint dwABitMask = 4278190080;
                header.AddRange(BitConverter.GetBytes(dwABitMask));

                // DDS_PIXELFORMAT End

                // Specifies the complexity of the surfaces stored.
                uint dwCaps = 4096;
                header.AddRange(BitConverter.GetBytes(dwCaps));

                // dwCaps2, dwCaps3, dwCaps4, dwReserved2.
                // Unused.
                byte[] blank1 = new byte[16];
                header.AddRange(blank1);
            }
            else
            {
                // dwRGBBitCount, dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask, dwCaps, dwCaps2, dwCaps3, dwCaps4, dwReserved2.
                // Unused.
                byte[] blank1 = new byte[40];
                header.AddRange(blank1);
            }

            return(header.ToArray());
        }
コード例 #23
0
        /// <summary>
        /// Imports the items texture into a dat file
        /// </summary>
        /// <param name="texData">Data for the currently displayed texture</param>
        /// <param name="category">The items category</param>
        /// <param name="itemName">The items name</param>
        /// <param name="internalFilePath">The internal file path of the texture map</param>
        /// <returns>The offset in which the data was placed</returns>
        public static int ImportTexture(TEXData texData, string category, string itemName, string internalFilePath)
        {
            int       textureType, lineNum = 0, offset = 0;
            bool      inModList = false;
            JsonEntry modEntry  = null;

            string dxPath   = Path.GetFileNameWithoutExtension(internalFilePath);
            var    savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + dxPath + ".dds";

            if (File.Exists(savePath))
            {
                if (Properties.Settings.Default.Mod_List == 0)
                {
                    try
                    {
                        using (StreamReader sr = new StreamReader(Info.modListDir))
                        {
                            string line;
                            while ((line = sr.ReadLine()) != null)
                            {
                                modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                                if (modEntry.fullPath.Equals(internalFilePath))
                                {
                                    inModList = true;
                                    break;
                                }
                                lineNum++;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("[Main] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }

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

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

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

                    textureType = Info.DDSType[br.ReadInt32()];

                    if (textureType == texData.Type)
                    {
                        List <byte> newTEX = new List <byte>();

                        int uncompressedLength = (int)new FileInfo(savePath).Length - 128;

                        var DDSInfo = ReadDDS(br, texData, newWidth, newHeight, newMipCount);

                        newTEX.AddRange(MakeType4DATHeader(texData, DDSInfo.Item2, DDSInfo.Item3, uncompressedLength, newMipCount, newWidth, newHeight));
                        newTEX.AddRange(MakeTextureInfoHeader(texData, newWidth, newHeight, newMipCount));
                        newTEX.AddRange(DDSInfo.Item1);

                        offset = WriteToDat(newTEX, modEntry, inModList, internalFilePath, category, itemName, lineNum);
                    }
                    else
                    {
                        MessageBox.Show("Incorrect file type \nExpected: " + Info.TextureTypes[texData.Type] + " Given: " + Info.TextureTypes[textureType], "Texture format error", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
            }
            else
            {
                MessageBox.Show("Could not find file \n" + savePath, "File read Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return(offset);
        }