Example #1
0
        public PCCObject(String path)
        {
            lzo = new SaltLZOHelper();
            fullname = path;
            BitConverter.IsLittleEndian = true;
            DebugOutput.PrintLn("Load file : " + path);
            pccFileName = Path.GetFullPath(path);
            MemoryTributary tempStream = new MemoryTributary();
            if (!File.Exists(pccFileName))
                throw new FileNotFoundException("PCC file not found");
            using (FileStream fs = new FileStream(pccFileName, FileMode.Open, FileAccess.Read))
            {
                FileInfo tempInfo = new FileInfo(pccFileName);
                tempStream.WriteFromStream(fs, tempInfo.Length);
                if (tempStream.Length != tempInfo.Length)
                {
                    throw new FileLoadException("File not fully read in. Try again later");
                }
            }

            tempStream.Seek(12, SeekOrigin.Begin);
            int tempNameSize = tempStream.ReadValueS32();
            tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin);
            int tempGenerator = tempStream.ReadValueS32();
            tempStream.Seek(36 + tempGenerator * 12, SeekOrigin.Current);
            int tempPos = (int)tempStream.Position;
            NumChunks = tempStream.ReadValueS32();
            tempStream.Seek(0, SeekOrigin.Begin);
            header = tempStream.ReadBytes(tempPos);
            tempStream.Seek(0, SeekOrigin.Begin);

            if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic)
            {
                DebugOutput.PrintLn("Magic number incorrect: " + magic);
                throw new FormatException("This is not a pcc file. The magic number is incorrect.");
            }

            if (bCompressed)
            {
                DebugOutput.PrintLn("File is compressed");
                {
                    listsStream = lzo.DecompressPCC(tempStream, this);

                    //Correct the header
                    bCompressed = false;
                    listsStream.Seek(0, SeekOrigin.Begin);
                    listsStream.WriteBytes(header);

                    //Set numblocks to zero
                    listsStream.WriteValueS32(0);
                    //Write the magic number
                    listsStream.WriteValueS32(1026281201);
                    //Write 8 bytes of 0
                    listsStream.WriteValueS32(0);
                    listsStream.WriteValueS32(0);
                }
            }
            else
            {
                DebugOutput.PrintLn("File already decompressed. Reading decompressed data.");
                listsStream = tempStream;
            }

            ReadNames(listsStream);
            ReadImports(listsStream);
            ReadExports(listsStream);
            LoadExports();
        }
Example #2
0
        public void CopyImgList(Texture2D inTex, PCCObject pcc)
        {
            numMipMaps = inTex.numMipMaps;

            if (properties.ContainsKey("NeverStream") && properties["NeverStream"].Value.IntValue == 1)
            {
                imageData = null;
                GC.Collect();
                // store images as pccSto format
                imgList = new List<ImageInfo>();
                MemoryStream tempData = new MemoryStream();

                for (int i = 0; i < inTex.imgList.Count; i++)
                {
                    ImageInfo newImg = new ImageInfo();
                    ImageInfo replaceImg = inTex.imgList[i];
                    newImg.storageType = storage.pccSto;
                    newImg.uncSize = replaceImg.uncSize;
                    newImg.cprSize = replaceImg.uncSize;
                    newImg.imgSize = replaceImg.imgSize;
                    newImg.offset = (int)(tempData.Position);
                    if (replaceImg.storageType == storage.arcCpr)
                    {
                        string archivePath = inTex.FullArcPath;
                        if (!File.Exists(archivePath))
                            throw new FileNotFoundException("Texture archive not found in " + archivePath);

                        using (FileStream archiveStream = File.OpenRead(archivePath))
                        {
                            archiveStream.Seek(replaceImg.offset, SeekOrigin.Begin);
                            SaltLZOHelper lzohelp = new SaltLZOHelper();
                            tempData.WriteBytes(lzohelp.DecompressTex(archiveStream, replaceImg.offset, replaceImg.uncSize, replaceImg.cprSize));
                        }
                    }
                    else if (replaceImg.storageType == storage.pccSto)
                    {
                        byte[] buffer = new byte[newImg.cprSize];
                        Buffer.BlockCopy(inTex.imageData, replaceImg.offset, buffer, 0, buffer.Length);
                        tempData.WriteBytes(buffer);
                    }
                    else
                        throw new NotImplementedException("Copying from non package stored texture no available");
                    imgList.Add(newImg);
                }

                for (int i = 0; i < imgList.Count; i++)
                {
                    ImageInfo tempinfo = imgList[i];
                    if (inTex.imgList[i].storageType == storage.empty)
                        tempinfo.storageType = storage.empty;
                    imgList[i] = tempinfo;
                }

                imageData = tempData.ToArray();
                tempData.Close();
                tempData = null;
                GC.Collect();
            }
            else
            {
                imageData = inTex.imageData;
                imgList = inTex.imgList;
            }

            // add properties "TextureFileCacheName" and "TFCFileGuid" if they are missing,
            if (!properties.ContainsKey("TextureFileCacheName") && inTex.properties.ContainsKey("TextureFileCacheName"))
            {
                SaltPropertyReader.Property none = properties["None"];
                properties.Remove("None");

                SaltPropertyReader.Property property = new SaltPropertyReader.Property();
                property.TypeVal = SaltPropertyReader.Type.NameProperty;
                property.Name = "TextureFileCacheName";
                property.Size = 8;
                SaltPropertyReader.PropertyValue value = new SaltPropertyReader.PropertyValue();
                value.StringValue = "Textures";
                property.Value = value;
                properties.Add("TextureFileCacheName", property);
                arcName = value.StringValue;

                if (!properties.ContainsKey("TFCFileGuid"))
                {
                    SaltPropertyReader.Property guidprop = new SaltPropertyReader.Property();
                    guidprop.TypeVal = SaltPropertyReader.Type.StructProperty;
                    guidprop.Name = "TFCFileGuid";
                    guidprop.Size = 16;
                    SaltPropertyReader.PropertyValue guid = new SaltPropertyReader.PropertyValue();
                    guid.len = guidprop.Size;
                    guid.StringValue = "Guid";
                    guid.IntValue = pcc.AddName(guid.StringValue);
                    guid.Array = new List<SaltPropertyReader.PropertyValue>();
                    for (int i = 0; i < 4; i++)
                        guid.Array.Add(new SaltPropertyReader.PropertyValue());
                    guidprop.Value = guid;
                    properties.Add("TFCFileGuid", guidprop);
                }

                properties.Add("None", none);
            }

            // copy specific properties from inTex
            for (int i = 0; i < inTex.properties.Count; i++)
            {
                SaltPropertyReader.Property prop = inTex.properties.ElementAt(i).Value;
                switch (prop.Name)
                {
                    case "TextureFileCacheName":
                        arcName = prop.Value.StringValue;
                        properties["TextureFileCacheName"].Value.StringValue = arcName;
                        break;
                    case "TFCFileGuid":
                        SaltPropertyReader.Property GUIDProp = properties["TFCFileGuid"];
                        for (int l = 0; l < 4; l++)
                        {
                            SaltPropertyReader.PropertyValue tempVal = GUIDProp.Value.Array[l];
                            tempVal.IntValue = prop.Value.Array[l].IntValue;
                            GUIDProp.Value.Array[l] = tempVal;
                        }
                        break;
                    case "MipTailBaseIdx":
                        properties["MipTailBaseIdx"].Value.IntValue = prop.Value.IntValue;
                        break;
                    case "SizeX":
                        properties["SizeX"].Value.IntValue = prop.Value.IntValue;
                        break;
                    case "SizeY":
                        properties["SizeY"].Value.IntValue = prop.Value.IntValue;
                        break;
                }
            }
        }
Example #3
0
        public void DumpImageData(ImageInfo imgInfo, string archiveDir = null, string fileName = null)
        {
            if (fileName == null)
            {
                fileName = texName + "_" + imgInfo.imgSize + ".bin";
            }

            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 = FullArcPath;
                    if (String.IsNullOrEmpty(archivePath))
                        GetTexArchive(archiveDir);
                    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)
                        {
                            SaltLZOHelper lzohelp = new SaltLZOHelper();
                            imgBuffer = lzohelp.DecompressTex(archiveStream, imgInfo.offset, imgInfo.uncSize, imgInfo.cprSize);
                        }
                        else
                        {
                            archiveStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                            imgBuffer = new byte[imgInfo.uncSize];
                            archiveStream.Read(imgBuffer, 0, imgBuffer.Length);
                        }
                    }
                    break;
                default:
                    throw new FormatException("Unsupported texture storage type");
            }
            using (FileStream outputImg = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                outputImg.Write(imgBuffer, 0, imgBuffer.Length);
        }
Example #4
0
        public byte[] DumpImage(ImageSize imgSize, string archiveDir)
        {
            byte[] imgBuff = null;

            ImageInfo imgInfo;
            if (imgList.Exists(img => img.imgSize == imgSize))
                imgInfo = imgList.Find(img => img.imgSize == imgSize);
            else
                throw new FileNotFoundException("Image with resolution " + imgSize + " not found");

            switch (imgInfo.storageType)
            {
                case storage.pccSto:
                    imgBuff = new byte[imgInfo.uncSize];
                    Buffer.BlockCopy(imageData, imgInfo.offset, imgBuff, 0, imgInfo.uncSize);
                    break;
                case storage.arcCpr:
                case storage.arcUnc:
                    string archivePath = FullArcPath;
                    if (String.IsNullOrEmpty(archivePath))
                        archivePath = GetTexArchive(archiveDir);
                    if (!File.Exists(archivePath))
                        throw new FileNotFoundException("Texture archive not found in " + archivePath);

                    using (FileStream archiveStream = File.OpenRead(archivePath))
                    {
                        if (imgInfo.storageType == storage.arcCpr)
                        {
                            SaltLZOHelper lzohelp = new SaltLZOHelper();
                            imgBuff = lzohelp.DecompressTex(archiveStream, imgInfo.offset, imgInfo.uncSize, imgInfo.cprSize);
                        }
                        else
                        {
                            archiveStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                            imgBuff = new byte[imgInfo.uncSize];
                            archiveStream.Read(imgBuff, 0, imgBuff.Length);
                        }
                    }
                    break;
                default:
                    throw new FormatException("Unsupported texture storage type");
            }
            return imgBuff;
        }
Example #5
0
        public void replaceImage2(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 ".DDS": imgFile = new DDS(fileToReplace, null); break;
                default: throw new FormatException(fileFormat + " image extension not supported");
            }

            if (texFormat == "PF_NormalMap_HQ")
            {
                if (imgFile.format != "ATI2")
                    throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype());
            }
            else if (String.Compare(texFormat, "PF_" + imgFile.format, true) != 0 &&
                String.Compare(texFormat, imgFile.format, true) != 0)
            {
                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 = FullArcPath;
                    if (String.IsNullOrEmpty(archivePath))
                        archivePath = GetTexArchive(archiveDir);
                    if (!File.Exists(archivePath))
                        throw new FileNotFoundException("Texture archive not found in " + archivePath);

                    imgBuffer = imgFile.imgData;

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

                    if (arcName.Length <= CustCache.Length || arcName.Substring(0, CustCache.Length) != CustCache) // Check whether existing texture is in a custom cache
                    {
                        ChooseNewCache(archiveDir, imgBuffer.Length);
                        archivePath = FullArcPath;
                    }
                    else
                    {
                        FileInfo arc = new FileInfo(archivePath);
                        if (arc.Length + imgBuffer.Length >= 0x80000000)
                        {
                            ChooseNewCache(archiveDir, imgBuffer.Length);
                            archivePath = FullArcPath;
                        }
                    }

                    using (FileStream archiveStream = new FileStream(archivePath, FileMode.Append, FileAccess.Write))
                    {
                        int newOffset = (int)archiveStream.Position;
                        if (imgInfo.storageType == storage.arcCpr)
                        {
                            byte[] tempBuff;
                            SaltLZOHelper lzohelper = new SaltLZOHelper();
                            tempBuff = lzohelper.CompressTex(imgBuffer);
                            imgBuffer = new byte[tempBuff.Length];
                            Buffer.BlockCopy(tempBuff, 0, imgBuffer, 0, tempBuff.Length);
                            imgInfo.cprSize = imgBuffer.Length;
                        }
                        archiveStream.Write(imgBuffer, 0, imgBuffer.Length);

                        imgInfo.offset = newOffset;
                    }
                    break;
                case storage.pccSto:
                    imgBuffer = imgFile.resize();
                    using (MemoryStream dataStream = new MemoryStream())
                    {
                        dataStream.WriteBytes(imageData);
                        if (imgBuffer.Length <= imgInfo.uncSize && imgInfo.offset > 0)
                            dataStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                        else
                            imgInfo.offset = (int)dataStream.Position;
                        dataStream.WriteBytes(imgBuffer);
                        imgInfo.cprSize = imgBuffer.Length;
                        imgInfo.uncSize = imgBuffer.Length;
                        imageData = dataStream.ToArray();
                    }
                    break;
            }

            imgList[imageIdx] = imgInfo;
        }