Пример #1
0
        private ushort getNTP3CompressionType(DDSFileInfo DDSFileList, NTP3FileInfo NTP3FileInfo)
        {
            string compressionType = DDSFileList.CompressionType;

            if (compressionType == "No Compression")
            {
                if (Enum.TryParse(NTP3FileInfo.pixelFormat, out PixelFormat pixelFormat))
                {
                    switch (pixelFormat)
                    {
                    case PixelFormat.AbgrExt:
                        return(14);

                    case PixelFormat.R5G6B5IccSgix:
                    default:
                        return(7);
                    }
                }
                else
                {
                    throw new Exception("Cannot parse pixelFormat!");
                }
            }
            else
            {
                return(NTP3CompressedTypes[compressionType]);
            }
        }
Пример #2
0
        /* Pre Base64 conversion code: TODO remove
         * public StreamReader getNTP3InfoStreamReader(string[] NTP3Info)
         * {
         *  string PACPath = rootDirectory + @"\PAC.info";
         *  StreamReader allStream = new StreamReader(PACPath);
         *  string from = NTP3Info.First();
         *  string end = NTP3Info.LastOrDefault(line => line != "");
         *  byte[] NTP3InfoBuffer = readByteArrayinPACInfoBetweenString(allStream, from, end, false);
         *
         *  MemoryStream NTP3InfoMemoryStream = new MemoryStream();
         *  NTP3InfoMemoryStream.Write(NTP3InfoBuffer, 0, NTP3InfoBuffer.Length);
         *
         *  StreamReader NTP3InfoStream = new StreamReader(NTP3InfoMemoryStream);
         *  return NTP3InfoStream;
         * }
         */

        public void parseNTP3Info(string[] NTP3Info, int fileNumber)
        {
            List <NTP3FileInfo> NTP3FileInfoList = new List <NTP3FileInfo>();
            int numberofFiles = convertStringtoInt(getSpecificFileInfoProperties("Number of Files: ", NTP3Info));

            for (int fileNo = 1; fileNo <= numberofFiles; fileNo++)
            {
                string   from    = "#DDS: " + fileNo.ToString();
                string   end     = "#DDS: " + (fileNo + 1).ToString();
                string[] DDSInfo = getSpecificFileInfoPropertiesRegion(NTP3Info, from, end);

                /* Pre Base64 conversion code: TODO remove
                 * string end = fileNo != numberofFiles ? "#DDS: " + (fileNo + 1).ToString() : NTP3Info.LastOrDefault(line => line != "");
                 * byte[] DDSInfoStreamInBytes = readByteArrayinPACInfoBetweenString(NTP3InfoStream, from, end, false);
                 *
                 * MemoryStream DDSStreamMem = new MemoryStream();
                 * DDSStreamMem.Write(DDSInfoStreamInBytes, 0, DDSInfoStreamInBytes.Length);
                 * StreamReader DDSInfoStream = new StreamReader(DDSStreamMem);
                 */

                NTP3FileInfo newFileInfo = new NTP3FileInfo();

                newFileInfo.fileNo     = fileNo;
                newFileInfo.widthReso  = convertStringtoInt(getSpecificFileInfoProperties("Width Resolution: ", DDSInfo));
                newFileInfo.heightReso = convertStringtoInt(getSpecificFileInfoProperties("Height Resolution: ", DDSInfo));
                newFileInfo.hexName    = convertHexStringtoByteArray(getSpecificFileInfoProperties("Name: ", DDSInfo), true);

                byte[] eXtChunk = Convert.FromBase64String(getSpecificFileInfoProperties("eXtChunk: ", DDSInfo));
                newFileInfo.eXtChunk = eXtChunk;

                byte[] GIDXChunk = Convert.FromBase64String(getSpecificFileInfoProperties("GIDXChunk: ", DDSInfo));
                newFileInfo.GIDXChunk = GIDXChunk;

                newFileInfo.CompressionType     = getSpecificFileInfoProperties("Compression Type: ", DDSInfo);
                newFileInfo.DDSDataChunkSize    = convertStringtoInt(getSpecificFileInfoProperties("DDS Data Chunk Size: ", DDSInfo));
                newFileInfo.NTP3HeaderChunkSize = convertStringtoInt(getSpecificFileInfoProperties("NTP3 Header Chunk Size: ", DDSInfo));
                int numberofMipmaps = convertStringtoInt(getSpecificFileInfoProperties("numberofMipmaps: ", DDSInfo));

                string fileName = getSpecificFileInfoProperties("fileName: ", DDSInfo);
                newFileInfo.fileName = fileName;

                if (newFileInfo.CompressionType == "No Compression")
                {
                    newFileInfo.pixelFormat = getSpecificFileInfoProperties("pixelFormat: ", DDSInfo);
                }

                newFileInfo.numberofMipmaps = numberofMipmaps;

                for (int i = 0; i < numberofMipmaps; i++)
                {
                    //newFileInfo.mipmapsSizeList.Add(convertStringtoInt(getSpecificFileInfoProperties("mipmapSize" + i.ToString() + ": ", DDSInfo)));
                }

                NTP3FileInfoList.Add(newFileInfo);
            }

            NTP3FileInfoDic[fileNumber] = NTP3FileInfoList;
        }
Пример #3
0
        private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            TreeViewItem selectedItem = (TreeViewItem)TreeView.SelectedItem;
            var          ddd          = selectedItem.Header;

            try
            {
                GeneralFileInfo tag = (GeneralFileInfo)selectedItem.Tag;

                if (tag != null)
                {
                    fileNumberInput.Text = tag.fileNo.ToString();
                    fileNameInput.Text   = tag.fileName;
                    headerInput.Text     = tag.header;

                    FHMEnumSelect.SelectedIndex = tag.FHMAssetLoadEnum;

                    if (tag.isLinked)
                    {
                        isLinkedFile.IsChecked = true;
                        linkedtoFile.IsEnabled = true;
                        //linkedtoFile.Text = tag.linkedFileName;
                    }
                    else
                    {
                        isLinkedFile.IsChecked = false;
                        linkedtoFile.IsEnabled = false;
                    }
                }
            }
            catch
            {
                NTP3FileInfo tag = (NTP3FileInfo)selectedItem.Tag;

                GeneralFileInfo parentTag = (GeneralFileInfo)(GetSelectedTreeViewItemParent(selectedItem) as TreeViewItem).Tag;

                if (parentTag != null)
                {
                    fileNumberInput.Text = parentTag.fileNo.ToString();
                    fileNameInput.Text   = parentTag.fileName;
                    headerInput.Text     = parentTag.header;

                    FHMEnumSelect.SelectedIndex = parentTag.FHMAssetLoadEnum;

                    if (parentTag.isLinked)
                    {
                        isLinkedFile.IsChecked = true;
                        linkedtoFile.IsEnabled = true;
                        //linkedtoFile.Text = tag.linkedFileName;
                    }
                    else
                    {
                        isLinkedFile.IsChecked = false;
                        linkedtoFile.IsEnabled = false;
                    }
                }
            }
        }
Пример #4
0
        private void repackNTP3(List <NTP3FileInfo> NTP3FileInfoList, List <DDSFileInfo> DDSFileList, MemoryStream NTP3Stream)
        {
            for (int fileNo = 0; fileNo < DDSFileList.Count; fileNo++)
            {
                NTP3FileInfo NTP3Info = NTP3FileInfoList[fileNo];
                DDSFileInfo  DDSFile  = DDSFileList[fileNo];

                // We try to follow the compressionType

                bool writeWithNTP3Header = fileNo == 0 ? true : false;
                writeNTP3Header(writeWithNTP3Header, NTP3Info, DDSFileList, fileNo, NTP3Stream);

                // byteReverse?
                byte[] DDSDataChunkBuffer = addPaddingArrayBuffer(DDSFile.DDSByteStream.ToArray());
                NTP3Stream.Write(DDSDataChunkBuffer, 0, DDSDataChunkBuffer.Length);

                FileStream fileStream = File.Create(Directory.GetCurrentDirectory() + (@"\temp\NTP3-" + fileNumber.ToString()));
                fileStream.Write(DDSDataChunkBuffer, 0, DDSDataChunkBuffer.Length);

                fileStream.Close();
            }
        }
Пример #5
0
        private void writeNTP3Header(bool withHeader, NTP3FileInfo NTP3FileInfo, List <DDSFileInfo> DDSFileList, int fileNo, MemoryStream NTP3Stream)
        {
            DDSFileInfo DDSFile = DDSFileList[fileNo];

            int DDSDataChunkSize = DDSFile.DDSFileChunkSize;

            byte[] NTP3Header   = new byte[0];
            byte[] NTP3Metadata = new byte[0];
            if (withHeader)
            {
                NTP3Header = appendUIntArrayBuffer(NTP3Header, 0x4E545033, true);
                NTP3Header = appendShortArrayBuffer(NTP3Header, 0x0001, false); // Version 1
                NTP3Header = appendShortArrayBuffer(NTP3Header, (ushort)DDSFileList.Count, true);
                NTP3Header = appendZeroArrayBuffer(NTP3Header, 0x08);
            }

            int combinedSizeOffset = NTP3Metadata.Length;

            NTP3Metadata = appendUIntArrayBuffer(NTP3Metadata, 0, true); // Placeholder, will be written once the header part is all done.
            NTP3Metadata = appendZeroArrayBuffer(NTP3Metadata, 0x04);
            NTP3Metadata = appendUIntArrayBuffer(NTP3Metadata, (uint)DDSDataChunkSize, true);
            int NTP3HeaderChunkSizeOffset = NTP3Metadata.Length;

            NTP3Metadata = appendShortArrayBuffer(NTP3Metadata, 0, true); // Placeholder, will be written once the header part is all done.
            NTP3Metadata = appendZeroArrayBuffer(NTP3Metadata, 0x02);

            NTP3Metadata = appendShortArrayBuffer(NTP3Metadata, (ushort)DDSFile.numberofMipmaps, true);

            ushort NTP3compresionType = getNTP3CompressionType(DDSFile, NTP3FileInfo);

            NTP3Metadata = appendShortArrayBuffer(NTP3Metadata, NTP3compresionType, true);
            NTP3Metadata = appendShortArrayBuffer(NTP3Metadata, (ushort)DDSFile.widthReso, true);
            NTP3Metadata = appendShortArrayBuffer(NTP3Metadata, (ushort)DDSFile.heightReso, true);

            // TODO: cube maps
            NTP3Metadata = appendZeroArrayBuffer(NTP3Metadata, 0x18);

            // Manually calculate mipmapsSize, not trusting Info file's.
            List <uint> mipmapsSizeList = calculateMipmapsSize(DDSFile);

            if (mipmapsSizeList.Count > 1)
            {
                // Only write the offsets if there are more than 1 mipmaps. (1 is the original)
                for (int i = 0; i < mipmapsSizeList.Count; i++)
                {
                    NTP3Metadata = appendUIntArrayBuffer(NTP3Metadata, mipmapsSizeList[i], true);
                }
            }


            NTP3Metadata = addPaddingArrayBuffer(NTP3Metadata);

            byte[] eXtChunkBuffer  = NTP3FileInfo.eXtChunk;
            byte[] GIDXChunkBuffer = NTP3FileInfo.GIDXChunk; // TODO: write hash seperately.

            byte[] hexName = NTP3FileInfo.hexName;
            int    a       = 0x8;

            foreach (var name in hexName)
            {
                GIDXChunkBuffer[a] = name;
                a++;
            }

            byte[] NTP3MetadataBuffer = NTP3Metadata.Concat(eXtChunkBuffer).Concat(GIDXChunkBuffer).ToArray();

            // I don't like this implementation, for changing size when everything is written.
            ushort NTP3HeaderChunkSize = (ushort)NTP3MetadataBuffer.Length;
            uint   combinedSize        = (uint)(NTP3HeaderChunkSize + DDSDataChunkSize);

            byte[] NTP3HeaderChunkSizeBuffer = BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(NTP3HeaderChunkSize));
            byte[] combinedSizeBuffer        = BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(combinedSize));

            for (int i = 0; i < NTP3HeaderChunkSizeBuffer.Length; i++)
            {
                NTP3MetadataBuffer[NTP3HeaderChunkSizeOffset + i] = NTP3HeaderChunkSizeBuffer[i];
            }

            for (int i = 0; i < combinedSizeBuffer.Length; i++)
            {
                NTP3MetadataBuffer[combinedSizeOffset + i] = combinedSizeBuffer[i];
            }

            byte[] NTP3HeaderBuffer = NTP3Header.Concat(NTP3MetadataBuffer).ToArray();

            NTP3Stream.Write(NTP3HeaderBuffer, 0, NTP3HeaderBuffer.Length);
        }
Пример #6
0
        private List <DDSFileInfo> parseDDS(List <NTP3FileInfo> NTP3FileInfoList, List <FileInfo> allDDSFiles)
        {
            List <DDSFileInfo> realNTP3FileList = new List <DDSFileInfo>();
            int numberofDDS = allDDSFiles.Count;

            for (int fileNo = 0; fileNo < numberofDDS; fileNo++)
            {
                // https://docs.microsoft.com/en-us/windows/win32/direct3ddds/dds-header
                FileStream   DDSStream    = File.OpenRead(allDDSFiles[fileNo].FullName);
                NTP3FileInfo NTP3FileInfo = NTP3FileInfoList[fileNo];
                changeStreamFile(DDSStream);

                if (readIntBigEndian(DDSStream.Position) != 0x44445320)
                {
                    throw new Exception("DDS header not found!");
                }

                // 7C byte
                DDSStream.Seek(0x04, SeekOrigin.Current);

                // DDSFlags
                dwDDSFlags ddsFlags         = (dwDDSFlags)readIntSmallEndian(DDSStream.Position);
                dwDDSFlags requiredDDSFlags = dwDDSFlags.DDSD_CAPS | dwDDSFlags.DDSD_HEIGHT | dwDDSFlags.DDSD_WIDTH | dwDDSFlags.DDSD_PIXELFORMAT;

                if (!ddsFlags.HasFlag(requiredDDSFlags))
                {
                    throw new Exception("DDS Flags error!");
                }

                // Resolutions
                int heightReso = readIntSmallEndian(DDSStream.Position);
                int widthReso  = readIntSmallEndian(DDSStream.Position);

                if (widthReso != NTP3FileInfo.widthReso || heightReso != NTP3FileInfo.heightReso)
                {
                    throw new Exception("Image resolution mismatch between DDS file and NTP3FileInfo!" + Environment.NewLine + "DDS File: " + allDDSFiles[fileNo].FullName);
                }

                // pitchorLinearSize
                int pitchorLinearSize = readIntSmallEndian(DDSStream.Position); // Not used as per Microsoft's Guideline.

                // depth, skipped.
                DDSStream.Seek(0x04, SeekOrigin.Current);

                // Mipmaps
                int numberofMipmaps = readIntSmallEndian(DDSStream.Position);

                // Reserved 11*4 byte + 4 byte dwSizeforPixelFormat.
                DDSStream.Seek(0x30, SeekOrigin.Current);

                // Pixel Formats.
                dwPixelFormatFlags pixelFlags = (dwPixelFormatFlags)readIntSmallEndian(DDSStream.Position);
                string             compressionType = null;
                uint dwRGBBitCount = 0, dwRBitMask = 0, dwGBitMask = 0, dwBBitMask = 0, dwABitMask = 0, dwCaps = 0, dwCaps2 = 0, dwCaps3 = 0, dwCaps4 = 0;

                DDSFileInfo newFileInfo      = new DDSFileInfo();
                int         DDSFileChunkSize = addPaddingSizeCalculation((int)DDSStream.Length) - 0x80;

                if (pixelFlags.HasFlag(dwPixelFormatFlags.DDPF_FOURCC))
                {
                    // Compressed.
                    compressionType = identifyCompressionType(readIntBigEndian(DDSStream.Position));
                    DDSStream.Seek(0x80, SeekOrigin.Begin);
                    DDSStream.CopyTo(newFileInfo.DDSByteStream); // If not compressed, directly copy the RGBA values.
                }
                else
                {
                    DDSStream.Seek(0x04, SeekOrigin.Current);
                    compressionType = "No Compression";

                    dwRGBBitCount = readUIntSmallEndian(DDSStream.Position);
                    dwRBitMask    = readUIntSmallEndian(DDSStream.Position);
                    dwGBitMask    = readUIntSmallEndian(DDSStream.Position);
                    dwBBitMask    = readUIntSmallEndian(DDSStream.Position);
                    dwABitMask    = readUIntSmallEndian(DDSStream.Position);
                    dwCaps        = readUIntSmallEndian(DDSStream.Position); // Caps are not used to determine stuff although we set them.
                    dwCaps2       = readUIntSmallEndian(DDSStream.Position); // TODO: caps 2 stores cubemap infos.
                    dwCaps3       = readUIntSmallEndian(DDSStream.Position);
                    dwCaps4       = readUIntSmallEndian(DDSStream.Position);

                    DDSStream.Seek(0x04, SeekOrigin.Current); // Reserved 1*4 bytes.

                    bool isAlpha = pixelFlags.HasFlag(dwPixelFormatFlags.DDPF_ALPHAPIXELS);

                    if (dwRGBBitCount % 8 != 0)
                    {
                        throw new Exception("dwRGBitCount not a multiple of 4!");
                    }

                    int           RGBAByteCount = (int)(dwRGBBitCount / 8);
                    byte[]        RGBAChunk     = extractChunk(0x80, DDSFileChunkSize);
                    List <byte[]> RGBA          = parseMaskedRGBA(isAlpha, RGBAChunk, RGBAByteCount, dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask);

                    newFileInfo.pixelFormatRGBAByteSize = RGBAByteCount;

                    // We try to convert based on the pixelFormat in info file, else we use the default of Abgr.
                    byte[] maskedRGBA;
                    if (Enum.TryParse(NTP3FileInfo.pixelFormat, out PixelFormat pixelFormat))
                    {
                        maskedRGBA = writeMaskedRGBA(pixelFormat, RGBA);
                    }
                    else
                    {
                        maskedRGBA = writeMaskedRGBA(PixelFormat.AbgrExt, RGBA);
                    }

                    newFileInfo.DDSByteStream.Write(maskedRGBA, 0, maskedRGBA.Length);
                }

                if (compressionType != NTP3FileInfo.CompressionType)
                {
                    throw new Exception("Compression Type mismatch between DDS file and NTP3FileInfo!" + Environment.NewLine + "DDS File: " + allDDSFiles[fileNo].FullName);
                }

                newFileInfo.fileNo           = fileNo + 1;
                newFileInfo.DDSFileChunkSize = DDSFileChunkSize;
                newFileInfo.widthReso        = widthReso;
                newFileInfo.heightReso       = heightReso;
                newFileInfo.CompressionType  = compressionType;
                newFileInfo.hexName          = convertInt32toByteArray(getDDSFileName(DDSStream.Name), true);
                newFileInfo.numberofMipmaps  = numberofMipmaps;

                realNTP3FileList.Add(newFileInfo);
                DDSStream.Close();
            }

            return(realNTP3FileList);
        }