Exemple #1
0
        public void extractImage(ImageInfo imgInfo, string archiveDir = null, string fileName = null)
        {
            ImageFile imgFile;

            if (fileName == null)
            {
                fileName = texName + "_" + imgInfo.imgSize + getFileFormat();
            }

            byte[] imgBuffer;

            switch (imgInfo.storageType)
            {
            case storage.pccSto:
                imgBuffer = new byte[imgInfo.uncSize];
                Buffer.BlockCopy(imageData, imgInfo.offset, imgBuffer, 0, imgInfo.uncSize);
                break;

            case storage.arcCpr:
            case storage.arcUnc:
                string archivePath = archiveDir + "\\" + arcName + ".tfc";
                if (!File.Exists(archivePath))
                {
                    throw new FileNotFoundException("Texture archive not found in " + archivePath);
                }

                using (FileStream archiveStream = File.OpenRead(archivePath))
                {
                    archiveStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                    if (imgInfo.storageType == storage.arcCpr)
                    {
                        imgBuffer = ZBlock.Decompress(archiveStream, imgInfo.cprSize);
                    }
                    else
                    {
                        imgBuffer = new byte[imgInfo.uncSize];
                        archiveStream.Read(imgBuffer, 0, imgBuffer.Length);
                    }
                }
                break;

            default:
                throw new FormatException("Unsupported texture storage type");
            }

            if (getFileFormat() == ".dds")
            {
                imgFile = new DDS(fileName, imgInfo.imgSize, texFormat, imgBuffer);
            }
            else
            {
                imgFile = new TGA(fileName, imgInfo.imgSize, texFormat, imgBuffer);
            }

            byte[] saveImg = imgFile.ToArray();
            using (FileStream outputImg = new FileStream(imgFile.fileName, FileMode.Create, FileAccess.Write))
                outputImg.Write(saveImg, 0, saveImg.Length);
        }
Exemple #2
0
 public static void resetColors()
 {
     OBlock.resetColor();
     IBlock.resetColor();
     TBlock.resetColor();
     JBlock.resetColor();
     LBlock.resetColor();
     SBlock.resetColor();
     ZBlock.resetColor();
 }
        private void DiscardColors(OptionArgs args)
        {
            OBlock.resetColor();
            IBlock.resetColor();
            TBlock.resetColor();
            JBlock.resetColor();
            LBlock.resetColor();
            SBlock.resetColor();
            ZBlock.resetColor();

            ColorData.saveColors();
        }
Exemple #4
0
        private void Reset(OptionArgs args)
        {
            BlockType.textureAsset = "Game/Bricks/Cat-Eye Brick";

            OBlock.resetColor();
            IBlock.resetColor();
            TBlock.resetColor();
            JBlock.resetColor();
            LBlock.resetColor();
            SBlock.resetColor();
            ZBlock.resetColor();

            ColorData.saveColors();
        }
Exemple #5
0
        /// <summary>
        ///     given export data offset, the function recovers it from the file.
        /// </summary>
        /// <param name="offset">offset position of desired export data</param>
        private void getData(int offset, ExportEntry exp = null)
        {
            byte[] buffer;
            if (bCompressed)
            {
                Block  selected = blockList.Find(block => block.uncOffset <= offset && block.uncOffset + block.uncSize > offset);
                byte[] uncBlock;

                using (FileStream pccStream = File.OpenRead(pccFileName))
                {
                    pccStream.Seek(selected.cprOffset, SeekOrigin.Begin);
                    uncBlock = ZBlock.Decompress(pccStream, selected.cprSize);

                    // the selected block has been read
                    selected.bRead = true;
                }

                // fill all the exports data extracted from the uncBlock
                foreach (ExportEntry expInfo in Exports)
                {
                    if (expInfo.DataOffset >= selected.uncOffset && expInfo.DataOffset + expInfo.DataSize <= selected.uncOffset + selected.uncSize)
                    {
                        buffer = new byte[expInfo.DataSize];
                        Buffer.BlockCopy(uncBlock, expInfo.DataOffset - selected.uncOffset, buffer, 0, expInfo.DataSize);
                        expInfo.Data = buffer;
                    }
                }
            }
            else
            {
                ExportEntry expSelect;
                if (exp == null)
                {
                    int expIndex = Exports.FindIndex(export => export.DataOffset <= offset && export.DataOffset + export.DataSize > offset);
                    expSelect = Exports[expIndex];
                }
                else
                {
                    expSelect = exp;
                }
                using (FileStream pccStream = File.OpenRead(pccFileName))
                {
                    buffer = new byte[expSelect.DataSize];
                    pccStream.Seek(expSelect.DataOffset, SeekOrigin.Begin);
                    pccStream.Read(buffer, 0, buffer.Length);
                    expSelect.Data = buffer;
                }
            }
        }
        private LongIntComboListPart(int capacity)
        {
            ZBlock.CleanZBlockFiles("unsorted", "sorted");

            b12buffer = new List <B12>(0);

            this.enums = new LongIntComboListPartEnumerator[32];

            // Pre-set with defaults.
            int numzblocks    = 139;
            int zblockbufsize = 131072; // 128 KB default.

            if (null != DistributedObjectsSlave.xslave)
            {
                System.Xml.XmlNode xzblocks = DistributedObjectsSlave.xslave["zblocks"];
                if (null != xzblocks)
                {
                    {
                        System.Xml.XmlAttribute xnzb = xzblocks.Attributes["count"];
                        if (null != xnzb)
                        {
                            numzblocks = int.Parse(xnzb.Value);
                        }
                    }
                    {
                        System.Xml.XmlAttribute xzbs = xzblocks.Attributes["addbuffersize"];
                        if (null != xzbs)
                        {
                            zblockbufsize = DistributedObjectsSlave.ParseCapacity(xzbs.Value);
                        }
                    }
                }
            }

            if (XLog.logging)
            {
                XLog.log("Creating " + numzblocks.ToString() + " ZBlock`s");
            }

            zblocks = new ZBlock[numzblocks];
            for (int i = 0; i != numzblocks; i++)
            {
                zblocks[i] = new ZBlock(this, i, zblockbufsize);
            }
        }
Exemple #7
0
        public byte[] extractRawData(ImageInfo imgInfo, string archiveDir = null)
        {
            byte[] imgBuffer;

            switch (imgInfo.storageType)
            {
            case storage.pccSto:
                imgBuffer = new byte[imgInfo.uncSize];
                System.Buffer.BlockCopy(imageData, imgInfo.offset, imgBuffer, 0, imgInfo.uncSize);
                break;

            case storage.arcCpr:
            case storage.arcUnc:
                string archivePath = GetTFC(arcName);
                if (archivePath != null && File.Exists(archivePath))
                {
                    Console.WriteLine("Loaded texture from tfc '" + archivePath + "'.");

                    using (FileStream archiveStream = File.OpenRead(archivePath))
                    {
                        archiveStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                        if (imgInfo.storageType == storage.arcCpr)
                        {
                            imgBuffer = ZBlock.Decompress(archiveStream, imgInfo.cprSize);
                        }
                        else
                        {
                            imgBuffer = new byte[imgInfo.uncSize];
                            archiveStream.Read(imgBuffer, 0, imgBuffer.Length);
                        }
                    }
                }
                else
                {
                    //how do i put default unreal texture
                    imgBuffer = null;     //this will cause exception that will bubble up.
                }

                break;

            default:
                throw new FormatException("Unsupported texture storage type");
            }
            return(imgBuffer); //cannot be uninitialized.
        }
        BlockType randomize()
        {
            BlockType randomBlock;

            switch (random.Next(1, 8))
            {
            case 1:
                randomBlock = new OBlock();
                break;

            case 2:
                randomBlock = new IBlock();
                break;

            case 3:
                randomBlock = new TBlock();
                break;

            case 4:
                randomBlock = new LBlock();
                break;

            case 5:
                randomBlock = new JBlock();
                break;

            case 6:
                randomBlock = new SBlock();
                break;

            case 7:
                randomBlock = new ZBlock();
                break;

            default:
                randomBlock = new LBlock();
                break;
            }

            randomBlock.load(Game.Content);

            return(randomBlock);
        }
            public static void CleanZBlockFiles(params string[] otherinfos)
            {
                // Clean any potential old zblock files...
                bool found = true;

                for (int i = 0; found; i++)
                {
                    found = false;
                    foreach (string otherinfo in otherinfos)
                    {
                        string fn = ZBlock.CreateFileName(i, otherinfo);
                        if (System.IO.File.Exists(fn))
                        {
                            System.IO.File.Delete(fn);
                            found = true;
                        }
                    }
                }
            }
Exemple #10
0
        /// <summary>
        /// Generates a random block
        /// </summary>
        /// <param name="block">A reference to the Block object that will be affected</param>
        private void GenerateBlock(ref Block block)
        {
            switch (random.Next(0, 7))
            {
            case 0:
                block = new IBlock();
                break;

            case 1:
                block = new LBlock();
                break;

            case 2:
                block = new RLBlock();
                break;

            case 3:
                block = new SBlock();
                break;

            case 4:
                block = new SquareBlock();
                break;

            case 5:
                block = new TBlock();
                break;

            case 6:
                block = new ZBlock();
                break;

            default:
                throw new ArgumentException("Bad block type!");
            }
        }
        /// <summary>
        ///     decompress an entire pcc file.
        /// </summary>
        /// <param name="input">pcc file passed in stream format</param>
        /// <returns>a decompressed array of bytes</returns>
        public static byte[] Decompress(Stream input)
        {
            input.Seek(0, SeekOrigin.Begin);
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != 0x9E2A83C1 &&
                magic.Swap() != 0x9E2A83C1)
            {
                throw new FormatException("not a pcc file");
            }
            var endian = magic == 0x9E2A83C1 ? Endian.Little : Endian.Big;

            var versionLo = input.ReadValueU16(endian);
            var versionHi = input.ReadValueU16(endian);

            if (versionLo != 684 &&
                versionHi != 194)
            {
                throw new FormatException("unsupported pcc version");
            }

            long headerSize = 8;

            input.Seek(4, SeekOrigin.Current);
            headerSize += 4;

            var folderNameLength = input.ReadValueS32(endian);

            headerSize += 4;

            var folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);

            input.Seek(folderNameByteLength, SeekOrigin.Current);
            headerSize += folderNameByteLength;

            var packageFlagsOffset = input.Position;
            var packageFlags       = input.ReadValueU32(endian);

            headerSize += 4;

            if ((packageFlags & 0x02000000u) == 0)
            {
                throw new FormatException("pcc file is already decompressed");
            }

            if ((packageFlags & 8) != 0)
            {
                input.Seek(4, SeekOrigin.Current);
                headerSize += 4;
            }

            uint nameCount  = input.ReadValueU32(endian);
            uint nameOffset = input.ReadValueU32(endian);

            input.Seek(52, SeekOrigin.Current);
            headerSize += 60;

            var generationsCount = input.ReadValueU32(endian);

            input.Seek(generationsCount * 12, SeekOrigin.Current);
            headerSize += generationsCount * 12;

            input.Seek(20, SeekOrigin.Current);
            headerSize += 24;

            var blockCount            = input.ReadValueU32(endian);
            int headBlockOff          = (int)input.Position;
            var afterBlockTableOffset = headBlockOff + (blockCount * 16);
            var indataOffset          = afterBlockTableOffset + 8;

            byte[] buff;

            input.Seek(0, SeekOrigin.Begin);
            using (MemoryStream output = new MemoryStream())
            {
                output.Seek(0, SeekOrigin.Begin);

                output.WriteFromStream(input, headerSize);
                output.WriteValueU32(0, endian); // block count

                input.Seek(afterBlockTableOffset, SeekOrigin.Begin);
                output.WriteFromStream(input, 8);

                //check if has extra name list (don't know it's usage...)
                if ((packageFlags & 0x10000000) != 0)
                {
                    long curPos = output.Position;
                    output.WriteFromStream(input, nameOffset - curPos);
                }

                for (int i = 0; i < blockCount; i++)
                {
                    input.Seek(headBlockOff, SeekOrigin.Begin);
                    var uncompressedOffset = input.ReadValueU32(endian);
                    var uncompressedSize   = input.ReadValueU32(endian);
                    var compressedOffset   = input.ReadValueU32(endian);
                    var compressedSize     = input.ReadValueU32(endian);
                    headBlockOff = (int)input.Position;

                    buff = new byte[compressedSize];
                    input.Seek(compressedOffset, SeekOrigin.Begin);
                    input.Read(buff, 0, buff.Length);

                    byte[] temp = ZBlock.Decompress(buff, 0, buff.Length);
                    output.Seek(uncompressedOffset, SeekOrigin.Begin);
                    output.Write(temp, 0, temp.Length);
                }

                output.Seek(packageFlagsOffset, SeekOrigin.Begin);
                output.WriteValueU32(packageFlags & ~0x02000000u, endian);
                return(output.ToArray());
            }
        }
        /// <summary>
        ///     compress an entire pcc into a byte array.
        /// </summary>
        /// <param name="uncompressedPcc">uncompressed pcc stream.</param>
        /// <returns>a compressed array of bytes.</returns>
        public static Stream Compress(Stream uncompressedPcc)
        {
            uncompressedPcc.Position = 0;

            var magic = uncompressedPcc.ReadValueU32(Endian.Little);

            if (magic != 0x9E2A83C1 &&
                magic.Swap() != 0x9E2A83C1)
            {
                throw new FormatException("not a pcc package");
            }
            var endian = magic == 0x9E2A83C1 ?
                         Endian.Little : Endian.Big;
            var encoding = endian == Endian.Little ?
                           Encoding.Unicode : Encoding.BigEndianUnicode;

            var versionLo = uncompressedPcc.ReadValueU16(endian);
            var versionHi = uncompressedPcc.ReadValueU16(endian);

            if (versionLo != 684 &&
                versionHi != 194)
            {
                throw new FormatException("unsupported version");
            }

            uncompressedPcc.Seek(4, SeekOrigin.Current);

            var folderNameLength     = uncompressedPcc.ReadValueS32(endian);
            var folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);

            uncompressedPcc.Seek(folderNameByteLength, SeekOrigin.Current);

            var packageFlagsOffset = uncompressedPcc.Position;
            var packageFlags       = uncompressedPcc.ReadValueU32(endian);

            if ((packageFlags & 8) != 0)
            {
                uncompressedPcc.Seek(4, SeekOrigin.Current);
            }

            var nameCount         = uncompressedPcc.ReadValueU32(endian);
            var namesOffset       = uncompressedPcc.ReadValueU32(endian);
            var exportCount       = uncompressedPcc.ReadValueU32(endian);
            var exportInfosOffset = uncompressedPcc.ReadValueU32(endian);
            SortedDictionary <uint, uint> exportDataOffsets = new SortedDictionary <uint, uint>();

            Stream data;

            if ((packageFlags & 0x02000000) == 0)
            {
                data = uncompressedPcc;
            }
            else
            {
                throw new FormatException("pcc data is compressed");
            }

            // get info about export data, sizes and offsets
            data.Seek(exportInfosOffset, SeekOrigin.Begin);
            for (uint i = 0; i < exportCount; i++)
            {
                var classIndex = data.ReadValueS32(endian);
                data.Seek(4, SeekOrigin.Current);
                var outerIndex      = data.ReadValueS32(endian);
                var objectNameIndex = data.ReadValueS32(endian);
                data.Seek(16, SeekOrigin.Current);

                uint exportDataSize   = data.ReadValueU32(endian);
                uint exportDataOffset = data.ReadValueU32(endian);
                exportDataOffsets.Add(exportDataOffset, exportDataSize);

                data.Seek(4, SeekOrigin.Current);
                var count = data.ReadValueU32(endian);
                data.Seek(count * 4, SeekOrigin.Current);
                data.Seek(20, SeekOrigin.Current);
            }

            const uint maxBlockSize = 0x100000;
            Stream     outputStream = new MemoryStream();

            // copying pcc header
            byte[] buffer = new byte[130];
            uncompressedPcc.Seek(0, SeekOrigin.Begin);
            uncompressedPcc.Read(buffer, 0, 130);
            outputStream.Write(buffer, 0, buffer.Length);

            //add compressed pcc flag
            uncompressedPcc.Seek(12, SeekOrigin.Begin);
            folderNameLength     = uncompressedPcc.ReadValueS32();
            folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);
            uncompressedPcc.Seek(folderNameByteLength, SeekOrigin.Current);
            outputStream.Seek(uncompressedPcc.Position, SeekOrigin.Begin);

            packageFlags  = uncompressedPcc.ReadValueU32();
            packageFlags |= 0x02000000; // add compression flag
            outputStream.WriteValueU32(packageFlags);

            outputStream.Seek(buffer.Length, SeekOrigin.Begin);

            long       outOffsetData;
            long       outOffsetBlockInfo;
            long       inOffsetData = namesOffset;
            List <int> blockSizes   = new List <int>();
            int        countSize    = (int)(exportDataOffsets.Min(obj => obj.Key) - namesOffset);

            //count the number of blocks and relative sizes
            uint lastOffset = exportDataOffsets.Min(obj => obj.Key);

            foreach (KeyValuePair <uint, uint> exportInfo in exportDataOffsets)
            {
                // part that adds empty spaces (leaved when editing export data and moved to the end of pcc) into the count
                if (exportInfo.Key != lastOffset)
                {
                    int emptySpace = (int)(exportInfo.Key - lastOffset);
                    if (countSize + emptySpace > maxBlockSize)
                    {
                        blockSizes.Add(countSize);
                        countSize = 0;
                    }
                    else
                    {
                        countSize += emptySpace;
                    }
                }

                // adds export data into the count
                if (countSize + exportInfo.Value > maxBlockSize)
                {
                    blockSizes.Add(countSize);
                    countSize = (int)exportInfo.Value;
                }
                else
                {
                    countSize += (int)exportInfo.Value;
                }

                lastOffset = exportInfo.Key + exportInfo.Value;
            }
            blockSizes.Add(countSize);

            outputStream.WriteValueS32(blockSizes.Count);
            outOffsetBlockInfo = outputStream.Position;
            outOffsetData      = namesOffset + (blockSizes.Count * 16);

            uncompressedPcc.Seek(namesOffset, SeekOrigin.Begin);
            //divide the block in segments
            for (int i = 0; i < blockSizes.Count; i++)
            {
                int currentUncBlockSize = blockSizes[i];

                outputStream.Seek(outOffsetBlockInfo, SeekOrigin.Begin);
                outputStream.WriteValueU32((uint)uncompressedPcc.Position);
                outputStream.WriteValueS32(currentUncBlockSize);
                outputStream.WriteValueU32((uint)outOffsetData);

                byte[] inputBlock = new byte[currentUncBlockSize];
                uncompressedPcc.Read(inputBlock, 0, currentUncBlockSize);
                byte[] compressedBlock = ZBlock.Compress(inputBlock, 0, inputBlock.Length);

                outputStream.WriteValueS32(compressedBlock.Length);
                outOffsetBlockInfo = outputStream.Position;

                outputStream.Seek(outOffsetData, SeekOrigin.Begin);
                outputStream.Write(compressedBlock, 0, compressedBlock.Length);
                outOffsetData = outputStream.Position;
            }

            //copying some unknown values + extra names list
            int bufferSize = (int)namesOffset - 0x86;

            buffer = new byte[bufferSize];
            uncompressedPcc.Seek(0x86, SeekOrigin.Begin);
            uncompressedPcc.Read(buffer, 0, buffer.Length);
            outputStream.Seek(outOffsetBlockInfo, SeekOrigin.Begin);
            outputStream.Write(buffer, 0, buffer.Length);

            outputStream.Seek(0, SeekOrigin.Begin);

            return(outputStream);
        }
Exemple #13
0
        /// <summary>
        ///     PCCObject class constructor. It also load namelist, importlist and exportinfo (not exportdata) from pcc file
        /// </summary>
        /// <param name="pccFilePath">full path + file name of desired pcc file.</param>
        public PCCObject(string pccFilePath, bool fullFileInMemory = false)
        {
            Loaded      = true;
            pccFileName = Path.GetFullPath(pccFilePath);
            Debug.WriteLine("Loading pcc " + pccFileName);
            using (FileStream pccStream = File.OpenRead(pccFileName))
            {
                Names   = new List <string>();
                Imports = new List <ImportEntry>();
                Exports = new List <ExportEntry>();

                pccStream.Read(header, 0, header.Length);
                if (magic != ZBlock.magic &&
                    magic.Swap() != ZBlock.magic)
                {
                    throw new FormatException("not a pcc file");
                }

                // BitConverter isn't working?!?!
                if (magic == 0x9E2A83C1)
                {
                    BitConverter.IsLittleEndian = true;
                }
                else
                {
                    BitConverter.IsLittleEndian = true;
                }

                if (lowVers != 684 && highVers != 194)
                {
                    throw new FormatException("unsupported version");
                }

                Stream listsStream;

                if (bCompressed)
                {
                    Debug.WriteLine("COMPRESSED...");
                    // seeks the blocks info position
                    pccStream.Seek(idxOffsets + 60, SeekOrigin.Begin);
                    int generator = pccStream.ReadValueS32();
                    pccStream.Seek((generator * 12) + 20, SeekOrigin.Current);

                    int blockCount = pccStream.ReadValueS32();
                    blockList = new List <Block>();

                    // creating the Block list
                    for (int i = 0; i < blockCount; i++)
                    {
                        Block temp = new Block();
                        temp.uncOffset = pccStream.ReadValueS32();
                        temp.uncSize   = pccStream.ReadValueS32();
                        temp.cprOffset = pccStream.ReadValueS32();
                        temp.cprSize   = pccStream.ReadValueS32();
                        blockList.Add(temp);
                    }

                    // correcting the header, in case there's need to be saved
                    Buffer.BlockCopy(BitConverter.GetBytes((int)0), 0, header, header.Length - 12, sizeof(int));
                    pccStream.Read(header, header.Length - 8, 8);
                    headerEnd = (int)pccStream.Position;

                    // copying the extraNamesList
                    int extraNamesLenght = blockList[0].cprOffset - headerEnd;
                    if (extraNamesLenght > 0)
                    {
                        extraNamesList = new byte[extraNamesLenght];
                        pccStream.Read(extraNamesList, 0, extraNamesLenght);
                        //FileStream fileStream = File.Create(Path.GetDirectoryName(pccFileName) + "\\temp.bin");
                        //fileStream.Write(extraNamesList, 0, extraNamesLenght);
                        //MessageBox.Show("posizione: " + pccStream.Position.ToString("X8"));
                    }

                    // decompress first block that holds infos about names, imports and exports
                    pccStream.Seek(blockList[0].cprOffset, SeekOrigin.Begin);
                    byte[] uncBlock = ZBlock.Decompress(pccStream, blockList[0].cprSize);

                    // write decompressed block inside temporary stream
                    listsStream = new MemoryStream();
                    listsStream.Seek(blockList[0].uncOffset, SeekOrigin.Begin);
                    listsStream.Write(uncBlock, 0, uncBlock.Length);
                }
                else
                {
                    listsStream = pccStream;
                    headerEnd   = (int)NameOffset;

                    // copying the extraNamesList
                    int extraNamesLenght = headerEnd - headerSize;
                    if (extraNamesLenght > 0)
                    {
                        extraNamesList = new byte[extraNamesLenght];
                        listsStream.Seek(headerSize, SeekOrigin.Begin);
                        listsStream.Read(extraNamesList, 0, extraNamesLenght);
                        //FileStream fileStream = File.Create(Path.GetDirectoryName(pccFileName) + "\\temp.bin");
                        //fileStream.Write(extraNamesList, 0, extraNamesLenght);
                        //MessageBox.Show("posizione: " + pccStream.Position.ToString("X8"));
                    }
                }

                /*if(bExtraNamesList)
                 * {
                 *  int extraNamesListSize = namesOffset - headerEnd;
                 *  extraNamesList = new byte[extraNamesListSize];
                 *  pccStream.Seek(headerEnd, SeekOrigin.Begin);
                 *  pccStream.Read(extraNamesList, 0, extraNamesList.Length);
                 * }*/

                // fill names list
                listsStream.Seek(NameOffset, SeekOrigin.Begin);
                for (int i = 0; i < NameCount; i++)
                {
                    long   currOffset = listsStream.Position;
                    int    strLength  = listsStream.ReadValueS32();
                    string str        = listsStream.ReadString(strLength * -2, true, Encoding.Unicode);
                    //Debug.WriteLine("Read name "+i+" "+str+" length: " + strLength+", offset: "+currOffset);
                    Names.Add(str);
                }
                //Debug.WriteLine("Names done. Current offset: "+listsStream.Position);
                //Debug.WriteLine("Import Offset: " + ImportOffset);

                // fill import list
                //Console.Out.WriteLine("IMPORT OFFSET: " + ImportOffset);
                listsStream.Seek(ImportOffset, SeekOrigin.Begin);
                byte[] buffer = new byte[ImportEntry.byteSize];
                for (int i = 0; i < ImportCount; i++)
                {
                    long        offset = listsStream.Position;
                    ImportEntry e      = new ImportEntry(this, listsStream);
                    Imports.Add(e);
                    //Debug.WriteLine("Read import " + i + " " + e.ObjectName + ", offset: " + offset);
                }
                ;

                // fill export list (only the headers, not the data)
                listsStream.Seek(ExportOffset, SeekOrigin.Begin);
                //Console.Out.WriteLine("Export OFFSET: " + ImportOffset);
                for (int i = 0; i < ExportCount; i++)
                {
                    uint expInfoOffset = (uint)listsStream.Position;

                    listsStream.Seek(44, SeekOrigin.Current);
                    int count = listsStream.ReadValueS32();
                    listsStream.Seek(-48, SeekOrigin.Current);

                    int expInfoSize = 68 + (count * 4);
                    buffer = new byte[expInfoSize];

                    listsStream.Read(buffer, 0, buffer.Length);
                    ExportEntry e = new ExportEntry(this, buffer, expInfoOffset);
                    //Debug.WriteLine("Read export " + i + " " + e.ObjectName + ", offset: " + expInfoOffset+ ", size: "+expInfoSize);
                    Exports.Add(e);
                }
            }
            //Debug.WriteLine(getMetadataString());
        }
Exemple #14
0
        // KFreon: Decompresses specific blocks if compressed, or returns data specified by offset and length.
        public byte[] Decompressor(uint offset, int length)
        {
            using (MemoryStream retval = new MemoryStream())
            {
                uint newoffset = 0;

                /*if (blockList.Count == 1)
                 *  bCompressed = false;*/
                /*if (bCompressed)
                 * {*/
                // KFreon: Find datablocks to decompress
                int DataStart = 0;
                int DataEnd   = 0;
                int got       = 0;
                for (int m = 0; m < blockList.Count; m++)
                {
                    if (got == 0 && blockList[m].uncOffset + blockList[m].uncSize > offset)
                    {
                        DataStart = m;
                        got++;
                    }

                    if (got == 1 && blockList[m].uncOffset + blockList[m].uncSize > offset + length)
                    {
                        DataEnd = m;
                        got++;
                    }

                    if (got == 2)
                    {
                        break;
                    }
                }

                if (DataEnd == 0 && DataStart != 0)
                {
                    DataEnd = DataStart;
                }

                /*// KFreon: Move end along so as able to read
                 * if (DataStart == DataEnd)
                 *  DataEnd++;*/

                // KFreon: Decompress blocks
                newoffset = offset - (uint)blockList[DataStart].uncOffset;
                for (int i = DataStart; i <= DataEnd; i++)
                {
                    DataStream.Seek(blockList[i].cprOffset, SeekOrigin.Begin);
                    //retval.Seek(blockList[i].uncOffset, SeekOrigin.Begin);
                    retval.WriteBytes(ZBlock.Decompress(DataStream, blockList[i].cprSize));
                }

                /*}
                 * else
                 * {
                 *  listsStream.Seek(offset, SeekOrigin.Begin);
                 *  retval.ReadFrom(listsStream, length);
                 *  newoffset = 0;
                 * }*/
                //retval.Seek(offset, SeekOrigin.Begin);
                retval.Seek(newoffset, SeekOrigin.Begin);
                return(retval.ReadBytes(length));
            }
        }
Exemple #15
0
        public void ME3PCCObjectHelper(MemoryStream tempStream, string filePath, bool TablesOnly)
        {
            tempStream.Seek(0, SeekOrigin.Begin);
            DataStream = new MemoryStream();
            tempStream.WriteTo(DataStream);
            Names   = new List <string>();
            Imports = new List <ME3ImportEntry>();
            Exports = new List <ME3ExportEntry>();

            header = tempStream.ReadBytes(headerSize);
            if (magic != ZBlock.magic &&
                magic.Swap() != ZBlock.magic)
            {
                throw new FormatException(filePath + " is not a pcc file");
            }

            if (lowVers != 684 && highVers != 194)
            {
                throw new FormatException("unsupported version");
            }

            if (bCompressed)
            {
                // seeks the blocks info position
                tempStream.Seek(idxOffsets + 60, SeekOrigin.Begin);
                int generator = tempStream.ReadValueS32();
                tempStream.Seek((generator * 12) + 20, SeekOrigin.Current);

                int blockCount = tempStream.ReadValueS32();
                blockList = new List <Block>();

                // creating the Block list
                for (int i = 0; i < blockCount; i++)
                {
                    Block temp = new Block();
                    temp.uncOffset = tempStream.ReadValueS32();
                    temp.uncSize   = tempStream.ReadValueS32();
                    temp.cprOffset = tempStream.ReadValueS32();
                    temp.cprSize   = tempStream.ReadValueS32();
                    blockList.Add(temp);
                }

                // correcting the header, in case there's need to be saved
                Buffer.BlockCopy(BitConverter.GetBytes(0), 0, header, header.Length - 12, sizeof(int));
                tempStream.Read(header, header.Length - 8, 8);
                headerEnd = (int)tempStream.Position;

                // copying the extraNamesList
                int extraNamesLenght = blockList[0].cprOffset - headerEnd;
                if (extraNamesLenght > 0)
                {
                    extraNamesList = new byte[extraNamesLenght];
                    tempStream.Read(extraNamesList, 0, extraNamesLenght);
                    //FileStream fileStream = File.Create(Path.GetDirectoryName(pccFileName) + "\\temp.bin");
                    //fileStream.Write(extraNamesList, 0, extraNamesLenght);
                    //MessageBox.Show("posizione: " + pccStream.Position.ToString("X8"));
                }

                int dataStart = 0;
                using (MemoryStream he = new MemoryStream(header))
                {
                    he.Seek(0, SeekOrigin.Begin);
                    he.ReadValueS32();
                    he.ReadValueS32();
                    dataStart = he.ReadValueS32();
                }

                if (TablesOnly)
                {
                    int TableStart = 0;
                    for (int m = 0; m < blockList.Count; m++)
                    {
                        if (blockList[m].uncOffset + blockList[m].uncSize > dataStart)
                        {
                            TableStart = m;
                            break;
                        }
                    }

                    listsStream = new MemoryStream();
                    tempStream.Seek(blockList[TableStart].cprOffset, SeekOrigin.Begin);
                    listsStream.Seek(blockList[TableStart].uncOffset, SeekOrigin.Begin);
                    listsStream.WriteBytes(ZBlock.Decompress(tempStream, blockList[TableStart].cprSize));
                    DataStream = new MemoryStream();
                    tempStream.WriteTo(DataStream);
                    bCompressed = true;
                }
                else
                {
                    //Decompress ALL blocks
                    listsStream = new MemoryStream();
                    for (int i = 0; i < blockCount; i++)
                    {
                        tempStream.Seek(blockList[i].cprOffset, SeekOrigin.Begin);
                        listsStream.Seek(blockList[i].uncOffset, SeekOrigin.Begin);
                        listsStream.WriteBytes(ZBlock.Decompress(tempStream, blockList[i].cprSize));
                    }
                }
                bCompressed = false;
            }
            else
            {
                listsStream = new MemoryStream();
                listsStream.WriteBytes(tempStream.ToArray());
            }
            tempStream.Dispose();

            //Fill name list
            listsStream.Seek(NameOffset, SeekOrigin.Begin);
            for (int i = 0; i < NameCount; i++)
            {
                int strLength = listsStream.ReadValueS32();
                Names.Add(listsStream.ReadString(strLength * -2, true, Encoding.Unicode));
            }

            // fill import list
            listsStream.Seek(ImportOffset, SeekOrigin.Begin);
            byte[] buffer = new byte[ME3ImportEntry.byteSize];
            for (int i = 0; i < ImportCount; i++)
            {
                Imports.Add(new ME3ImportEntry(this, listsStream));
            }

            //fill export list
            listsStream.Seek(ExportOffset, SeekOrigin.Begin);
            for (int i = 0; i < ExportCount; i++)
            {
                uint expInfoOffset = (uint)listsStream.Position;

                listsStream.Seek(44, SeekOrigin.Current);
                int count = listsStream.ReadValueS32();
                listsStream.Seek(-48, SeekOrigin.Current);

                int expInfoSize = 68 + (count * 4);
                buffer = new byte[expInfoSize];

                listsStream.Read(buffer, 0, buffer.Length);
                Exports.Add(new ME3ExportEntry(this, buffer, expInfoOffset));
            }
        }
        /// <summary>
        ///     decompress an entire ME3 pcc file into a new stream
        /// </summary>
        /// <param name="input">pcc file passed in stream format</param>
        /// <returns>a decompressed array of bytes</returns>
        public static MemoryStream DecompressME3(Stream input)
        {
            input.Seek(0, SeekOrigin.Begin);
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != 0x9E2A83C1 &&
                magic.Swap() != 0x9E2A83C1)
            {
                throw new FormatException("not a pcc file");
            }
            var endian = magic == 0x9E2A83C1 ? Endian.Little : Endian.Big;

            var versionLo = input.ReadValueU16(endian);
            var versionHi = input.ReadValueU16(endian);

            if (versionLo != 684 &&
                versionHi != 194)
            {
                throw new FormatException("unsupported pcc version");
            }

            long headerSize = 8;

            input.Seek(4, SeekOrigin.Current);
            headerSize += 4;

            var folderNameLength = input.ReadValueS32(endian);

            headerSize += 4;

            var folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);

            input.Seek(folderNameByteLength, SeekOrigin.Current);
            headerSize += folderNameByteLength;

            var packageFlagsOffset = input.Position;
            var packageFlags       = input.ReadValueU32(endian);

            headerSize += 4;

            if ((packageFlags & 0x02000000u) == 0)
            {
                throw new FormatException("pcc file is already decompressed");
            }

            if ((packageFlags & 8) != 0)
            {
                input.Seek(4, SeekOrigin.Current);
                headerSize += 4;
            }

            uint nameCount  = input.ReadValueU32(endian);
            uint nameOffset = input.ReadValueU32(endian);

            input.Seek(52, SeekOrigin.Current);
            headerSize += 60;

            var generationsCount = input.ReadValueU32(endian);

            input.Seek(generationsCount * 12, SeekOrigin.Current);
            headerSize += generationsCount * 12;

            input.Seek(20, SeekOrigin.Current);
            headerSize += 24;

            var blockCount            = input.ReadValueU32(endian);
            int headBlockOff          = (int)input.Position;
            var afterBlockTableOffset = headBlockOff + (blockCount * 16);
            var indataOffset          = afterBlockTableOffset + 8;

            byte[] buff;

            input.Seek(0, SeekOrigin.Begin);
            MemoryStream output = new MemoryStream();

            output.Seek(0, SeekOrigin.Begin);

            output.WriteFromStream(input, headerSize);
            output.WriteValueU32(0, endian); // block count

            input.Seek(afterBlockTableOffset, SeekOrigin.Begin);
            output.WriteFromStream(input, 8);

            //check if has extra name list (don't know it's usage...)
            if ((packageFlags & 0x10000000) != 0)
            {
                long curPos = output.Position;
                output.WriteFromStream(input, nameOffset - curPos);
            }

            //decompress blocks in parallel
            Task <byte[]>[] tasks = new Task <byte[]> [blockCount];
            uint[]          uncompressedOffsets = new uint[blockCount];
            for (int i = 0; i < blockCount; i++)
            {
                input.Seek(headBlockOff, SeekOrigin.Begin);
                uncompressedOffsets[i] = input.ReadValueU32(endian);
                var uncompressedSize = input.ReadValueU32(endian);
                var compressedOffset = input.ReadValueU32(endian);
                var compressedSize   = input.ReadValueU32(endian);
                headBlockOff = (int)input.Position;

                buff = new byte[compressedSize];
                input.Seek(compressedOffset, SeekOrigin.Begin);
                input.Read(buff, 0, buff.Length);

                tasks[i] = ZBlock.DecompressAsync(buff);
            }
            Task.WaitAll(tasks);
            for (int i = 0; i < blockCount; i++)
            {
                output.Seek(uncompressedOffsets[i], SeekOrigin.Begin);
                output.WriteBytes(tasks[i].Result);
            }

            //Do not change the IsCompressed bit as it will not accurately reflect the state of the file on disk.
            //output.Seek(packageFlagsOffset, SeekOrigin.Begin);
            //output.WriteValueU32(packageFlags & ~0x02000000u, endian); //Mark file as decompressed.
            return(output);
        }
Exemple #17
0
        public void replaceImage(string strImgSize, string fileToReplace, string archiveDir)
        {
            ImageSize imgSize = ImageSize.stringToSize(strImgSize);

            if (!imgList.Exists(img => img.imgSize == imgSize))
            {
                throw new FileNotFoundException("Image with resolution " + imgSize + " isn't found");
            }

            int       imageIdx = imgList.FindIndex(img => img.imgSize == imgSize);
            ImageInfo imgInfo  = imgList[imageIdx];

            if (!File.Exists(fileToReplace))
            {
                throw new FileNotFoundException("invalid file to replace: " + fileToReplace);
            }

            // check if replacing image is supported
            ImageFile imgFile;
            string    fileFormat = Path.GetExtension(fileToReplace);

            switch (fileFormat)
            {
            case ".dds": imgFile = new DDS(fileToReplace, null); break;

            case ".tga": imgFile = new TGA(fileToReplace, null); break;

            default: throw new FileFormatException(fileFormat + " image extension not supported");
            }

            // check if images have same format type
            if (texFormat != imgFile.format)
            {
                DialogResult selection = MessageBox.Show("Warning, replacing image has format " + imgFile.subtype() + " while original has " + texFormat + ", would you like to replace it anyway?", "Warning, different image format found", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (selection == DialogResult.Yes)
                {
                    imgFile.format = texFormat;
                }
                else
                {
                    return;
                }
                //throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype());
            }

            byte[] imgBuffer;

            // if the image is empty then recover the archive compression from the image list
            if (imgInfo.storageType == storage.empty)
            {
                imgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType;
                imgInfo.uncSize     = imgFile.resize().Length;
                imgInfo.cprSize     = imgFile.resize().Length;
            }

            switch (imgInfo.storageType)
            {
            case storage.arcCpr:
            case storage.arcUnc:
                string archivePath = archiveDir + "\\" + arcName + ".tfc";
                if (!File.Exists(archivePath))
                {
                    throw new FileNotFoundException("Texture archive not found in " + archivePath);
                }

                if (getFileFormat() == ".tga")
                {
                    imgBuffer = imgFile.resize();     // shrink image to essential data
                }
                else
                {
                    imgBuffer = imgFile.imgData;
                }

                if (imgBuffer.Length != imgInfo.uncSize)
                {
                    throw new FormatException("image sizes do not match, original is " + imgInfo.uncSize + ", new is " + imgBuffer.Length);
                }

                using (FileStream archiveStream = new FileStream(archivePath, FileMode.Append, FileAccess.Write))
                {
                    int newOffset = (int)archiveStream.Position;

                    if (imgInfo.storageType == storage.arcCpr)
                    {
                        imgBuffer = ZBlock.Compress(imgBuffer);

                        /*byte[] compressed = ZBlock.Compress(imgBuffer);
                         * archiveStream.Write(compressed, 0, compressed.Length);*/
                        imgInfo.cprSize = imgBuffer.Length;
                    }
                    //else
                    archiveStream.Write(imgBuffer, 0, imgBuffer.Length);

                    imgInfo.offset = newOffset;
                }
                break;

            case storage.pccSto:
                imgBuffer = imgFile.imgData;     // copy image data as-is
                if (imgBuffer.Length != imgInfo.uncSize)
                {
                    throw new FormatException("image sizes do not match, original is " + imgInfo.uncSize + ", new is " + imgBuffer.Length);
                }

                using (MemoryStream dataStream = new MemoryStream(imageData))
                {
                    dataStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                    dataStream.Write(imgBuffer, 0, imgBuffer.Length);
                }

                break;
            }

            imgList[imageIdx] = imgInfo;
        }
Exemple #18
0
        public void replaceImage(string strImgSize, ImageFile im, string archiveDir)
        {
            ImageSize imgSize = ImageSize.stringToSize(strImgSize);

            if (!imgList.Exists(img => img.imgSize == imgSize))
            {
                throw new FileNotFoundException("Image with resolution " + imgSize + " isn't found");
            }

            int       imageIdx = privateImageList.FindIndex(img => img.imgSize == imgSize);
            ImageInfo imgInfo  = privateImageList[imageIdx];

            ImageFile         imgFile       = im;
            ImageEngineFormat imgFileFormat = Textures.Methods.ParseFormat(imgFile.format);


            // check if images have same format type
            if (texFormat != imgFileFormat)
            {
                bool res = KFreonLib.Misc.Methods.DisplayYesNoDialogBox("Warning, replacing image has format " + imgFile.subtype() + " while original has " + texFormat + ", would you like to replace it anyway?", "Warning, different image format found");
                if (res)
                {
                    imgFile.format = Textures.Methods.StringifyFormat(texFormat);
                }
                else
                {
                    return;
                }
                //throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype());
            }

            byte[] imgBuffer;

            // if the image is empty then recover the archive compression from the image list
            if (imgInfo.storageType == storage.empty)
            {
                imgInfo.storageType = privateImageList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType;
                imgInfo.uncSize     = imgFile.resize().Length;
                imgInfo.cprSize     = imgFile.resize().Length;
            }

            switch (imgInfo.storageType)
            {
            case storage.arcCpr:
            case storage.arcUnc:
                string archivePath = archiveDir + "\\" + arcName + ".tfc";
                if (!File.Exists(archivePath))
                {
                    throw new FileNotFoundException("Texture archive not found in " + archivePath);
                }

                if (getFileFormat() == ".tga")
                {
                    imgBuffer = imgFile.resize();     // shrink image to essential data
                }
                else
                {
                    imgBuffer = imgFile.imgData;
                }

                if (imgBuffer.Length != imgInfo.uncSize)
                {
                    throw new FormatException("image sizes do not match, original is " + imgInfo.uncSize + ", new is " + imgBuffer.Length);
                }

                using (FileStream archiveStream = new FileStream(archivePath, FileMode.Append, FileAccess.Write))
                {
                    int newOffset = (int)archiveStream.Position;

                    if (imgInfo.storageType == storage.arcCpr)
                    {
                        imgBuffer = ZBlock.Compress(imgBuffer);

                        /*byte[] compressed = ZBlock.Compress(imgBuffer);
                         * archiveStream.Write(compressed, 0, compressed.Length);*/
                        imgInfo.cprSize = imgBuffer.Length;
                    }
                    //else
                    archiveStream.Write(imgBuffer, 0, imgBuffer.Length);

                    imgInfo.offset = newOffset;
                }
                break;

            case storage.pccSto:
                imgBuffer = imgFile.imgData;     // copy image data as-is
                if (imgBuffer.Length != imgInfo.uncSize)
                {
                    throw new FormatException("image sizes do not match, original is " + imgInfo.uncSize + ", new is " + imgBuffer.Length);
                }

                using (MemoryStream dataStream = new MemoryStream(imageData))
                {
                    dataStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                    dataStream.Write(imgBuffer, 0, imgBuffer.Length);
                }

                break;
            }

            imgList[imageIdx] = imgInfo;
        }
        private LongIntComboListPart(int capacity)
        {
            ZBlock.CleanZBlockFiles("unsorted", "sorted");

            b12buffer = new List<B12>(0);

            this.enums = new LongIntComboListPartEnumerator[32];

            // Pre-set with defaults.
            int numzblocks = 139;
            int zblockbufsize = 131072; // 128 KB default.

            if (null != DistributedObjectsSlave.xslave)
            {
                System.Xml.XmlNode xzblocks = DistributedObjectsSlave.xslave["zblocks"];
                if (null != xzblocks)
                {
                    {
                        System.Xml.XmlAttribute xnzb = xzblocks.Attributes["count"];
                        if (null != xnzb)
                        {
                            numzblocks = int.Parse(xnzb.Value);
                        }
                    }
                    {
                        System.Xml.XmlAttribute xzbs = xzblocks.Attributes["addbuffersize"];
                        if (null != xzbs)
                        {
                            zblockbufsize = DistributedObjectsSlave.ParseCapacity(xzbs.Value);
                        }
                    }
                }
            }

            if (XLog.logging)
            {
                XLog.log("Creating " + numzblocks.ToString() + " ZBlock`s");
            }

            zblocks = new ZBlock[numzblocks];
            for (int i = 0; i != numzblocks; i++)
            {
                zblocks[i] = new ZBlock(this, i, zblockbufsize);
            }
        }
Exemple #20
0
        public void ImportFromFile(int tfc)
        {
            OpenFileDialog Dialog = new OpenFileDialog();

            if (T2D.PixelFormat == "PF_DXT1\0" ||
                T2D.PixelFormat == "PF_DXT5\0")
            {
                Dialog.Filter = "DDS Files (*.dds)|*.dds";
            }
            if (T2D.PixelFormat == "PF_G8\0" ||
                T2D.PixelFormat == "PF_V8U8\0" ||
                T2D.PixelFormat == "PF_A8R8G8B8\0")
            {
                Dialog.Filter = "TGA Files (*.tga)|*.tga";
            }
            int format = -1;

            if (T2D.PixelFormat == "PF_DXT1\0")
            {
                format = 0;
            }
            if (T2D.PixelFormat == "PF_DXT5\0")
            {
                format = 1;
            }
            if (T2D.PixelFormat == "PF_V8U8\0")
            {
                format = 2;
            }
            if (T2D.PixelFormat == "PF_A8R8G8B8\0")
            {
                format = 3;
            }
            if (T2D.PixelFormat == "PF_G8\0")
            {
                format = 4;
            }
            if (!TextureTFCs[tfc].InCache)
            {
                if (Dialog.ShowDialog() == DialogResult.OK)
                {
                    if (format == 0 || format == 1)
                    {
                        ImageFile t = new ImageFile();
                        t.ImportFromFile(Dialog.FileName);
                        if (t.ImageSizeX == TextureTFCs[tfc].sizeX &&
                            t.ImageSizeY == TextureTFCs[tfc].sizeY &&
                            t.ImageFormat == format &&
                            t.memsize == TextureTFCs[tfc].size)
                        {
                            for (int i = 0; i < t.memsize; i++)
                            {
                                memory[TextureTFCs[tfc].offset + i] = t.memory[i];
                            }
                            MessageBox.Show("Done.");
                        }
                    }
                    if (format > 1 && format < 5)
                    {
                        ImageFile t = new ImageFile();
                        t.ImportFromFile(Dialog.FileName);
                        if (t.ImageSizeX == TextureTFCs[tfc].sizeX &&
                            t.ImageSizeY == TextureTFCs[tfc].sizeY)
                        {
                            if (t.ImageBits != 32)
                            {
                                MessageBox.Show("Please use 32 bit Targa image!");
                            }
                            else
                            {
                                switch (format)
                                {
                                case 2:
                                    for (int i = 0; i < t.memsize / 4; i++)
                                    {
                                        memory[TextureTFCs[tfc].offset + i * 2]     = t.memory[i * 4];
                                        memory[TextureTFCs[tfc].offset + i * 2 + 1] = t.memory[i * 4 + 2];
                                    }
                                    break;

                                case 3:
                                    for (int i = 0; i < t.memsize; i++)
                                    {
                                        memory[TextureTFCs[tfc].offset + i] = t.memory[i];
                                    }
                                    break;

                                case 4:
                                    for (int i = 0; i < t.memsize / 4; i++)
                                    {
                                        memory[TextureTFCs[tfc].offset + i] = t.memory[i * 4];
                                    }
                                    break;
                                }
                                MessageBox.Show("Done.");
                            }
                        }
                    }
                }
            }
            else
            if (Dialog.ShowDialog() == DialogResult.OK)
            {
                ImageFile t = new ImageFile();
                t.ImportFromFile(Dialog.FileName);
                if ((format == 0 || format == 1) && t.ImageFormat == format)
                {
                    if (t.ImageSizeX == TextureTFCs[tfc].sizeX &&
                        t.ImageSizeY == TextureTFCs[tfc].sizeY)
                    {
                        TFCFile TFCf = new TFCFile(T2D.Tsource);
                        byte[]  buff;
                        if (TFCf.isTFCCompressed())
                        {
                            buff = ZBlock.Compress(t.memory);
                        }
                        else
                        {
                            buff = t.memory;
                        }
                        byte[] buff2 = BitConverter.GetBytes(TFCf.getFileSize());
                        for (int i = 0; i < 4; i++)
                        {
                            memory[TextureTFCs[tfc].HeaderOffset + 20 + i] = buff2[i];
                        }
                        buff2 = BitConverter.GetBytes(buff.Length);
                        for (int i = 0; i < 4; i++)
                        {
                            memory[TextureTFCs[tfc].HeaderOffset + 16 + i] = buff2[i];
                        }
                        TFCf.AppendToTFC(buff);
                        int size = TFCf.getFileSize();
                        if (size != -1)
                        {
                            TOCeditor tc = new TOCeditor();
                            if (!tc.UpdateFile(T2D.Tsource + ".tfc", (uint)size))
                            {
                                MessageBox.Show("Didn't found Entry");
                            }
                            tc.Close();
                        }
                    }
                    else
                    {
                        System.Windows.Forms.DialogResult m = MessageBox.Show("The size doesn't match, import anyway?", "ME3 Explorer", MessageBoxButtons.YesNo);
                        if (m == DialogResult.Yes)
                        {
                            TFCFile TFCf = new TFCFile(T2D.Tsource);
                            byte[]  buff;
                            if (TFCf.isTFCCompressed())
                            {
                                buff = ZBlock.Compress(t.memory);
                            }
                            else
                            {
                                buff = t.memory;
                            }
                            byte[] buff2 = BitConverter.GetBytes(TFCf.getFileSize());
                            for (int i = 0; i < 4; i++)
                            {
                                memory[TextureTFCs[tfc].HeaderOffset + 20 + i] = buff2[i];
                            }
                            buff2 = BitConverter.GetBytes(buff.Length);
                            for (int i = 0; i < 4; i++)
                            {
                                memory[TextureTFCs[tfc].HeaderOffset + 16 + i] = buff2[i];
                            }
                            if (tfc == 0)
                            {
                                buff2 = BitConverter.GetBytes(t.ImageSizeX);
                                for (int i = 0; i < 4; i++)
                                {
                                    memory[T2D.offSizeX + i] = buff2[i];
                                }
                                buff2 = BitConverter.GetBytes(t.ImageSizeY);
                                for (int i = 0; i < 4; i++)
                                {
                                    memory[T2D.offSizeY + i] = buff2[i];
                                }
                            }
                            else
                            {
                                buff2 = BitConverter.GetBytes(t.ImageSizeX * 2);
                                for (int i = 0; i < 4; i++)
                                {
                                    memory[TextureTFCs[tfc].HeaderOffset + i] = buff2[i];
                                }
                                buff2 = BitConverter.GetBytes(t.ImageSizeY * 2);
                                for (int i = 0; i < 4; i++)
                                {
                                    memory[TextureTFCs[tfc].HeaderOffset + 4 + i] = buff2[i];
                                }
                                TFCf.AppendToTFC(buff);
                            }
                            TFCf.AppendToTFC(buff);
                            int size = TFCf.getFileSize();
                            if (size != -1)
                            {
                                TOCeditor tc = new TOCeditor();
                                if (!tc.UpdateFile(T2D.Tsource + ".tfc", (uint)size))
                                {
                                    MessageBox.Show("Didn't found Entry");
                                }
                                tc.Close();
                            }
                        }
                    }
                }
                if (format > 1 && format < 5)
                {
                    if (t.ImageSizeX == TextureTFCs[tfc].sizeX &&
                        t.ImageSizeY == TextureTFCs[tfc].sizeY)
                    {
                        if (t.ImageBits != 32)
                        {
                            MessageBox.Show("Please use 32 bit Targa image!");
                        }
                        else
                        {
                            byte[] buf = new byte[0];
                            switch (format)
                            {
                            case 2:
                                buf = new byte[t.memsize / 2];
                                for (int i = 0; i < t.memsize / 4; i++)
                                {
                                    buf[i * 2]     = t.memory[i * 4];
                                    buf[i * 2 + 1] = t.memory[i * 4 + 2];
                                }
                                break;

                            case 3:
                                buf = t.memory;
                                break;

                            case 4:
                                buf = new byte[t.memsize / 4];
                                for (int i = 0; i < t.memsize / 4; i++)
                                {
                                    buf[i] = t.memory[i * 4];
                                }
                                break;
                            }
                            TFCFile TFCf = new TFCFile(T2D.Tsource);
                            byte[]  buff;
                            if (TFCf.isTFCCompressed())
                            {
                                buff = ZBlock.Compress(t.memory);
                            }
                            else
                            {
                                buff = t.memory;
                            }
                            byte[] buff2 = BitConverter.GetBytes(TFCf.getFileSize());
                            for (int i = 0; i < 4; i++)
                            {
                                memory[TextureTFCs[tfc].HeaderOffset + 20 + i] = buff2[i];
                            }
                            buff2 = BitConverter.GetBytes(buff.Length);
                            for (int i = 0; i < 4; i++)
                            {
                                memory[TextureTFCs[tfc].HeaderOffset + 12 + i] = buff2[i];
                            }
                            TFCf.AppendToTFC(buff);
                            int size = TFCf.getFileSize();
                            if (size != -1)
                            {
                                TOCeditor tc = new TOCeditor();
                                if (!tc.UpdateFile(T2D.Tsource + ".tfc", (uint)size))
                                {
                                    MessageBox.Show("Didn't found Entry");
                                }
                                tc.Close();
                            }
                            MessageBox.Show("Done.");
                        }
                    }
                }
            }
        }
 int _kcmp(ZBlock.KeyBlockEntry x, ZBlock.KeyBlockEntry y)
 {
     for (int i = 0; i != this.keylen; i++)
     {
         int diff = (int)x.key[i] - (int)y.key[i];
         //Console.WriteLine("Comparing {0} with {1} = {2}", (int)kbuf1[k1 + i], (int)kbuf2[k2 + i], diff);
         if (0 != diff)
         {
             return diff;
         }
     }
     return 0;
 }
        private FixedArrayComboListPart(int keylength, int valuelength)
        {
            int count_capacity = 1024;
            int estimated_row_capacity = 32;

            ZBlock.CleanZBlockFiles("value", "key_unsorted", "key_sorted");

            this.keylen = keylength;
            this.valuelen = valuelength;

            if (keylength > 4)
            {
                _smallbuf = new byte[keylength];
            }
            else
            {
                _smallbuf = new byte[4];
            }

            net = new List<byte[]>(8);

            entries = new List<Entry>(1);
            kentries = new List<ZBlock.KeyBlockEntry>(1);

            ebytes = new byte[count_capacity * estimated_row_capacity];
            //evaluesbuf = // Moved down.
            net.Add(ebytes);

            this.streamwritebuf = new byte[1048576];

            // Pre-set with defaults.
            int numzblocks = 139;
            int zblockkeybufsize = FILE_BUFFER_SIZE;
            int zblockvaluebufsize = FILE_BUFFER_SIZE;

            if (null != DistributedObjectsSlave.xslave)
            {
                System.Xml.XmlNode xzblocks = DistributedObjectsSlave.xslave["zblocks"];
                if (null != xzblocks)
                {
                    {
                        System.Xml.XmlAttribute xnzb = xzblocks.Attributes["count"];
                        if (null != xnzb)
                        {
                            numzblocks = int.Parse(xnzb.Value);
                            /*{
                                string computer_name = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
                                if (computer_name == "MAPDCMILLER")
                                {
                                    numzblocks = 3;
                                }
                            }*/
                        }
                    }
                    {
                        System.Xml.XmlAttribute xzbs = xzblocks.Attributes["addbuffersize"];
                        if (null != xzbs)
                        {
                            int x = DistributedObjectsSlave.ParseCapacity(xzbs.Value);
                            zblockkeybufsize = x;
                            zblockvaluebufsize = x;
                        }
                    }
                    {
                        System.Xml.XmlAttribute xzbs = xzblocks.Attributes["addkeybuffersize"];
                        if (null != xzbs)
                        {
                            zblockkeybufsize = DistributedObjectsSlave.ParseCapacity(xzbs.Value);
                        }
                    }
                    {
                        System.Xml.XmlAttribute xzbs = xzblocks.Attributes["addvaluebuffersize"];
                        if (null != xzbs)
                        {
                            zblockvaluebufsize = DistributedObjectsSlave.ParseCapacity(xzbs.Value);
                        }
                    }
                }
            }

            evaluesbuf = new byte[(count_capacity * estimated_row_capacity) / numzblocks * 2];

            if (XLog.logging)
            {
                XLog.log("Creating " + numzblocks.ToString() + " ZBlock`s");
            }

            zblocks = new ZBlock[numzblocks];
            for (int i = 0; i != numzblocks; i++)
            {
                zblocks[i] = new ZBlock(this, i, zblockkeybufsize, zblockvaluebufsize);
            }
        }