From 5f1687efcd0f8d72683353e22a6440a607d498b9 Mon Sep 17 00:00:00 2001 From: morkt Date: Sun, 15 Jan 2017 01:26:24 +0400 Subject: [PATCH] implemented ARC0 archives and PB00 images. --- ArcFormats/ArcFormats.csproj | 2 + ArcFormats/Mixwill/ArcARC0.cs | 96 ++++++++++++++++++++++++++ ArcFormats/Mixwill/ImagePB00.cs | 115 ++++++++++++++++++++++++++++++++ supported.html | 6 ++ 4 files changed, 219 insertions(+) create mode 100644 ArcFormats/Mixwill/ArcARC0.cs create mode 100644 ArcFormats/Mixwill/ImagePB00.cs diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index 74471b81..65cb9a59 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -104,6 +104,8 @@ + + diff --git a/ArcFormats/Mixwill/ArcARC0.cs b/ArcFormats/Mixwill/ArcARC0.cs new file mode 100644 index 00000000..c3e767af --- /dev/null +++ b/ArcFormats/Mixwill/ArcARC0.cs @@ -0,0 +1,96 @@ +//! \file ArcARC0.cs +//! \date Sat Jan 14 23:23:37 2017 +//! \brief Mixwill soft resource archive. +// +// Copyright (C) 2017 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; + +namespace GameRes.Formats.Mixwill +{ + [Export(typeof(ArchiveFormat))] + public class Arc0Opener : ArchiveFormat + { + public override string Tag { get { return "ARC0"; } } + public override string Description { get { return "Mixwill soft resource archive"; } } + public override uint Signature { get { return 0x30435241; } } // 'ARC0' + public override bool IsHierarchic { get { return false; } } + public override bool CanWrite { get { return false; } } + + public Arc0Opener () + { + Extensions = new string[] { "arc" }; + } + + public override ArcFile TryOpen (ArcView file) + { + int count = file.View.ReadInt32 (0x10004); + if (!IsSaneCount (count)) + return null; + var name_buf = new byte[0x100]; + uint index_offset = 0x10008; + var dir = new List (count); + for (int i = 0; i < count; ++i) + { + if (0x100 != file.View.Read (index_offset, name_buf, 0, 0x100)) + return null; + int n; + for (n = 0; n < 0x100; ++n) + { + name_buf[n] ^= (byte)n; + if (0 == name_buf[n]) + break; + } + if (0 == n) + return null; + index_offset += 0x100; + var name = Encodings.cp932.GetString (name_buf, 0, n); + var entry = FormatCatalog.Instance.Create (name); + entry.Size = file.View.ReadUInt32 (index_offset); + entry.Offset = file.View.ReadUInt32 (index_offset+4); + if (!entry.CheckPlacement (file.MaxOffset)) + return null; + dir.Add (entry); + index_offset += 8; + } + return new ArcFile (file, this, dir); + } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + uint encrypted_size = entry.Size; + if (!entry.Name.EndsWith (".txt", StringComparison.InvariantCultureIgnoreCase) + && encrypted_size > 0x100) + encrypted_size = 0x100; + var prefix = arc.File.View.ReadBytes (entry.Offset, encrypted_size); + for (int i = 0; i < prefix.Length; ++i) + prefix[i] ^= (byte)i; + if (entry.Size == encrypted_size) + return new BinMemoryStream (prefix, entry.Name); + var rest = arc.File.CreateStream (entry.Offset+encrypted_size, entry.Size-encrypted_size); + return new PrefixStream (prefix, rest); + } + } +} diff --git a/ArcFormats/Mixwill/ImagePB00.cs b/ArcFormats/Mixwill/ImagePB00.cs new file mode 100644 index 00000000..28a47795 --- /dev/null +++ b/ArcFormats/Mixwill/ImagePB00.cs @@ -0,0 +1,115 @@ +//! \file ImagePB00.cs +//! \date Sat Jan 14 23:58:54 2017 +//! \brief Mixwill soft image format. +// +// Copyright (C) 2017 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System.ComponentModel.Composition; +using System.IO; +using System.Windows.Media; + +namespace GameRes.Formats.Mixwill +{ + internal class Pb00MetaData :ImageMetaData + { + public readonly int[] ChannelTable = new int[4]; + } + + [Export(typeof(ImageFormat))] + public class Pb00Format : ImageFormat + { + public override string Tag { get { return "PB00"; } } + public override string Description { get { return "Mixwill soft image format"; } } + public override uint Signature { get { return 0x30304250; } } // 'PB00' + + public Pb00Format () + { + Extensions = new string[] { "pb" }; + } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var header = file.ReadHeader (0x20); + var info = new Pb00MetaData + { + Width = header.ToUInt32 (8), + Height = header.ToUInt32 (0xC), + BPP = header.ToInt32 (4) * 8, + }; + for (int i = 0; i < 4; ++i) + info.ChannelTable[i] = header.ToInt32 (0x10 + i * 4); + + return info; + } + + static readonly byte[] RgbOrder = { 2, 1, 0, 3 }; + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var meta = (Pb00MetaData)info; + int channels = info.BPP/8; + var pixels = new byte[info.Width * info.Height * channels]; + long channel_pos = 0x20; + for (int i = 0; i < channels; ++i) + { + file.Position = channel_pos; + int length = meta.ChannelTable[i]; + channel_pos += length; + int dst = RgbOrder[i]; + for (int j = 0; j < length; ++j) + { + int b = file.ReadInt8(); + if (b >= 0) + { + for (int count = b + 1; count > 0; --count) + { + pixels[dst] = file.ReadUInt8(); + dst += channels; + ++j; + } + } + else + { + byte c = file.ReadUInt8(); + for (int count = 1 - b; count > 0; --count) + { + pixels[dst] = c; + dst += channels; + } + ++j; + } + } + } + PixelFormat format; + if (4 == channels) + format = PixelFormats.Bgra32; + else + format = PixelFormats.Bgr24; + return ImageData.Create (info, format, null, pixels); + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("Pb00Format.Write not implemented"); + } + } +} diff --git a/supported.html b/supported.html index e0ed2069..ed7498bb 100644 --- a/supported.html +++ b/supported.html @@ -276,6 +276,7 @@ Kurenai no Tsuki
LOVELY x CATION
Mayoeru Futari to Sekai no Subete
Mahoutsukai no Yoru
+Maitetsu
Mizukoi
Mizu no Miyako no Patisserie
Nakadashi Hara Maid series
@@ -703,6 +704,7 @@ Yuukyou Gangu 2
Asa no Konai Yoru ni Dakarete -Eternal Night-
Guren ni Somaru Gin no Rozario
Konata yori Kanata made
+Niji no Kanata ni
Thirua Panic
*.mcgMCG 2.00No @@ -1317,6 +1319,10 @@ Angelium -Tokimeki Love God-
Teri ☆ Mix
*.elgELGNo +*.arcARC0NoMixwill soft +Onepapa ~Onegai PaPa!~
+ +*.pbPB00No

1 Non-encrypted only