Example #1
0
        /// <summary>
        /// Extract resource info
        /// </summary>
        /// <param name="d">PsbObject which contains "pixel"</param>
        /// <param name="r">Resource</param>
        /// <param name="duplicatePalette"></param>
        /// <returns></returns>
        internal static ImageMetadata GenerateImageMetadata(PsbDictionary d, PsbResource r = null,
                                                            bool duplicatePalette          = false)
        {
            if (r == null)
            {
                r = d.Values.FirstOrDefault(v => v is PsbResource) as PsbResource;
            }

            bool       is2D = false;
            var        part = GetPartName(d);
            var        name = d.GetName();
            RectangleF clip = RectangleF.Empty;

            if (d["clip"] is PsbDictionary clipDic && clipDic.Count > 0)
            {
                is2D = true;
                clip = RectangleF.FromLTRB(
                    left: clipDic["left"] == null ? 0f : (float)(PsbNumber)clipDic["left"],
                    top: clipDic["top"] == null ? 0f : (float)(PsbNumber)clipDic["top"],
                    right: clipDic["right"] == null ? 1f : (float)(PsbNumber)clipDic["right"],
                    bottom: clipDic["bottom"] == null ? 1f : (float)(PsbNumber)clipDic["bottom"]
                    );
            }

            var compress = PsbCompressType.None;

            if (d["compress"] is PsbString sc)
            {
                is2D = true;
                if (sc.Value.ToUpperInvariant() == "RL")
                {
                    compress = PsbCompressType.RL;
                }
            }

            int   width = 1, height = 1;
            float originX = 0, originY = 0;

            if (d["width"] is PsbNumber nw)
            {
                is2D  = true;
                width = (int)nw;
            }

            if (d["height"] is PsbNumber nh)
            {
                is2D   = true;
                height = (int)nh;
            }

            if (d["originX"] is PsbNumber nx)
            {
                is2D    = true;
                originX = (float)nx;
            }

            if (d["originY"] is PsbNumber ny)
            {
                is2D    = true;
                originY = (float)ny;
            }

            PsbString typeString = null;

            if (d["type"] is PsbString typeStr)
            {
                typeString = typeStr;
            }

            int top = 0, left = 0;

            if (d["top"] is PsbNumber nt)
            {
                is2D = true;
                top  = (int)nt;
            }

            if (d["left"] is PsbNumber nl)
            {
                is2D = true;
                left = (int)nl;
            }

            PsbResource palResource   = null;
            PsbString   palTypeString = null;

            if (d["pal"] is PsbResource palRes)
            {
                if (duplicatePalette)
                {
                    palResource = new PsbResource(palRes.Index);
                    d["pal"]    = palResource;
                }
                else
                {
                    palResource = palRes;
                }

                palTypeString = d["palType"] as PsbString;
            }

            var md = new ImageMetadata()
            {
                Index             = r.Index ?? int.MaxValue,
                Compress          = compress,
                Name              = name,
                Part              = part,
                Clip              = clip,
                Is2D              = is2D,
                OriginX           = originX,
                OriginY           = originY,
                Top               = top,
                Left              = left,
                Width             = width,
                Height            = height,
                TypeString        = typeString,
                Resource          = r,
                Palette           = palResource,
                PaletteTypeString = palTypeString
            };

            return(md);
        }
Example #2
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);
            }
        }