Inheritance: ImageFile
Beispiel #1
0
        public void HardReplaceImage(string strImgSize, string fileToReplace)
        {
            if (!File.Exists(fileToReplace))
                throw new FileNotFoundException("Required file was not found");

            ImageFile dds = new DDS(fileToReplace, null);

            if (strImgSize == null)
                strImgSize = dds.imgSize.ToString();

            if (imgList.Count != 1)
                throw new Exception("Cannot use this function for a multi-level texture");

            ImageSize imgSize = ImageSize.stringToSize(strImgSize);
            // Check for correct dimensions/ size
            if (imgSize.width == imgList[0].imgSize.width)
            {
                if (imgSize.height != imgList[0].imgSize.height)
                    throw new FormatException("The input size is not the correct dimensions (Error: 0)");
            }
            else if (imgSize.width < imgList[0].imgSize.width)
            {
                if (imgList[0].imgSize.width / imgSize.width != imgList[0].imgSize.height / imgSize.height || (imgList[0].imgSize.width / imgSize.width) % 2 != 0)
                    throw new FormatException("The input size is not the correct size (Error: 1)");
            }
            else
            {
                if (imgSize.width / imgList[0].imgSize.width != imgSize.height / imgList[0].imgSize.height || (imgSize.width / imgList[0].imgSize.width) % 2 != 0)
                    throw new FormatException("The input size is not the correct size (Error: 2)");
            }

            if (dds.format == "R8G8B8")
            {
                byte[] buff = ImageMipMapHandler.ConvertTo32bit(dds.imgData, (int)dds.imgSize.width, (int)dds.imgSize.height);
                dds = new DDS(null, dds.imgSize, "A8R8G8B8", buff);
            }

            if (Class == class2 || Class == class3)
                ChangeFormat(dds.format);

            if (texFormat == "PF_NormalMap_HQ")
            {
                if (dds.format != "ATI2")
                    throw new FormatException("Input texture is the wrong format");
            }
            else if (String.Compare(texFormat, "PF_" + dds.format, true) != 0 && String.Compare(texFormat, dds.format, true) != 0)
                throw new FormatException("Input texture is the wrong format");

            ImageInfo newImg = new ImageInfo();
            newImg.storageType = imgList[0].storageType;
            if (newImg.storageType == storage.empty || newImg.storageType == storage.arcCpr || newImg.storageType == storage.arcUnc)
                throw new FormatException("Original texture cannot be empty or externally stored");

            newImg.offset = 0;
            newImg.imgSize = imgSize;

            switch (newImg.storageType)
            {
                case storage.pccSto:
                    imageData = dds.resize();
                    newImg.cprSize = imageData.Length;
                    newImg.uncSize = imageData.Length;
                    break;
                case storage.pccCpr:
                    SaltLZOHelper lzohelper = new SaltLZOHelper();
                    imageData = lzohelper.CompressTex(dds.resize());
                    newImg.cprSize = imageData.Length;
                    newImg.uncSize = dds.resize().Length;
                    break;
            }

            imgList.RemoveAt(0);
            imgList.Add(newImg);

            // Fix up properties
            properties["SizeX"].Value.IntValue = (int)imgSize.width;
            properties["SizeY"].Value.IntValue = (int)imgSize.height;
        }
Beispiel #2
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);
        }
Beispiel #3
0
        public void replaceImage(string strImgSize, string fileToReplace)
        {
            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;
                case ".tga": imgFile = new TGA(fileToReplace, null); break;
                case ".TGA": imgFile = new TGA(fileToReplace, null); break;
                default: throw new FormatException(fileFormat + " image extension not supported");
            }

            if (imgFile.imgSize.height != imgInfo.imgSize.height || imgFile.imgSize.width != imgInfo.imgSize.width)
                throw new FormatException("Incorrect input texture dimensions. Expected: " + imgInfo.imgSize.ToString());

            // check if images have same format type
            if (texFormat != imgFile.format && texFormat != ("PF_" + imgFile.format) && imgFile.format != "ATI2")
            {
                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:
                    throw new NotImplementedException("Texture replacement not supported in external packages yet");
                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;
                case storage.pccCpr:
                    using (MemoryStream dataStream = new MemoryStream())
                    {
                        dataStream.WriteBytes(imageData);
                        SaltLZOHelper lzohelper = new SaltLZOHelper();
                        imgBuffer = lzohelper.CompressTex(imgFile.resize());
                        if (imgBuffer.Length <= imgInfo.cprSize && imgInfo.offset > 0)
                            dataStream.Seek(imgInfo.offset, SeekOrigin.Begin);
                        else
                            imgInfo.offset = (int)dataStream.Position;
                        dataStream.WriteBytes(imgBuffer);
                        imgInfo.cprSize = imgBuffer.Length;
                        imgInfo.uncSize = imgFile.resize().Length;
                        imageData = dataStream.ToArray();
                    }
                    break;
            }

            imgList[imageIdx] = imgInfo;
        }
Beispiel #4
0
        public void addMissingImage(String strImgSize, string fileToReplace)
        {
            if (imgList.Count == 1)
                throw new Exception("The imglist must contain more than 1 texture");

            ImageSize imgSize = ImageSize.stringToSize(strImgSize);
            if (imgList.Exists(img => img.imgSize.width == imgSize.width && img.imgSize.height == imgSize.height))
                throw new Exception("The img already exists in the list");
            ImageInfo tempImg = imgList.Last();

            if (!File.Exists(fileToReplace))
                throw new FileNotFoundException("Required file was not found");

            ImageFile dds = new DDS(fileToReplace, null);

            if (dds.imgSize.width != imgSize.width || dds.imgSize.height != imgSize.height)
                throw new FormatException("Input texture is not required size");

            if (dds.format == "R8G8B8")
            {
                byte[] buff = ImageMipMapHandler.ConvertTo32bit(dds.imgData, (int)dds.imgSize.width, (int)dds.imgSize.height);
                dds = new DDS(null, dds.imgSize, "A8R8G8B8", buff);
            }

            if (texFormat == "PF_NormalMap_HQ")
            {
                if (dds.format != "ATI2")
                    throw new FormatException("Input texture is the wrong format");
            }
            else if (String.Compare(texFormat, "PF_" + dds.format, true) != 0 && String.Compare(texFormat, dds.format, true) != 0)
                throw new FormatException("Input texture is the wrong format");

            ImageInfo newImg = new ImageInfo();
            
            if (tempImg.storageType == storage.empty || tempImg.storageType == storage.arcCpr || tempImg.storageType == storage.arcUnc)
                throw new FormatException("Existing textures cannot be empty or externally stored");
            newImg.storageType = tempImg.storageType;
            newImg.imgSize = imgSize;

            using (MemoryStream ms = new MemoryStream())
            {
                ms.WriteBytes(imageData);
                newImg.offset = (int)ms.Position;
                switch (newImg.storageType)
                {
                    case storage.pccSto:
                        ms.WriteBytes(dds.resize());
                        //newImg.cprSize = dds.imgData.Length;
                        //newImg.uncSize = dds.imgData.Length;
                        newImg.cprSize = dds.resize().Length;
                        newImg.uncSize = dds.resize().Length;
                        break;
                    case storage.pccCpr:
                        SaltLZOHelper lzohelper = new SaltLZOHelper();
                        //byte[] buff = lzohelper.CompressTex(dds.imgData);
                        byte[] buff = lzohelper.CompressTex(dds.resize());
                        ms.WriteBytes(buff);
                        //newImg.uncSize = dds.imgData.Length;
                        newImg.uncSize = dds.resize().Length;
                        newImg.cprSize = buff.Length;
                        break;
                }
                imageData = ms.ToArray();
            }

            int i = 0;
            for (; i < imgList.Count; i++)
            {
                if (imgList[i].imgSize.width > imgSize.width)
                    continue;

                imgList.Insert(i, newImg);
                return;
            }
            imgList.Insert(i, newImg);

            if (ImageMipMapHandler.CprFormat(dds.format) && (newImg.imgSize.width < 4 || newImg.imgSize.height < 4))
            {
                newImg = imgList[i];
                if (newImg.imgSize.width < 4 && newImg.imgSize.height > 4)
                {
                    newImg.imgSize = new ImageSize(4, newImg.imgSize.height);
                }
                else if (newImg.imgSize.width > 4 && newImg.imgSize.height < 4)
                {
                    newImg.imgSize = new ImageSize(newImg.imgSize.width, 4);
                }
                else if (newImg.imgSize.width < 4 && newImg.imgSize.height < 4)
                {
                    newImg.imgSize = new ImageSize(4, 4);
                }
                else
                    throw new Exception("safety catch");
                imgList[i] = newImg;
            }
            //throw new Exception("Newimg wasn't inserted in list!");
        }
Beispiel #5
0
        public bool InstallTexture(string texname, List<string> pccs, List<int> IDs, byte[] imgdata)
        {
            if (pccs.Count == 0)
            {
                DebugOutput.PrintLn("No PCC's found for " + texname + ", skipping.");
                return false;
            }
            string fulpath = pccs[0];
            //string temppath = (WhichGame == 1) ? Path.GetDirectoryName(pathBIOGame) : pathBIOGame;
            // Heff: Again, is the removal of the last dir for ME1 intended, and if so for what purpose?
            string temppath = pathBIOGame;
            if (!fulpath.Contains(temppath))
                fulpath = Path.Combine(temppath, fulpath);


            // KFreon: Skip files that don't exist
            if (!File.Exists(fulpath))
                return false;

            using (PCCObjects.IPCCObject pcc = PCCObjects.Creation.CreatePCCObject(fulpath, WhichGame))
            {
                if ((pcc.Exports[IDs[0]].ClassName != "Texture2D" && pcc.Exports[IDs[0]].ClassName != "LightMapTexture2D" && pcc.Exports[IDs[0]].ClassName != "TextureFlipBook") || String.Compare(pcc.Exports[IDs[0]].ObjectName, texname, true) != 0)
                    throw new InvalidDataException("Export is not correct class or name!");

                //Load the texture from the pcc
                using (Textures.ITexture2D tex2D = pcc.CreateTexture2D(IDs[0], pathBIOGame))
                {
                    
                    tex2D.allPccs = pccs;
                    tex2D.expIDs = IDs;
                    int noImg = tex2D.imgList.Count;

                    DebugOutput.PrintLn("Now replacing textures in texture: " + tex2D.texName, true);
                    Debug.WriteLine("Now replacing textures in texture: " + tex2D.texName + "  ID: " + IDs[0]);
                    WriteDebug("Now replacing textures in texture: " + tex2D.texName + "  ID: " + IDs[0]);

                    ImageFile im = null;
                    try
                    {
                        im = new DDS("", imgdata);
                    }
                    catch
                    {
                        Console.WriteLine("Error: Unable to detect input DDS format, skipping.");
                        return false;
                    }



                    // KFreon: TESTING
                    Debug.WriteLine("First pcc: " + fulpath + "    ArcName: " + tex2D.arcName);
                    WriteDebug("First pcc: " + fulpath + "    ArcName: " + tex2D.arcName);



                    //The texture is a single image, therefore use replace function
                    if (noImg == 1)
                    {
                        string imgSize = tex2D.imgList[0].imgSize.width.ToString() + "x" + tex2D.imgList[0].imgSize.height.ToString();
                        try
                        {
                            tex2D.replaceImage(imgSize, im, pathBIOGame);
                        }
                        catch
                        {
                            // KFreon:  If replace fails, it's single image thus use the singleimageupscale function
                            tex2D.singleImageUpscale(im, pathBIOGame);
                        }
                    }

                    //If the texture has multiple images, then check the input texture for MIPMAPS
                    else
                    {
                        bool hasMips = true;
                        ImageFile imgFile = im;
                        /*try { ImageMipMapHandler imgMipMap = new ImageMipMapHandler("", imgdata); }
                        catch (Exception e)
                        {
                            hasMips = false;
                        }*/
                        using (ImageEngineImage img = new ImageEngineImage(imgdata))
                            hasMips = img.NumMipMaps > 1;


                        if (!hasMips)
                        {
                            string imgSize = imgFile.imgSize.width.ToString() + "x" + imgFile.imgSize.height.ToString();
                            try
                            {
                                //Try replacing the image. If it doesn't exist then it'll throw and error and you'll need to upscale the image
                                tex2D.replaceImage(imgSize, imgFile, pathBIOGame);
                            }
                            catch (Exception e)
                            {
                                tex2D.addBiggerImage(imgFile, pathBIOGame);
                            }
                        }
                        else
                        {
                            try
                            {
                                tex2D.OneImageToRuleThemAll(imgFile, pathBIOGame, imgdata);
                            }
                            catch (Exception e)
                            {
                                if (e.Message.Contains("Format"))
                                {
                                    MessageBox.Show(texname + " is in the wrong format." + Environment.NewLine + Environment.NewLine + e.Message);
                                    return false;
                                }
                            }
                        }
                    }

                    Debug.WriteLine("After replace: " + tex2D.arcName);
                    WriteDebug("After replace: " + tex2D.arcName);


                    DebugOutput.PrintLn("Replacement complete. Now saving pcc: " + pcc.pccFileName, true);

                    PCCObjects.IExportEntry expEntry = pcc.Exports[IDs[0]];
                    expEntry.SetData(tex2D.ToArray(expEntry.DataOffset, pcc));
                    expEntry.hasChanged = true;
                    pcc.Exports[IDs[0]] = expEntry;

                    pcc.saveToFile(pcc.pccFileName);

                    int modCount = tex2D.allPccs.Count;

                    // KFreon: Elapsed time stuff
                    int start = Environment.TickCount;

                    if (modCount > 1)
                        for (int item = 1; item < modCount; item++)
                        {
                            Debug.WriteLine(pccs[item] + "   " + IDs[item]);
                            WriteDebug(pccs[item] + "   " + IDs[item]);
                            if (!SaveFile(pccs, IDs, tex2D, item))
                                break;
                        }
                    Debug.WriteLine("");
                    WriteDebug("");

                    // KFreon: More timer stuff
                    TimeSpan ts = TimeSpan.FromMilliseconds(Environment.TickCount - start);
                    Console.WriteLine(ts.Duration().ToString());
                    DebugOutput.Print("All PCC updates finished. ");
                    return true;
                }
            }
        }
Beispiel #6
0
        public void extractImage(ImageInfo imgInfo, string archiveDir = null, string fileName = null)
        {
            ImageFile imgFile;
            if (fileName == null)
                fileName = texName + "_" + imgInfo.imgSize + getFileFormat();

            byte[] imgBuffer = null;

            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 = FindFile();
                    if (String.IsNullOrEmpty(archivePath))
                        throw new FileNotFoundException();
                    PCCObject temp = new PCCObject(archivePath);
                    for (int i = 0; i < temp.ExportCount; i++)
                    {
                        if (String.Compare(texName, temp.Exports[i].ObjectName, true) == 0 && temp.Exports[i].ClassName == "Texture2D")
                        {
                            Texture2D temptex = new Texture2D(temp, i);
                            temptex.extractImage(imgInfo.imgSize.ToString(), temp, null, fileName);
                        }
                    }
                    break;
                case storage.pccCpr:
                    using (MemoryStream ms = new MemoryStream(imageData))
                    {
                        SaltLZOHelper lzohelp = new SaltLZOHelper();
                        imgBuffer = lzohelp.DecompressTex(ms, imgInfo.offset, imgInfo.uncSize, imgInfo.cprSize);
                    }
                    break;
                default:
                    throw new FormatException("Unsupported texture storage type");
            }

            if (imgInfo.storageType == storage.pccSto || imgInfo.storageType == storage.pccCpr)
            {
                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);
            }
        }
        public ImageMipMapHandler(string imageWithMipMaps, byte[] data)
        {
            imageWithMipMaps = (imageWithMipMaps == "") ? ".dds" : imageWithMipMaps;
            imageList        = new List <ImageFile>();
            string    fileFormat = Path.GetExtension(imageWithMipMaps).ToLowerInvariant();
            string    fileName   = Path.GetFileNameWithoutExtension(imageWithMipMaps);
            ImageFile imageMipMap;
            int       headerSize;

            if (data != null)
            {
                headerSize  = 128;
                imageMipMap = new DDS("", data);
            }
            else
            {
                switch (fileFormat)
                {
                case ".dds":
                    headerSize  = 128;
                    imageMipMap = new DDS(imageWithMipMaps, null);
                    break;

                case ".tga":
                    headerSize  = 18;
                    imageMipMap = new TGA(imageWithMipMaps, null);
                    break;

                default: throw new FormatException("Invalid image format");
                }
            }

            //Console.WriteLine("Image Format: {0}", imageMipMap.format);

            //check if image has mipmaps

            /* using (FileStream imageStream = File.OpenRead(imageWithMipMaps))
             * {
             *  long size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP);
             *  if (imageStream.Length - headerSize != ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP))
             *  {
             *      //MessageBox.Show("bytes in file: " + (imageStream.Length - headerSize) + ", bytes calulated: " + ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP) + ", BPP: " + imageMipMap.BPP + ", format: " + imageMipMap.format);
             *      //Console.WriteLine("bytes in file: {0}, bytes calulated: {1}, BPP: {2}", imageStream.Length - headerSize, ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP), imageMipMap.BPP);
             *      throw new FormatException("The image doesn't have any mipmaps");
             *  }
             * } */



            // KFreon: This can be wrong too much. Single mip images etc.

            /*
             * var size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP);
             * if (imageMipMap.imgData.Length != size)
             *  throw new FormatException("The image doesn't have any mipmaps");*/

            byte[] buffer = null;

            // add the first tga image
            if (fileFormat == ".tga")
            {
                //buffer = new byte[imageMipMap.imgData.Length];
                buffer = imageMipMap.imgData;
                //imageList.Add(imageMipMap);
            }

            // Heff: Use Max to support 1x1 mips for 1:2 ratio images.
            int maxCount   = (int)Math.Max(imageMipMap.imgSize.width, imageMipMap.imgSize.height);
            int count      = 1;
            int imgDataPos = 0;

            while (count <= maxCount)
            {
                ImageFile newImageFile;
                ImageSize newImageSize = imageMipMap.imgSize / count;
                //if (newImageSize.width < 4 || newImageSize.height < 4)
                //    break;
                int imgDataSize = (int)ImageDataSize(newImageSize, imageMipMap.format, imageMipMap.BPP);

                if (fileFormat == ".dds")
                {
                    buffer = new byte[imgDataSize];
                    Buffer.BlockCopy(imageMipMap.imgData, imgDataPos, buffer, 0, imgDataSize);
                    imgDataPos += imgDataSize;

                    if (imageMipMap.format == "R8G8B8") // Automatic conversion to 32-bit
                    {
                        buffer       = ConvertTo32bit(buffer, (int)newImageSize.width, (int)newImageSize.height);
                        newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, "A8R8G8B8", buffer);
                    }
                    else
                    {
                        newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer);
                    }
                }
                else if (fileFormat == ".tga")
                {
                    newImageFile = new TGA(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer);
                    if (newImageSize != new ImageSize(1, 1))
                    {
                        buffer = ShrinkImage(buffer, newImageSize, imageMipMap.BPP);
                    }
                }
                else
                {
                    throw new FormatException("Invalid image format");
                }

                imageList.Add(newImageFile);

                count *= 2;
            }
        }
        public ImageMipMapHandler(string imageWithMipMaps, byte[] data)
        {
            imageWithMipMaps = (imageWithMipMaps == "") ? ".dds" : imageWithMipMaps;
            imageList = new List<ImageFile>();
            string fileFormat = Path.GetExtension(imageWithMipMaps).ToLowerInvariant();
            string fileName = Path.GetFileNameWithoutExtension(imageWithMipMaps);
            ImageFile imageMipMap;
            int headerSize;

            if (data != null)
            {
                headerSize = 128;
                imageMipMap = new DDS("", data);
            }
            else
            {
                switch (fileFormat)
                {
                    case ".dds":
                        headerSize = 128;
                        imageMipMap = new DDS(imageWithMipMaps, null);
                        break;
                    case ".tga":
                        headerSize = 18;
                        imageMipMap = new TGA(imageWithMipMaps, null);
                        break;
                    default: throw new FormatException("Invalid image format");
                }
            }

            //Console.WriteLine("Image Format: {0}", imageMipMap.format);

            //check if image has mipmaps
            /* using (FileStream imageStream = File.OpenRead(imageWithMipMaps))
            {
                long size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP);
                if (imageStream.Length - headerSize != ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP))
                {
                    //MessageBox.Show("bytes in file: " + (imageStream.Length - headerSize) + ", bytes calulated: " + ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP) + ", BPP: " + imageMipMap.BPP + ", format: " + imageMipMap.format);
                    //Console.WriteLine("bytes in file: {0}, bytes calulated: {1}, BPP: {2}", imageStream.Length - headerSize, ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP), imageMipMap.BPP);
                    throw new FormatException("The image doesn't have any mipmaps");
                }
            } */
            var size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP);
            if (imageMipMap.imgData.Length != size)
                throw new FormatException("The image doesn't have any mipmaps");

            byte[] buffer = null;

            // add the first tga image
            if (fileFormat == ".tga")
            {
                //buffer = new byte[imageMipMap.imgData.Length];
                buffer = imageMipMap.imgData;
                //imageList.Add(imageMipMap);
            }

            // Heff: Use Max to support 1x1 mips for 1:2 ratio images.
            int maxCount = (int)Math.Max(imageMipMap.imgSize.width, imageMipMap.imgSize.height);
            int count = 1;
            int imgDataPos = 0;
            while (count <= maxCount)
            {
                ImageFile newImageFile;
                ImageSize newImageSize = imageMipMap.imgSize / count;
                //if (newImageSize.width < 4 || newImageSize.height < 4)
                //    break;
                int imgDataSize = (int)ImageDataSize(newImageSize, imageMipMap.format, imageMipMap.BPP);

                if (fileFormat == ".dds")
                {
                    buffer = new byte[imgDataSize];
                    Buffer.BlockCopy(imageMipMap.imgData, imgDataPos, buffer, 0, imgDataSize);
                    imgDataPos += imgDataSize;

                    if (imageMipMap.format == "R8G8B8") // Automatic conversion to 32-bit
                    {
                        buffer = ConvertTo32bit(buffer, (int)newImageSize.width, (int)newImageSize.height);
                        newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, "A8R8G8B8", buffer);
                    }
                    else
                        newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer);
                }
                else if (fileFormat == ".tga")
                {
                    newImageFile = new TGA(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer);
                    if (newImageSize != new ImageSize(1, 1))
                        buffer = ShrinkImage(buffer, newImageSize, imageMipMap.BPP);
                }
                else
                    throw new FormatException("Invalid image format");

                imageList.Add(newImageFile);

                count *= 2;
            }
        }
Beispiel #9
0
        /// <summary>
        /// Load an image into one of AK86's classes.
        /// </summary>
        /// <param name="im">AK86 image already, just return it unless null. Then load from fileToLoad.</param>
        /// <param name="fileToLoad">Path to file to be loaded. Irrelevent if im is provided.</param>
        /// <returns>AK86 Image file.</returns>
        public static ImageFile LoadAKImageFile(ImageFile im, string fileToLoad)
        {
            ImageFile imgFile = null;
            if (im != null)
                imgFile = im;
            else
            {
                if (!File.Exists(fileToLoad))
                    throw new FileNotFoundException("invalid file to replace: " + fileToLoad);

                // check if replacing image is supported
                string fileFormat = Path.GetExtension(fileToLoad);
                switch (fileFormat)
                {
                    case ".dds": imgFile = new DDS(fileToLoad, null); break;
                    case ".tga": imgFile = new TGA(fileToLoad, null); break;
                    default: throw new FileNotFoundException(fileFormat + " image extension not supported");
                }
            }
            return imgFile;
        }
Beispiel #10
0
        public void addBiggerImage(ImageFile im)
        {
            ImageSize biggerImageSizeOnList = privateimgList.Max(image => image.imgSize);
            // check if replacing image is supported
            ImageFile imgFile = im;

            if (imgFile.format == "R8G8B8")
            {
                byte[] buff = ImageMipMapHandler.ConvertTo32bit(imgFile.imgData, (int)imgFile.imgSize.width, (int)imgFile.imgSize.height);
                imgFile = new DDS(null, imgFile.imgSize, "A8R8G8B8", buff);
            }

            if (!Methods.CheckTextureFormat(texFormat, imgFile.format))
                throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype());

            // check if image to add is valid
            if (biggerImageSizeOnList.width * 2 != imgFile.imgSize.width || biggerImageSizeOnList.height * 2 != imgFile.imgSize.height)
                throw new FormatException("image size " + imgFile.imgSize + " isn't valid, must be " + new ImageSize(biggerImageSizeOnList.width * 2, biggerImageSizeOnList.height * 2));

            // this check avoids insertion inside textures that have only 1 image stored inside pcc
            //if (!imgList.Exists(img => img.storageType != storage.empty && img.storageType != storage.pccSto))
            //    throw new Exception("Unable to add image, texture must have a reference to an external archive");
            if (privateimgList.Count <= 1)
                throw new Exception("Unable to add image, texture must have more than one image present");

            // !!! warning, this method breaks consistency between imgList and imageData[] !!!
            ImageInfo newImgInfo = new ImageInfo();
            newImgInfo.storageType = privateimgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType;
            newImgInfo.imgSize = imgFile.imgSize;
            newImgInfo.uncSize = imgFile.resize().Length;
            newImgInfo.cprSize = 0x00; // not yet filled
            newImgInfo.offset = 0x00; // not yet filled
            privateimgList.Insert(0, newImgInfo); // insert new image on top of the list
            //now I let believe the program that I'm doing an image replace, saving lot of code ;)
            replaceImage(newImgInfo.imgSize.ToString(), im);

            //updating num of images
            numMipMaps++;

            // update MipTailBaseIdx
            //SaltPropertyReader.Property MipTail = properties["MipTailBaseIdx"];
            int propVal = properties["MipTailBaseIdx"].Value.IntValue;
            propVal++;
            properties["MipTailBaseIdx"].Value.IntValue = propVal;
            //MessageBox.Show("raw size: " + properties["MipTailBaseIdx"].raw.Length + "\nproperty offset: " + properties["MipTailBaseIdx"].offsetval);
            using (MemoryStream rawStream = new MemoryStream(properties["MipTailBaseIdx"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["MipTailBaseIdx"].raw = rawStream.ToArray();
            }
            //properties["MipTailBaseIdx"] = MipTail;

            // update Sizes
            //SaltPropertyReader.Property Size = properties["SizeX"];
            propVal = (int)newImgInfo.imgSize.width;
            properties["SizeX"].Value.IntValue = propVal;
            using (MemoryStream rawStream = new MemoryStream(properties["SizeX"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["SizeX"].raw = rawStream.ToArray();
            }
            //properties["SizeX"] = Size;
            //Size = properties["SizeY"];
            properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height;
            using (MemoryStream rawStream = new MemoryStream(properties["SizeY"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["SizeY"].raw = rawStream.ToArray();
            }
            //properties["SizeY"] = Size;
            //this.hasChanged = true;
        }
Beispiel #11
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;
        }
Beispiel #12
0
        public void singleImageUpscale(string imagePathToAdd, string archiveDir)
        {
            ImageSize biggerImageSizeOnList = imgList.Max(image => image.imgSize);
            // check if replacing image is supported
            ImageFile imgFile;
            string fileFormat = Path.GetExtension(imagePathToAdd);
            switch (fileFormat)
            {
                case ".dds": imgFile = new DDS(imagePathToAdd, null); break;
                case ".DDS": imgFile = new DDS(imagePathToAdd, 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());
            }

            // !!! warning, this method breaks consistency between imgList and imageData[] !!!
            ImageInfo newImgInfo = new ImageInfo();
            newImgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType;
            newImgInfo.imgSize = imgFile.imgSize;
            newImgInfo.uncSize = imgFile.resize().Length;
            newImgInfo.cprSize = 0x00; // not yet filled
            newImgInfo.offset = 0x00; // not yet filled
            imgList.RemoveAt(0);  // Remove old single image and add new one
            imgList.Add(newImgInfo);

            //now I let believe the program that I'm doing an image replace, saving lot of code ;)
            replaceImage2(newImgInfo.imgSize.ToString(), imagePathToAdd, archiveDir);

            // update Sizes
            properties["SizeX"].Value.IntValue = (int)newImgInfo.imgSize.width;
            properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height;
        }
Beispiel #13
0
        public void addBiggerImage(string imagePathToAdd, string archiveDir)
        {
            ImageSize biggerImageSizeOnList = imgList.Max(image => image.imgSize);
            // check if replacing image is supported
            ImageFile imgFile;
            string fileFormat = Path.GetExtension(imagePathToAdd);
            switch (fileFormat)
            {
                case ".dds": imgFile = new DDS(imagePathToAdd, null); break;
                case ".DDS": imgFile = new DDS(imagePathToAdd, 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());
            }

            // check if image to add is valid
            if (biggerImageSizeOnList.width * 2 != imgFile.imgSize.width || biggerImageSizeOnList.height * 2 != imgFile.imgSize.height)
                throw new FormatException("image size " + imgFile.imgSize + " isn't valid, must be " + new ImageSize(biggerImageSizeOnList.width * 2, biggerImageSizeOnList.height * 2));

            if (imgList.Count <= 1)
                throw new Exception("Unable to add image, texture must have more than one image present");

            // !!! warning, this method breaks consistency between imgList and imageData[] !!!
            ImageInfo newImgInfo = new ImageInfo();
            newImgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType;
            // for additional mipmaps keep them in external archive but only when
            // texture allready have such property
            if (properties.ContainsKey("TextureFileCacheName"))
                newImgInfo.storageType = storage.arcCpr;
            newImgInfo.imgSize = imgFile.imgSize;
            newImgInfo.uncSize = imgFile.resize().Length;
            newImgInfo.cprSize = 0x00; // not yet filled
            newImgInfo.offset = 0x00; // not yet filled
            imgList.Insert(0, newImgInfo); // insert new image on top of the list

            //now I let believe the program that I'm doing an image replace, saving lot of code ;)
            replaceImage(newImgInfo.imgSize.ToString(), imagePathToAdd, archiveDir);

            //updating num of images
            numMipMaps++;

            // update MipTailBaseIdx
            int propVal = properties["MipTailBaseIdx"].Value.IntValue;
            propVal++;
            properties["MipTailBaseIdx"].Value.IntValue = propVal;

            // update Sizes
            properties["SizeX"].Value.IntValue = (int)newImgInfo.imgSize.width;
            properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height;
        }
Beispiel #14
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;
        }
Beispiel #15
0
        // New methods!
        public void OneSizeFitsAll(String inputFile, bool resFix = false)
        {
            // forced lowresfix
            // resFix = true;

            if (!File.Exists(inputFile))
                throw new FileNotFoundException("Input texture not found at: " + inputFile);

            bool containsmips = true;
            ImageMipMapHandler mipmaps = null;

            if (imgList.Count > 1)
            {
                try{ mipmaps = new ImageMipMapHandler(inputFile, null); }
                catch (FormatException) { containsmips = false; }
            }
            else
                containsmips = false;

            ImageInfo existingImg = imgList.First(img => img.storageType != storage.empty);
            if (containsmips)
            {
                if ((float)mipmaps.imageList[0].imgSize.width / (float)mipmaps.imageList[0].imgSize.height != (float)existingImg.imgSize.width / (float)existingImg.imgSize.height)
                    throw new FormatException("Input texture not correct aspect ratio");

                if (mipmaps.imageList[0].format == "PF_R8G8B8") // Convert to 32-bit if necessary
                {
                    for (int i = 0; i < mipmaps.imageList.Count; i++)
                        mipmaps.imageList[i] = new DDS(null, mipmaps.imageList[i].imgSize, "A8R8G8B8", ImageMipMapHandler.ConvertTo32bit(mipmaps.imageList[i].resize(), (int)mipmaps.imageList[i].imgSize.width, (int)mipmaps.imageList[i].imgSize.height));
                }

                if (Class == class2 || Class == class3) // Allow format modification if one of the derived classes. Don't need the single level check since we're replacing all levels
                    ChangeFormat(mipmaps.imageList[0].format);

                if (texFormat == "PF_NormalMap_HQ") // Check formats
                {
                    if (mipmaps.imageList[0].format != "ATI2")
                        throw new FormatException("Texture not in correct format - Expected ATI2");
                }
                else if (String.Compare(texFormat, "PF_" + mipmaps.imageList[0].format, true) != 0)
                    throw new FormatException("Texture not in correct format - Expected " + texFormat);

                for (int i = mipmaps.imageList.Count - 1; i >= 0; i--)
                {
                    if (imgList.Exists(img => img.imgSize == mipmaps.imageList[i].imgSize))
                        ReplaceImage(mipmaps.imageList[i]);
                    else if (mipmaps.imageList[i].imgSize.width > imgList.First().imgSize.width && mipmaps.imageList[i].imgSize.height > imgList.First().imgSize.height)
                        UpscaleImage(mipmaps.imageList[i]);
                    //else
                    //    AddMissingImage(mipmaps.imageList[i]);
                    // Else ignore missing values
                }

                while (imgList[0].imgSize.width > mipmaps.imageList[0].imgSize.width) // Remove any existing higher levels
                    imgList.RemoveAt(0);
            }
            else
            {
                ImageFile ddsfile = new DDS(inputFile, null);
                
                if ((float)ddsfile.imgSize.width / (float)ddsfile.imgSize.height != (float)existingImg.imgSize.width / (float)existingImg.imgSize.height) // Check dimensions
                    throw new FormatException("Input texture not correct aspect ratio");

                if (ddsfile.format == "R8G8B8")
                    ddsfile = new DDS(null, ddsfile.imgSize, "A8R8G8B8", ImageMipMapHandler.ConvertTo32bit(ddsfile.resize(), (int)ddsfile.imgSize.width, (int)ddsfile.imgSize.height));

                if (imgList.Count == 1 && (Class == class2 || Class == class3)) // Since this is single level replacement, only allow format change if a single level texture with required class
                    ChangeFormat(ddsfile.format);

                if (texFormat == "PF_NormalMap_HQ") // Check format
                {
                    if (ddsfile.format != "ATI2")
                        throw new FormatException("Texture not in correct format - Expected ATI2");
                }
                else if (String.Compare(texFormat, "PF_" + ddsfile.format, true) != 0)
                    throw new FormatException("Texture not in correct format - Expected " + texFormat);

                if (imgList.Count == 1 && imgList[0].imgSize != ddsfile.imgSize) // If img doesn't exist and it's a single level texture, use hard replace
                    HardReplaceImage(ddsfile);
                else if (imgList.Exists(img => img.imgSize == ddsfile.imgSize)) // Catches the rest of the single levels and every one which has an existing reference for that level
                    ReplaceImage(ddsfile);
                else if (ddsfile.imgSize.width > imgList[0].imgSize.width) // Add a greater image
                    UpscaleImage(ddsfile);
                //else if (ddsfile.imgSize.width < imgList.Last().imgSize.width) // Add a smaller image
                //    AddMissingImage(ddsfile);
            }

            if (imgList.Count > 1 && resFix)
                LowResFix();

            // Fix up properties
            if (properties.ContainsKey("SizeX"))
                properties["SizeX"].Value.IntValue = (int)imgList.First(img => img.storageType != storage.empty).imgSize.width;
            if (properties.ContainsKey("SizeY"))
                properties["SizeY"].Value.IntValue = (int)imgList.First(img => img.storageType != storage.empty).imgSize.height;
            if (properties.ContainsKey("MipTailBaseIdx"))
                properties["MipTailBaseIdx"].Value.IntValue = imgList.Count - 1;
            numMipMaps = (uint)imgList.Count;
        }
Beispiel #16
0
        public void addBiggerImage(string imagePathToAdd, string archiveDir)
        {
            ImageSize biggerImageSizeOnList = imgList.Max(image => image.imgSize);
            // check if replacing image is supported
            ImageFile imgFile;
            string fileFormat = Path.GetExtension(imagePathToAdd);
            switch (fileFormat)
            {
                case ".dds": imgFile = new DDS(imagePathToAdd, null); break;
                case ".tga": imgFile = new TGA(imagePathToAdd, null); break;
                default: throw new FileFormatException(fileFormat + " image extension not supported");
            }

            // check if image to add is valid
            if(biggerImageSizeOnList.width * 2 != imgFile.imgSize.width || biggerImageSizeOnList.height * 2 != imgFile.imgSize.height)
                throw new FormatException("image size " + imgFile.imgSize + " isn't valid, must be " + new ImageSize(biggerImageSizeOnList.width * 2,biggerImageSizeOnList.height * 2));

            // this check avoids insertion inside textures that have only 1 image stored inside pcc
            if(!imgList.Exists(img => img.storageType != storage.empty && img.storageType != storage.pccSto))
                throw new Exception("Unable to add image, texture must have a reference to an external archive");

            // !!! warning, this method breaks consistency between imgList and imageData[] !!!
            ImageInfo newImgInfo = new ImageInfo();
            newImgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType;
            newImgInfo.imgSize = imgFile.imgSize;
            newImgInfo.uncSize = imgFile.resize().Length;
            newImgInfo.cprSize = 0x00; // not yet filled
            newImgInfo.offset = 0x00; // not yet filled
            imgList.Insert(0, newImgInfo); // insert new image on top of the list
            //now I let believe the program that I'm doing an image replace, saving lot of code ;)
            replaceImage(newImgInfo.imgSize.ToString(), imagePathToAdd, archiveDir);
            
            //updating num of images
            numMipMaps++;

            // update MipTailBaseIdx
            //PropertyReader.Property MipTail = properties["MipTailBaseIdx"];
            int propVal = properties["MipTailBaseIdx"].Value.IntValue;
            propVal++;
            properties["MipTailBaseIdx"].Value.IntValue = propVal;
            //MessageBox.Show("raw size: " + properties["MipTailBaseIdx"].raw.Length + "\nproperty offset: " + properties["MipTailBaseIdx"].offsetval);
            using (MemoryStream rawStream = new MemoryStream(properties["MipTailBaseIdx"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["MipTailBaseIdx"].raw = rawStream.ToArray();
            }
            //properties["MipTailBaseIdx"] = MipTail;

            // update Sizes
            //PropertyReader.Property Size = properties["SizeX"];
            propVal = (int)newImgInfo.imgSize.width;
            properties["SizeX"].Value.IntValue = propVal;
            using (MemoryStream rawStream = new MemoryStream(properties["SizeX"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["SizeX"].raw = rawStream.ToArray();
            }
            //properties["SizeX"] = Size;
            //Size = properties["SizeY"];
            properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height;
            using (MemoryStream rawStream = new MemoryStream(properties["SizeY"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["SizeY"].raw = rawStream.ToArray();
            }
            //properties["SizeY"] = Size;
            properties["OriginalSizeX"].Value.IntValue = propVal;
            using (MemoryStream rawStream = new MemoryStream(properties["OriginalSizeX"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["OriginalSizeX"].raw = rawStream.ToArray();
            }
            properties["OriginalSizeY"].Value.IntValue = propVal;
            using (MemoryStream rawStream = new MemoryStream(properties["OriginalSizeY"].raw))
            {
                rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin);
                rawStream.WriteValueS32(propVal);
                properties["OriginalSizeY"].raw = rawStream.ToArray();
            }
        }
Beispiel #17
0
        public void HardReplaceImage(ImageFile ddsfile)
        {
            ImageSize imgSize = ddsfile.imgSize;

            if (ddsfile.format == "R8G8B8")
            {
                byte[] buff = ImageMipMapHandler.ConvertTo32bit(ddsfile.imgData, (int)ddsfile.imgSize.width, (int)ddsfile.imgSize.height);
                ddsfile = new DDS(null, ddsfile.imgSize, "A8R8G8B8", buff);
            }

            ImageInfo newImg = new ImageInfo();
            newImg.storageType = imgList[0].storageType;
            if (newImg.storageType == storage.empty || newImg.storageType == storage.arcCpr || newImg.storageType == storage.arcUnc)
                throw new FormatException("Original texture cannot be empty or externally stored");

            newImg.offset = 0;
            newImg.imgSize = imgSize;
            imageData = ddsfile.resize();
            newImg.uncSize = imageData.Length;
            if ((long)newImg.uncSize != ImageFile.ImageDataSize(imgSize, ddsfile.format, ddsfile.BPP))
                throw new FormatException("Input texture not correct length!");
            
            switch (newImg.storageType)
            {
                case storage.pccSto:
                    newImg.cprSize = imageData.Length;
                    break;
                case storage.pccCpr:
                    SaltLZOHelper lzohelper = new SaltLZOHelper();
                    imageData = lzohelper.CompressTex(imageData);
                    newImg.cprSize = imageData.Length;
                    break;
            }

            imgList.RemoveAt(0);
            imgList.Add(newImg);

            // Fix up properties
            properties["SizeX"].Value.IntValue = (int)imgSize.width;
            properties["SizeY"].Value.IntValue = (int)imgSize.height;
        }
        public byte[] extractImage(ImageInfo imgInfo, bool NoOutput, 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 = GetTexArchive(archiveDir);
                    string archivePath = FullArcPath;
                    if (String.IsNullOrEmpty(archivePath))
                        GetTexArchive(archiveDir);
                    if (archivePath == null)
                        throw new FileNotFoundException("Texture archive not found!");
                    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, Textures.Methods.StringifyFormat(texFormat), imgBuffer);
            //else
            //    imgFile = new TGA(fileName, imgInfo.imgSize, texFormat, imgBuffer);

            byte[] saveImg = imgFile.ToArray();

            if (!NoOutput)
                using (FileStream outputImg = new FileStream(imgFile.fileName, FileMode.Create, FileAccess.Write))
                    outputImg.Write(saveImg, 0, saveImg.Length);

            return saveImg;
        }
Beispiel #19
0
        public void InstallTexture(string texname, List<string> pccs, List<int> IDs, byte[] imgdata)
        {
            string fulpath = pccs[0];
            string temppath = (WhichGame == 1) ? Path.GetDirectoryName(pathBIOGame) : pathBIOGame;
            if (!fulpath.Contains(temppath))
                fulpath = Path.Combine(temppath, fulpath);


            // KFreon: Skip files that don't exist
            if (!File.Exists(fulpath))
                return;

            PCCObjects.IPCCObject pcc = PCCObjects.Creation.CreatePCCObject(fulpath, WhichGame);

            if ((pcc.Exports[IDs[0]].ClassName != "Texture2D" && pcc.Exports[IDs[0]].ClassName != "LightMapTexture2D" && pcc.Exports[IDs[0]].ClassName != "TextureFlipBook") || String.Compare(pcc.Exports[IDs[0]].ObjectName, texname, true) != 0)
                throw new InvalidDataException("Export is not correct class or name!");

            //Load the texture from the pcc
            Textures.ITexture2D tex2D = null;
            tex2D = pcc.CreateTexture2D(IDs[0], pathBIOGame);
            tex2D.allPccs = pccs;
            tex2D.expIDs = IDs;
            int noImg = tex2D.imgList.Count;

            DebugOutput.PrintLn("Now replacing textures in texture: " + tex2D.texName, true);
            Debug.WriteLine("Now replacing textures in texture: " + tex2D.texName + "  ID: " + IDs[0]);
            WriteDebug("Now replacing textures in texture: " + tex2D.texName + "  ID: " + IDs[0]);

            ImageFile im = null;
            try
            {
                im = new DDS("", imgdata);
            }
            catch
            {
                Console.WriteLine("");
            }



            // KFreon: TESTING
            Debug.WriteLine("First pcc: " + fulpath + "    ArcName: " + tex2D.arcName);
            WriteDebug("First pcc: " + fulpath + "    ArcName: " + tex2D.arcName);



            //The texture is a single image, therefore use replace function
            if (noImg == 1)
            {
                string imgSize = tex2D.imgList[0].imgSize.width.ToString() + "x" + tex2D.imgList[0].imgSize.height.ToString();
                try
                {
                    tex2D.replaceImage(imgSize, im, pathBIOGame);
                }
                catch
                {
                    // KFreon:  If replace fails, it's single image thus use the singleimageupscale function
                    tex2D.singleImageUpscale(im, pathBIOGame);
                }
            }
            //If the texture has multiple images, then check the input texture for MIPMAPS
            else
            {
                bool hasMips = true;
                ImageFile imgFile = im;
                try { ImageMipMapHandler imgMipMap = new ImageMipMapHandler("", imgdata); }
                catch { hasMips = false; }
                if (!hasMips)
                {
                    //string fileformat = Path.GetExtension(texFile);
                    //imgFile = new DDS(texFile);
                    string imgSize = imgFile.imgSize.width.ToString() + "x" + imgFile.imgSize.height.ToString();
                    try
                    {
                        //Try replacing the image. If it doesn't exist then it'll throw and error and you'll need to upscale the image
                        tex2D.replaceImage(imgSize, imgFile, pathBIOGame);
                    }
                    catch { tex2D.addBiggerImage(imgFile, pathBIOGame); }
                }
                else
                {
                    try
                    {
                        tex2D.OneImageToRuleThemAll(imgFile, pathBIOGame, imgdata);
                    }
                    catch (Exception e)
                    {
                        if (e.Message.Contains("Format"))
                        {
                            MessageBox.Show(texname + " is in the wrong format." + Environment.NewLine + Environment.NewLine + e.Message);
                            return;
                        }
                    }
                }
            }

            Debug.WriteLine("After replace: " + tex2D.arcName);
            WriteDebug("After replace: " + tex2D.arcName);


            DebugOutput.PrintLn("Replacement complete. Now saving pcc: " + pcc.pccFileName, true);

            //tex2D.DumpTexture(@"R:\commit.txt");

            PCCObjects.IExportEntry expEntry = pcc.Exports[IDs[0]];
            expEntry.SetData(tex2D.ToArray(expEntry.DataOffset, pcc));
            expEntry.hasChanged = true;
            pcc.Exports[IDs[0]] = expEntry;

            pcc.saveToFile(pcc.pccFileName);

            /*File.Delete(loc + "tex.dds");
            File.Delete(loc + "data.bin");*/

            int modCount = tex2D.allPccs.Count;

            // KFreon: Elapsed time stuff
            int start = Environment.TickCount;

            // KFreon: Start threading of save function (max 10 threads)
            //ParallelOptions po = new ParallelOptions();
            //po.MaxDegreeOfParallelism = 2;
            if (modCount > 1)
                //Parallel.For(1, modCount, po, (item, loopstate) =>
                for (int item = 1; item < modCount; item++)
                {
                    Debug.WriteLine(pccs[item] +  "   " + IDs[item]);
                    WriteDebug(pccs[item] + "   " + IDs[item]);
                    if (!SaveFile(pccs, IDs, tex2D, item))
                        break;
                    /*loopstate.Stop();
            });*/
                }
            Debug.WriteLine("");
            WriteDebug("");
            // KFreon: More timer stuff
            TimeSpan ts = TimeSpan.FromMilliseconds(Environment.TickCount - start);
            Console.WriteLine(ts.Duration().ToString());
            GC.Collect();
            DebugOutput.Print("All PCC updates finished. ");
        }