Example #1
0
        internal DataCoreBinary(byte[] data)
        {
            Reader = new BinaryBlobReader(data, 0);

            header = Reader.Read <RawHeader>();

            structureDefinitions   = Reader.Read <RawStructure>(header.structDefinitionCount);
            propertyDefinitions    = Reader.Read <RawProperty>(header.propertyDefinitionCount);
            enumDefinitions        = Reader.Read <RawEnum>(header.enumDefinitionCount);
            datamappingDefinitions = Reader.Read <RawDataMapping>(header.dataMappingCount);
            records = Reader.Read <RawRecord>(header.recordDefinitionCount);

            int8Values    = Reader.Read <sbyte>(header.int8ValueCount);
            int16Values   = Reader.Read <Int16>(header.int16ValueCount);
            int32Values   = Reader.Read <Int32>(header.int32ValueCount);
            int64Values   = Reader.Read <Int64>(header.int64ValueCount);
            UInt8Values   = Reader.Read <byte>(header.uInt8ValueCount);
            UInt16Values  = Reader.Read <UInt16>(header.uInt16ValueCount);
            UInt32Values  = Reader.Read <UInt32>(header.uInt32ValueCount);
            UInt64Values  = Reader.Read <UInt64>(header.uInt64ValueCount);
            booleanValues = Reader.Read <bool>(header.booleanValueCount);

            singleValues = Reader.Read <float>(header.singleValueCount);
            doubleValues = Reader.Read <double>(header.doubleValueCount);

            guidValues = Reader.Read <Guid>(header.guidValueCount);

            stringValues = Reader.Read <RawStringReference>(header.stringValueCount);
            localeValues = Reader.Read <RawLocaleReference>(header.localeValueCount);

            enumValues         = Reader.Read <Int32>(header.enumValueCount);
            strongValues       = Reader.Read <RawStrongPointer>(header.strongValueCount);
            weakValues         = Reader.Read <RawWeakPointer>(header.weakValueCount);
            referenceValues    = Reader.Read <RawReference>(header.referenceValueCount);
            enumValueNameTable = Reader.Read <RawStringReference>(header.enumOptionCount);

            textBlock = new TextBlock(Reader, header.textLength);

            var start = Reader.Position;

            DataChunk       = Reader.Read <byte>(Reader.Length - start);
            Reader.Position = start;

#if DEBUG
            Console.WriteLine("--------------------------- READ DCB ---------------------------");
            Console.WriteLine($"structureDefinitions: {structureDefinitions.Length}");
            Console.WriteLine($"propertyDefinitions: {propertyDefinitions.Length}");
            Console.WriteLine($"enumDefinitions: {enumDefinitions.Length}");
            Console.WriteLine($"datamappingDefinitions: {datamappingDefinitions.Length}");
            Console.WriteLine($"records: {records.Length}");
            Console.WriteLine();
            Console.WriteLine($"int8Values: {int8Values.Length}");
            Console.WriteLine($"int16Values: {int16Values.Length}");
            Console.WriteLine($"int32Values: {int32Values.Length}");
            Console.WriteLine($"int64Values: {int64Values.Length}");
            Console.WriteLine($"UInt8Values: {UInt8Values.Length}");
            Console.WriteLine($"UInt16Values: {UInt16Values.Length}");
            Console.WriteLine($"UInt32Values: {UInt32Values.Length}");
            Console.WriteLine($"UInt64Values: {UInt64Values.Length}");
            Console.WriteLine($"booleanValues: {booleanValues.Length}");
            Console.WriteLine();
            Console.WriteLine($"singleValues: {singleValues.Length}");
            Console.WriteLine($"doubleValues: {doubleValues.Length}");
            Console.WriteLine();
            Console.WriteLine($"stringValues: {stringValues.Length}");
            Console.WriteLine($"localeValues: {localeValues.Length}");
            Console.WriteLine();
            Console.WriteLine($"enumValues: {enumValues.Length}");
            Console.WriteLine($"strongValues: {strongValues.Length}");
            Console.WriteLine($"weakValues: {weakValues.Length}");
            Console.WriteLine($"referenceValues: {referenceValues.Length}");
            Console.WriteLine($"enumValueNameTable: {enumValueNameTable.Length}");
            Console.WriteLine();
            Console.WriteLine($"textBlock: {textBlock.Size}");
            Console.WriteLine("------------------------- END READ DCB -------------------------");
#endif
        }
Example #2
0
        public TextBlock(BinaryBlobReader reader, int size)
        {
            StringData = reader.Read <byte>(size).ToList();

            iterateblocktask = new TaskFactory().StartNew(_PopulateStrings);
        }
Example #3
0
        public unsafe static void SaveDDS(IFilesystemEntry file, string path = null)
        {
            var filesystem        = file.Filesystem;
            var filesystemManager = filesystem.FilesystemManager;
            var searchName        = file.FullPath;


            var rawData             = file.GetData();
            BinaryBlobReader reader = new BinaryBlobReader(rawData, 0);

            bool isDX10 = false;

            UInt32 dwMagic = reader.ReadUInt32();

            if (dwMagic != uchar32("DDS "))
            {
                throw new Exception("Invalid dds file");
            }
            DDS_HEADER       header = reader.Read <DDS_HEADER>();
            DDS_HEADER_DXT10 header10;

            if (header.dwSize != sizeof(DDS_HEADER))
            {
                throw new Exception("Invalid header size");
            }

            bool fourCCFlag = (header.ddspf.dwFlags & DDS_PIXELFORMAT_FLAGS.DDPF_FOURCC) != 0;

            if (fourCCFlag)
            {
                isDX10 = header.ddspf.dwFourCC == uchar32("DX10");
                if (isDX10)
                {
                    header10 = reader.Read <DDS_HEADER_DXT10>();
                }
            }

            var max_dimension = Math.Min(header.dwWidth, header.dwHeight);
            var mips          = (int)Math.Log((double)max_dimension, 2.0);
            var extra_mips    = Math.Max(mips - 4, 0);

            // hack: there must be a better way to tell
            bool isCubemap = file.Name.EndsWith("_cm_diff.dds", StringComparison.OrdinalIgnoreCase);

            if (isCubemap)
            {
                var index         = searchName.IndexOf("_cm_diff.dds", StringComparison.OrdinalIgnoreCase);
                var prefix        = searchName.Substring(0, index);
                var newSearchName = prefix + "_cm.dds";
                searchName = newSearchName;
            }

            var isNormal = false;

            isNormal |= searchName.EndsWith("ddna.dds", StringComparison.OrdinalIgnoreCase);
            isNormal |= searchName.EndsWith("ddn.dds", StringComparison.OrdinalIgnoreCase);

            byte[] allData;
            {
                List <byte> allDataBuffer   = new List <byte>(rawData);
                List <byte> alphaDataBuffer = new List <byte>(0);

                var chunkFileAlphaPath = $"{searchName}.a";
                var chunkFileAlpha     = filesystem[chunkFileAlphaPath];
                if (chunkFileAlpha != null) //todo programatically determine alpha existance
                {
                    var dataChunkAlpha = chunkFileAlpha.GetData();

                    BinaryBlobReader alphaReader = new BinaryBlobReader(dataChunkAlpha, 0);
                    DDS_HEADER       alphaHeader = reader.Read <DDS_HEADER>();
                    DDS_HEADER_DXT10 alphaHeader10;
                    if (isDX10)
                    {
                        alphaHeader10 = reader.Read <DDS_HEADER_DXT10>();
                    }
                    var remainderBytes = reader.Read <byte>((int)(dataChunkAlpha.LongLength - reader.Position));

                    alphaDataBuffer.AddRange(remainderBytes);
                    //alphaDataBuffer.AddRange(dataChunkAlpha);

                    for (int i = 1; i <= extra_mips; i++)
                    {
                        chunkFileAlphaPath = $"{searchName}.{i}a";
                        chunkFileAlpha     = filesystem[chunkFileAlphaPath];
                        dataChunkAlpha     = chunkFileAlpha.GetData();

                        alphaDataBuffer.AddRange(dataChunkAlpha);
                    }
                }

                for (int i = 1; i <= extra_mips; i++)
                {
                    var chunkFilePath = $"{searchName}.{i}";
                    var chunkFile     = filesystem[chunkFilePath];

                    if (chunkFile == null)
                    {
                        //throw new Exception($"Data chunk {chunkFilePath} missing!");
                        continue; // this is valid for some files
                    }
                    var dataChunk = chunkFile.GetData();

                    allDataBuffer.AddRange(dataChunk);
                }
                allDataBuffer.AddRange(alphaDataBuffer);
                allData = allDataBuffer.ToArray();
            }

            string fullPath;
            var    baseDirectory = path ?? filesystemManager.DirectoryName;

            if (file.IsDirectory)
            {
                fullPath = Path.Combine(baseDirectory, searchName);
            }
            else
            {
                fullPath = path ?? Path.Combine(baseDirectory, searchName);
            }
            var fullDirectory = Path.GetDirectoryName(fullPath);

            Directory.CreateDirectory(fullDirectory);
            using (FileStream fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write))
            {
                fs.Write(allData, 0, allData.Length);
            }
            if (!isCubemap)
            {
                var tiffPath = Path.ChangeExtension(fullPath, ".tiff");
                try
                {
                    var tiffData = ImageProcessing.DDS.Convert(allData, isNormal);
                    using (FileStream fs = new FileStream(tiffPath, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(tiffData, 0, tiffData.Length);
                    }
                }
                catch (Exception e)
                {
                    MainWindow.SetStatus($"Failed to save TIFF {tiffPath} | {e.Message}");
                }
            }
        }