public void TestPsbStrings() { var se1 = PsbString.Empty; var se2 = PsbString.Empty; se1.Index = 114514; var se2i = se2.Index; return; var p1 = new PsbString("PSB"); var p2 = new PsbString("PSB", index: 1); var p3 = new PsbString("MDF", 1); var p4 = new PsbString("MDF"); var s1 = "PSB"; var r = p1 == p2; r = p2 == p3; r = p3 == p4; r = p1 == s1; r = s1 == p1; r = p3 == s1; p2.Index = null; r = p2 == p3; p2.Index = 1; var dic = new Dictionary <PsbString, string>(); dic.Add(p3, "mdf"); r = dic.ContainsKey(p4); r = dic.ContainsKey(p2); r = dic.ContainsKey(p1); dic.Add(p1, "psb"); r = dic.ContainsKey(p4); r = dic.ContainsKey(p2); r = dic.ContainsKey(p1); }
/// <summary> /// Extract resource info /// </summary> /// <param name="d">PsbObject which contains "pixel"</param> /// <param name="r">Resource</param> /// <param name="duplicatePalette">When set to true, Pal.Data may not be set!</param> /// <returns></returns> internal static ImageMetadata GenerateImageMetadata(PsbDictionary d, PsbResource r = null, bool duplicatePalette = false) { if (r == null) { if (d.ContainsKey(Consts.ResourceKey) && d[Consts.ResourceKey] is PsbResource rr) { r = rr; } else //this may find Pal { 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); }
private void Travel(IPsbCollection collection, Dictionary <string, List <string> > iconInfo) { //TODO: recover icon names if (collection is PsbDictionary dic) { //mask+=1 //add ox=0, oy=0 //explain: the last bit of mask (00...01) is whether to use ox & oy. if use, last bit of mask is 1 //change src if (dic.ContainsKey("mask") && dic.GetName() == "content") { if (dic["src"] is PsbString s) { //"blank" ("icon" : "32:32:16:16") -> "blank/32:32:16:16" if (s.Value == "blank") { var size = dic["icon"].ToString(); dic["src"] = new PsbString($"blank/{size}"); } //"tex" ("icon" : "0001") -> "src/tex/0001" else if (iconInfo.ContainsKey(s)) { var iconName = dic["icon"].ToString(); dic["src"] = new PsbString($"src/{s}/{iconName}"); } //"ex_body_a" ("icon" : "差分A") -> "motion/ex_body_a/差分A" else { var iconName = dic["icon"].ToString(); dic["src"] = new PsbString($"motion/{s}/{iconName}"); } } var num = (PsbNumber)dic["mask"]; num.AsInt |= 1; //num.IntValue = num.IntValue + 1; //add src = layout || src = shape/point (0) if (num.IntValue == 1 || num.IntValue == 3 || num.IntValue == 19) { if (!dic.ContainsKey("src")) { bool isLayout = true; //content -> {} -> [] -> {} if (dic.Parent.Parent.Parent is PsbDictionary childrenArrayDic) { if (childrenArrayDic.ContainsKey("shape")) { string shape = ((PsbNumber)childrenArrayDic["shape"]).ToShapeString(); dic.Add("src", new PsbString($"shape/{shape}")); isLayout = false; } } if (isLayout) { dic.Add("src", new PsbString("layout")); } } } if (!dic.ContainsKey("ox")) { dic.Add("ox", PsbNumber.Zero); } if (!dic.ContainsKey("oy")) { dic.Add("oy", PsbNumber.Zero); } } foreach (var child in dic.Values) { if (child is IPsbCollection childCol) { Travel(childCol, iconInfo); } } } if (collection is PsbList col) { foreach (var child in col) { if (child is IPsbCollection childCol) { Travel(childCol, iconInfo); } } } }
internal IPsbValue ConvertToken(JToken token, Dictionary <string, PsbString> context) { switch (token.Type) { case JTokenType.Null: return(PsbNull.Null); case JTokenType.Integer: var l = token.Value <long>(); if (l > Int32.MaxValue || l < Int32.MinValue) { return(new PsbNumber(l)); } return(new PsbNumber(token.Value <int>())); case JTokenType.Float: //var numberStr = token.Value<string>(); var d = token.Value <double>(); if (UseDoubleOnly) { return(new PsbNumber(d)); } var f = token.Value <float>(); if (Math.Abs(f - d) < 1E-08) //float //pcc: 1E-05 //if (Math.Abs(f - d) < float.Epsilon) { return(new PsbNumber(f)); } //if (d < float.MaxValue && d > float.MinValue) //{ // return new PsbNumber(token.Value<float>()); //} return(new PsbNumber(d)); case JTokenType.Boolean: return(new PsbBool(token.Value <bool>())); case JTokenType.String: string str = token.Value <string>(); if (str.StartsWith(Consts.NumberStringPrefix)) { var prefixLen = Consts.NumberStringPrefix.Length; if (str.EndsWith("f")) { return(new PsbNumber(int.Parse(str.Substring(prefixLen, 8), NumberStyles.AllowHexSpecifier)) { NumberType = PsbNumberType.Float }); } if (str.EndsWith("d")) { return(new PsbNumber(long.Parse(str.Substring(prefixLen, 16), NumberStyles.AllowHexSpecifier)) { NumberType = PsbNumberType.Double }); } return(new PsbNumber(long.Parse(str.Substring(prefixLen), NumberStyles.AllowHexSpecifier))); } if (str.StartsWith(Consts.ResourceIdentifier)) { return(new PsbResource(uint.Parse(str.Replace(Consts.ResourceIdentifier, "")))); } var psbStr = new PsbString(str, (uint)context.Count); if (context.ContainsKey(str)) { return(context[str]); } else { context.Add(str, psbStr); } return(psbStr); case JTokenType.Array: var array = (JArray)token; var collection = new PsbList(array.Count); foreach (var val in array) { var o = ConvertToken(val, context); if (o is IPsbChild c) { c.Parent = collection; } if (o is IPsbSingleton s) { s.Parents.Add(collection); } collection.Add(o); } return(collection); case JTokenType.Object: var obj = (JObject)token; var dictionary = new PsbDictionary(obj.Count); foreach (var val in obj) { var o = ConvertToken(val.Value, context); if (o is IPsbChild c) { c.Parent = dictionary; } if (o is IPsbSingleton s) { s.Parents.Add(dictionary); } dictionary.Add(val.Key, o); } return(dictionary); default: throw new FormatException("Unsupported json element"); } }
/// <summary> /// Extract resource info /// </summary> /// <param name="d">PsbObject which contains "pixel"</param> /// <param name="r">Resource</param> /// <returns></returns> internal static ResourceMetadata GenerateMotionResMetadata(PsbDictionary d, PsbResource r = null) { if (r == null) { r = d.Values.FirstOrDefault(v => v is PsbResource) as PsbResource; } bool is2D = false; var part = d.GetPartName(); 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; } var md = new ResourceMetadata() { 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, }; return(md); }
private void Travel(IPsbCollection collection, Dictionary <string, List <string> > iconInfo) { //TODO: recover icon names if (collection is PsbDictionary dic) { //mask+=1 //add ox=0, oy=0 //change src if (dic.ContainsKey("mask") && dic.GetName() == "content") { if (dic["src"] is PsbString s) { //"blank" ("icon" : "32:32:16:16") -> "blank/32:32:16:16" if (s.Value == "blank") { var size = dic["icon"].ToString(); dic["src"] = new PsbString($"blank/{size}"); } //"tex" ("icon" : "0001") -> "src/tex/0001" else if (iconInfo.ContainsKey(s)) { var iconName = dic["icon"].ToString(); dic["src"] = new PsbString($"src/{s}/{iconName}"); } //"ex_body_a" ("icon" : "差分A") -> "motion/ex_body_a/差分A" else { var iconName = dic["icon"].ToString(); dic["src"] = new PsbString($"motion/{s}/{iconName}"); } } var num = (PsbNumber)dic["mask"]; num.IntValue = num.IntValue + 1; //add src = layout || src = shape/point (0) if (num.IntValue == 1 || num.IntValue == 3 || num.IntValue == 19) { if (!dic.ContainsKey("src")) { bool isLayout = true; //content -> {} -> [] -> {} if (dic.Parent.Parent.Parent is PsbDictionary childrenArrayDic) { if (childrenArrayDic.ContainsKey("shape")) { string shape; switch (((PsbNumber)childrenArrayDic["shape"]).IntValue) { case 0: //We only know 0 = point default: shape = "point"; break; } dic.Add("src", new PsbString($"shape/{shape}")); isLayout = false; } } if (isLayout) { dic.Add("src", new PsbString("layout")); } } } if (!dic.ContainsKey("ox")) { dic.Add("ox", new PsbNumber(0)); } if (!dic.ContainsKey("oy")) { dic.Add("oy", new PsbNumber(0)); } } foreach (var child in dic.Values) { if (child is IPsbCollection childCol) { Travel(childCol, iconInfo); } } } if (collection is PsbCollection col) { foreach (var child in col) { if (child is IPsbCollection childCol) { Travel(childCol, iconInfo); } } } }
internal IPsbValue ConvertToken(JToken token, List <PsbString> context) { switch (token.Type) { case JTokenType.Null: return(PsbNull.Null); case JTokenType.Integer: return(new PsbNumber(token.Value <int>())); case JTokenType.Float: var d = token.Value <double>(); var f = token.Value <float>(); if (Math.Abs(f - d) < 1E-05) //float //pcc: 1E-05 { return(new PsbNumber(token.Value <float>())); } //if (d < float.MaxValue && d > float.MinValue) //{ // return new PsbNumber(token.Value<float>()); //} return(new PsbNumber(d)); case JTokenType.Boolean: return(new PsbBool(token.Value <bool>())); case JTokenType.String: string str = token.Value <string>(); if (str.StartsWith(PsbResCollector.ResourceIdentifier)) { return(new PsbResource(uint.Parse(str.Replace(PsbResCollector.ResourceIdentifier, "")))); } var psbStr = new PsbString(str, (uint)context.Count); if (context.Contains(psbStr)) { return(context.Find(ps => ps.Value == str)); } else { context.Add(psbStr); } return(psbStr); case JTokenType.Array: var array = (JArray)token; var collection = new PsbCollection(array.Count); foreach (var val in array) { var o = ConvertToken(val, context); if (o is IPsbChild c) { c.Parent = collection; } if (o is IPsbSingleton s) { s.Parents.Add(collection); } collection.Add(o); } return(collection); case JTokenType.Object: var obj = (JObject)token; var dictionary = new PsbDictionary(obj.Count); foreach (var val in obj) { var o = ConvertToken(val.Value, context); if (o is IPsbChild c) { c.Parent = dictionary; } if (o is IPsbSingleton s) { s.Parents.Add(dictionary); } dictionary.Add(val.Key, o); } return(dictionary); default: throw new FormatException("Unsupported json element"); } }