Пример #1
0
        public void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null,
                         PsbLinkOrderBy order = PsbLinkOrderBy.Convention)
        {
            var rawResList = psb.CollectResources <AudioMetadata>();

            if (order == PsbLinkOrderBy.Order)
            {
                for (int i = 0; i < rawResList.Count; i++)
                {
                    var resMd    = rawResList[i];
                    var fullPath = Path.Combine(baseDir ?? "", resPaths[i]);
                    resMd.Link(fullPath, context);
                }

                return;
            }

            foreach (var resPath in resPaths)
            {
                var resMd = rawResList.FirstOrDefault(r => r.Name == Path.GetFileNameWithoutExtension(resPath));
                if (resMd == null)
                {
                    Console.WriteLine($"[WARN] {resPath} is not used.");
                    continue;
                }

                var fullPath = Path.Combine(baseDir ?? "", resPath);
                resMd.Link(fullPath, context);
            }
        }
Пример #2
0
        /// <summary>
        /// Convert a PSB to External Texture PSB.
        /// </summary>
        /// <param name="inputPath"></param>
        /// <param name="order"></param>
        /// <param name="format"></param>
        public static void UnlinkToFile(string inputPath, PsbLinkOrderBy order = PsbLinkOrderBy.Name, PsbImageFormat format = PsbImageFormat.Png)
        {
            if (!File.Exists(inputPath))
            {
                return;
            }

            var name    = Path.GetFileNameWithoutExtension(inputPath);
            var dirPath = Path.Combine(Path.GetDirectoryName(inputPath), name);

            if (File.Exists(dirPath))
            {
                name    += "-resources";
                dirPath += "-resources";
            }

            if (!Directory.Exists(dirPath)) //ensure there is no file with same name!
            {
                Directory.CreateDirectory(dirPath);
            }

            var psb  = new PSB(inputPath);
            var texs = psb.Unlink();

            var texExt    = format == PsbImageFormat.Bmp ? ".bmp" :".png";
            var texFormat = format == PsbImageFormat.Bmp ? ImageFormat.Bmp : ImageFormat.Png;

            switch (order)
            {
            case PsbLinkOrderBy.Convention:
                foreach (var tex in texs)
                {
                    tex.Save(Path.Combine(dirPath, tex.Tag + texExt), texFormat);
                }
                break;

            case PsbLinkOrderBy.Name:
                foreach (var tex in texs)
                {
                    tex.Save(Path.Combine(dirPath, $"{name}_{tex.Tag}{texExt}"), texFormat);
                }
                break;

            case PsbLinkOrderBy.Order:
                for (var i = 0; i < texs.Count; i++)
                {
                    var tex = texs[i];
                    tex.Save(Path.Combine(dirPath, $"{i}{texExt}"), texFormat);
                }
                break;
            }
        }
Пример #3
0
        /// <summary>
        /// Link Textures
        /// </summary>
        /// <param name="psb"></param>
        /// <param name="resPaths">resource paths</param>
        /// <param name="baseDir"></param>
        /// <param name="order">how to arrange images</param>
        /// <param name="isExternal">Whether this is an external texture PSB</param>
        public static void Link(this PSB psb, IList <string> resPaths, string baseDir = null,
                                PsbLinkOrderBy order = PsbLinkOrderBy.Convention, bool isExternal = false)
        {
            var context = FreeMount.CreateContext();

            if (psb.Type == PsbType.Motion)
            {
                PsbResHelper.LinkImages(psb, context, resPaths, baseDir, order, isExternal);
                return;
            }

            if (psb.TypeHandler != null)
            {
                psb.TypeHandler.Link(psb, context, resPaths, baseDir, order);
            }
            else
            {
                PsbResHelper.LinkImages(psb, context, resPaths, baseDir, order);
            }
        }
Пример #4
0
        /// <summary>
        /// Inlined PSB -> External Texture PSB. Inverse of Link
        /// </summary>
        /// <param name="psb"></param>
        /// <param name="order">To make a regular external texture PSB you should set it to <see cref="PsbLinkOrderBy.Name"/>.</param>
        /// <param name="disposeResInPsb">Whether to remove resources in PSB. To make a real external texture PSB you should set it to true.</param>
        /// <returns>Ordered textures</returns>
        public static List <Bitmap> UnlinkImages(PSB psb, PsbLinkOrderBy order = PsbLinkOrderBy.Name, bool disposeResInPsb = true)
        {
            var           resources = psb.CollectResources <ImageMetadata>();
            List <Bitmap> texs      = new List <Bitmap>();

            for (int i = 0; i < resources.Count; i++)
            {
                var resource = resources[i];
                var tex      = RL.ConvertToImage(resource.Data, resource.PalData, resource.Height, resource.Width,
                                                 resource.PixelFormat, resource.PalettePixelFormat);

                switch (order)
                {
                case PsbLinkOrderBy.Convention:
                    tex.Tag = resource.GetFriendlyName(psb.Type);
                    break;

                default:
                    var tId = resource.TextureIndex;
                    if (tId == null)
                    {
                        throw new FormatException(
                                  "Unable to unlink with texture names since they can't be recognized.");
                    }

                    tex.Tag = $"tex{tId.Value:D3}";
                    break;
                }

                texs.Add(tex);

                //Finally, dispose
                if (disposeResInPsb)
                {
                    resource.Data = null;
                }
            }

            return(texs);
        }
Пример #5
0
        public static void UnlinkImagesToFile(PSB psb, FreeMountContext context, string name, string dirPath,
                                              bool disposeResInPsb = true,
                                              PsbLinkOrderBy order = PsbLinkOrderBy.Name)
        {
            var texs = UnlinkImages(psb, order, disposeResInPsb);

            var texExt    = context.ImageFormat.DefaultExtension();
            var texFormat = context.ImageFormat.ToImageFormat();

            switch (order)
            {
            case PsbLinkOrderBy.Convention:
                foreach (var tex in texs)
                {
                    tex.Save(Path.Combine(dirPath, tex.Tag + texExt), texFormat);
                }

                break;

            case PsbLinkOrderBy.Name:
                foreach (var tex in texs)
                {
                    tex.Save(Path.Combine(dirPath, $"{name}_{tex.Tag}{texExt}"), texFormat);
                }

                break;

            case PsbLinkOrderBy.Order:
                for (var i = 0; i < texs.Count; i++)
                {
                    var tex = texs[i];
                    tex.Save(Path.Combine(dirPath, $"{i}{texExt}"), texFormat);
                }

                break;
            }

            return;
        }
Пример #6
0
        private static void Link(string psbPath, List <string> texPaths, PsbLinkOrderBy order)
        {
            if (!File.Exists(psbPath))
            {
                return;
            }

            var name = Path.GetFileNameWithoutExtension(psbPath);
            var ext  = Path.GetExtension(psbPath);

            try
            {
                List <string> texs = new List <string>();
                foreach (var texPath in texPaths)
                {
                    if (File.Exists(texPath))
                    {
                        texs.Add(texPath);
                    }
                    else if (Directory.Exists(texPath))
                    {
                        texs.AddRange(Directory.EnumerateFiles(texPath));
                    }
                }

                PSB psb = new PSB(psbPath);
                psb.Link(texs, order: order, isExternal: true);
                psb.Merge();
                File.WriteAllBytes(Path.ChangeExtension(psbPath, "linked" + ext), psb.Build());
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.WriteLine($"Link {name} succeed.");
        }
Пример #7
0
        public static void LinkImages(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null,
                                      PsbLinkOrderBy order = PsbLinkOrderBy.Convention, bool isExternal = false)
        {
            if (isExternal)
            {
                MotionType.MotionResourceInstrument(psb);
            }

            var rawResList = psb.CollectResources <ImageMetadata>();

            if (order == PsbLinkOrderBy.Order)
            {
                for (int i = 0; i < rawResList.Count; i++)
                {
                    var resMd    = rawResList[i];
                    var fullPath = Path.Combine(baseDir ?? "", resPaths[i]);
                    resMd.Link(fullPath, context);
                }

                return;
            }

            var resList = rawResList.ToList();

            if (order == PsbLinkOrderBy.Name)
            {
                if (psb.Platform == PsbSpec.krkr)
                {
                    throw new InvalidOperationException(
                              $"Can not link by file name for krkr PSB. Please consider using {PsbLinkOrderBy.Convention}");
                }

                resList.Sort((md1, md2) =>
                             (int)(((ImageMetadata)md1).TextureIndex ?? 0) - (int)(((ImageMetadata)md2).TextureIndex ?? 0));
            }

            for (var i = 0; i < resPaths.Count; i++)
            {
                var resPath = resPaths[i];
                var resName = Path.GetFileNameWithoutExtension(resPath);
                //var resMd = uint.TryParse(resName, out uint rid)
                //    ? resList.FirstOrDefault(r => r.Index == rid)
                //    : resList.FirstOrDefault(r =>
                //        resName == $"{r.Part}{PsbResCollector.ResourceNameDelimiter}{r.Name}");

                //Scan for Resource
                ImageMetadata resMd = null;
                if (order == PsbLinkOrderBy.Name)
                {
                    if (resName == null)
                    {
                        continue;
                    }

                    if (resList.Count == 1 && resPaths.Count == 1)
                    {
                        //If there is only one resource and one texture, we won't care about file name.
                        resMd = resList[0];
                    }
                    else
                    {
                        var texIdx = ImageMetadata.GetTextureIndex(resName);

                        if (texIdx == null)
                        {
                            Console.WriteLine($"[WARN]{resPath} is not used since the file name cannot be recognized.");
                            continue;
                        }

                        if (resList.Count <= texIdx.Value)
                        {
                            Console.WriteLine($"[WARN]{resPath} is not used since the tex No. is too large.");
                            continue;
                        }

                        resMd = resList[(int)texIdx.Value];
                    }
                }
                else //if (order == PsbLinkOrderBy.Convention)
                {
                    resMd = resList.FirstOrDefault(r =>
                                                   resName == $"{r.Part}{Consts.ResourceNameDelimiter}{r.Name}");
                    if (resMd == null && uint.TryParse(resName, out uint rid))
                    {
                        //This Link has no support for raw palette
                        resMd = resList.FirstOrDefault(r => r.Index == rid);
                    }

                    if (resMd == null && psb.Type == PsbType.Pimg)
                    {
                        resMd = resList.FirstOrDefault(r => resName == Path.GetFileNameWithoutExtension(r.Name));
                    }
                }


                if (resMd == null)
                {
                    Console.WriteLine($"[WARN]{resPath} is not used.");
                    continue;
                }

                var fullPath = Path.Combine(baseDir ?? "", resPath.Replace('/', '\\'));
                resMd.Link(fullPath, context);
            }
        }
Пример #8
0
 public virtual void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention)
 {
     PsbResHelper.LinkImages(psb, context, resPaths, baseDir, order);
 }
Пример #9
0
 public virtual void UnlinkToFile(PSB psb, FreeMountContext context, string name, string dirPath, bool outputUnlinkedPsb = true,
                                  PsbLinkOrderBy order = PsbLinkOrderBy.Name)
 {
     PsbResHelper.UnlinkImagesToFile(psb, context, name, dirPath, outputUnlinkedPsb, order);
 }
Пример #10
0
 public virtual List <Bitmap> Unlink(PSB psb, PsbLinkOrderBy order = PsbLinkOrderBy.Name, bool disposeResInPsb = true)
 {
     return(PsbResHelper.UnlinkImages(psb, order, disposeResInPsb));
 }
Пример #11
0
        /// <summary>
        /// Convert a PSB to External Texture PSB.
        /// </summary>
        /// <param name="inputPath"></param>
        /// <param name="outputUnlinkedPsb">output unlinked PSB; otherwise only output textures</param>
        /// <param name="order"></param>
        /// <param name="format"></param>
        /// <returns>The unlinked PSB path</returns>
        public static string UnlinkToFile(string inputPath, bool outputUnlinkedPsb = true, PsbLinkOrderBy order = PsbLinkOrderBy.Name, PsbImageFormat format = PsbImageFormat.png)
        {
            if (!File.Exists(inputPath))
            {
                return(null);
            }

            var name        = Path.GetFileNameWithoutExtension(inputPath);
            var dirPath     = Path.Combine(Path.GetDirectoryName(inputPath), name);
            var psbSavePath = inputPath;

            if (File.Exists(dirPath))
            {
                name    += "-resources";
                dirPath += "-resources";
            }

            if (!Directory.Exists(dirPath)) //ensure there is no file with same name!
            {
                Directory.CreateDirectory(dirPath);
            }

            var context = FreeMount.CreateContext();

            context.ImageFormat = format;
            var psb = new PSB(inputPath);

            if (psb.TypeHandler is BaseImageType imageType)
            {
                imageType.UnlinkToFile(psb, context, name, dirPath, outputUnlinkedPsb, order);
            }

            psb.TypeHandler.UnlinkToFile(psb, context, name, dirPath, outputUnlinkedPsb, order);

            if (outputUnlinkedPsb)
            {
                psb.Merge();
                psbSavePath = Path.ChangeExtension(inputPath, ".unlinked.psb"); //unlink only works with motion.psb so no need for ext rename
                File.WriteAllBytes(psbSavePath, psb.Build());
            }

            return(psbSavePath);
        }
Пример #12
0
 public void UnlinkToFile(PSB psb, FreeMountContext context, string name, string dirPath, bool outputUnlinkedPsb = true,
                          PsbLinkOrderBy order = PsbLinkOrderBy.Name)
 {
     //TODO:
 }
Пример #13
0
 public override void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null,
                           PsbLinkOrderBy order = PsbLinkOrderBy.Convention)
 {
     LinkImages(psb, context, resPaths, baseDir, order, true);
 }
Пример #14
0
 public void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention)
 {
 }