예제 #1
0
        public override ArcFile TryOpen(ArcView file)
        {
            var name = Path.GetFileName(file.Name);

            if (!NamePattern.IsMatch(name))
            {
                return(null);
            }
            var match   = NamePattern.Match(name);
            int name_id = 1;
            var num_str = match.Groups["num"].Value;

            if (!string.IsNullOrEmpty(num_str))
            {
                name_id = Int32.Parse(num_str);
            }
            if (name_id < 1)
            {
                return(null);
            }
            ArcView index = file;

            try
            {
                if (name_id != 1)
                {
                    string index_name;
                    if (file.Name.HasExtension(".dat"))
                    {
                        index_name = VFS.ChangeFileName(file.Name, "0001.dat");
                    }
                    else
                    {
                        index_name = VFS.ChangeFileName(file.Name, "data");
                    }
                    if (!VFS.FileExists(index_name))
                    {
                        return(null);
                    }
                    index = VFS.OpenView(index_name);
                }
                var dir = ReadIndex(index, name_id, file.MaxOffset);
                if (null == dir || 0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
            finally
            {
                if (index != file)
                {
                    index.Dispose();
                }
            }
        }
예제 #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".lay"))
            {
                return(null);
            }
            int tile_count  = file.View.ReadInt32(0);
            int coord_count = file.View.ReadInt32(4);

            if (!IsSaneCount(tile_count) || !IsSaneCount(coord_count))
            {
                return(null);
            }
            var base_name = Path.GetFileNameWithoutExtension(file.Name).TrimEnd('_');
            var png_name  = VFS.ChangeFileName(file.Name, base_name + ".png");

            if (!VFS.FileExists(png_name))
            {
                return(null);
            }
            ImageData image;
            var       png_entry = VFS.FindFile(png_name);

            using (var decoder = VFS.OpenImage(png_entry))
                image = decoder.Image;
            using (var input = file.CreateStream())
                using (var index = new BinaryReader(input))
                {
                    input.Position = 8;
                    var dir = new List <Entry> (tile_count);
                    for (int i = 0; i < tile_count; ++i)
                    {
                        uint id    = index.ReadUInt32();
                        int  first = index.ReadInt32();
                        int  count = index.ReadInt32();
                        var  name  = string.Format("{0}#{1:X8}", base_name, id);
                        var  entry = new LayEntry {
                            Name = name, Type = "image", Offset = 0,
                            Id   = id, First = first, Count = count
                        };
                        dir.Add(entry);
                    }
                    var tiles = new List <LayCoord> (coord_count);
                    for (int i = 0; i < coord_count; ++i)
                    {
                        var tile = new LayCoord();
                        tile.TargetX = index.ReadSingle() + 1;
                        tile.TargetY = index.ReadSingle() + 1;
                        tile.SourceX = index.ReadSingle() - 1;
                        tile.SourceY = index.ReadSingle() - 1;
                        tiles.Add(tile);
                    }
                    return(new LayArchive(file, this, dir, image.Bitmap, tiles));
                }
        }
예제 #3
0
파일: ArcDAT.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var pac_name = Path.GetFileNameWithoutExtension(file.Name);
            int pac_num;

            if (!Int32.TryParse(pac_name, out pac_num))
            {
                return(null);
            }
            var hdr_name = string.Format("{0:D3}.dat", pac_num - 1);

            hdr_name = VFS.ChangeFileName(file.Name, hdr_name);
            if (!VFS.FileExists(hdr_name))
            {
                return(null);
            }
            using (var index = VFS.OpenBinaryStream(hdr_name))
            {
                var header = index.ReadHeader(8);
                if (!header.AsciiEqual("\x89HDR"))
                {
                    return(null);
                }
                if (header.ToInt32(4) != count)
                {
                    return(null);
                }
                var dir = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    var name  = index.ReadCString(0x10);
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Size   = index.ReadUInt32();
                    entry.Offset = index.ReadUInt32();
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                return(new ArcFile(file, this, dir));
            }
        }
예제 #4
0
파일: ImageCBM.cs 프로젝트: zxc120/GARbro
        IEnumerable <string> GetPaletteNames(string filename)
        {
            var base_name = Path.GetFileNameWithoutExtension(filename);

            yield return(VFS.ChangeFileName(filename, base_name + ".pal"));

            if (base_name.Length > 3)
            {
                base_name = base_name.Substring(0, 3);
                yield return(VFS.ChangeFileName(filename, base_name + ".pal"));
            }
            yield return(VFS.ChangeFileName(filename, base_name + "_2.pal"));

            yield return(VFS.ChangeFileName(filename, base_name + "_1.pal"));
        }
예제 #5
0
파일: ImageWBM.cs 프로젝트: zxc120/GARbro
        public override ImageData Read(IBinaryStream file, ImageMetaData info)
        {
            file.Position = 12;
            var           pixels       = file.ReadBytes((int)info.Width * (int)info.Height);
            var           format       = PixelFormats.Gray8;
            BitmapPalette palette      = null;
            var           palette_name = VFS.ChangeFileName(file.Name, "data.act");

            if (VFS.FileExists(palette_name))
            {
                using (var pal_file = VFS.OpenStream(palette_name))
                    palette = ReadPalette(pal_file, 0x100, PaletteFormat.Rgb);
                format = PixelFormats.Indexed8;
            }
            return(ImageData.Create(info, format, palette, pixels));
        }
예제 #6
0
        BitmapSource BlendBaseLine(BitmapSource overlay, GdtMetaData meta)
        {
            string base_name = VFS.ChangeFileName(meta.FileName, meta.BaseLine);

            if (!VFS.FileExists(base_name))
            {
                base_name += ".gdt";
                if (!VFS.FileExists(base_name))
                {
                    return(overlay);
                }
            }
            using (var base_file = VFS.OpenBinaryStream(base_name))
            {
                var base_info = ReadMetaData(base_file) as GdtMetaData;
                if (null == base_info)
                {
                    return(overlay);
                }
                var base_image = ReadBitmapSource(base_file, base_info);
                if (base_image.Format.BitsPerPixel < 24)
                {
                    base_image = new FormatConvertedBitmap(base_image, PixelFormats.Bgr32, null, 0);
                }
                var canvas     = new WriteableBitmap(base_image);
                int canvas_bpp = canvas.Format.BitsPerPixel;
                if (canvas_bpp != overlay.Format.BitsPerPixel)
                {
                    overlay = new FormatConvertedBitmap(overlay, canvas.Format, null, 0);
                }
                canvas.Lock();
                unsafe
                {
                    byte *buffer         = (byte *)canvas.BackBuffer;
                    int   canvas_stride  = canvas.BackBufferStride;
                    int   canvas_size    = canvas_stride * canvas.PixelHeight;
                    int   overlay_stride = (overlay.PixelWidth * canvas_bpp + 7) / 8;
                    int   overlay_size   = overlay_stride * overlay.PixelHeight;
                    int   pos            = meta.OffsetY * canvas_stride + meta.OffsetX * canvas_bpp / 8;
                    overlay.CopyPixels(Int32Rect.Empty, (IntPtr)(buffer + pos), canvas_size - pos, canvas_stride);
                }
                var rect = new Int32Rect(meta.OffsetX, meta.OffsetY, overlay.PixelWidth, overlay.PixelHeight);
                canvas.AddDirtyRect(rect);
                canvas.Unlock();
                return(canvas);
            }
        }
예제 #7
0
파일: ImageLSG.cs 프로젝트: x132321/GARbro
        internal BitmapPalette ReadDefaultPalette(string filename)
        {
            var pal_name = Path.ChangeExtension(filename, ".pal");

            if (!VFS.FileExists(pal_name))
            {
                pal_name = VFS.ChangeFileName(filename, DefaultPaletteName);
            }
            if (!VFS.FileExists(pal_name))
            {
                return(null);
            }
            using (var input = VFS.OpenStream(pal_name))
            {
                return(ReadPalette(input, 0x100, PaletteFormat.Rgb));
            }
        }
예제 #8
0
        public override ArcFile TryOpen(ArcView file)
        {
            var name = Path.GetFileName(file.Name);

            if (!NamePattern.IsMatch(name))
            {
                return(null);
            }
            var match   = NamePattern.Match(name);
            int name_id = Int32.Parse(match.Groups[1].Value);

            if (name_id < 1)
            {
                return(null);
            }
            ArcView index = file;

            try
            {
                if (name_id != 1)
                {
                    var index_name = VFS.ChangeFileName(file.Name, "0001.dat");
                    if (!VFS.FileExists(index_name))
                    {
                        return(null);
                    }
                    index = VFS.OpenView(index_name);
                }
                var dir = ReadIndex(index, name_id, file.MaxOffset);
                if (null == dir || 0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
            finally
            {
                if (index != file)
                {
                    index.Dispose();
                }
            }
        }
예제 #9
0
파일: ImageRCT.cs 프로젝트: zxc120/GARbro
        public override ImageData Read(IBinaryStream file, ImageMetaData info)
        {
            var meta   = (RctMetaData)info;
            var pixels = ReadPixelsData(file, meta);

            if (ApplyMask.Get <bool>())
            {
                var mask_name = Path.GetFileNameWithoutExtension(meta.FileName) + "_.rc8";
                mask_name = VFS.ChangeFileName(meta.FileName, mask_name);
                if (VFS.FileExists(mask_name))
                {
                    try
                    {
                        return(ApplyMaskToImage(meta, pixels, mask_name));
                    }
                    catch { /* ignore mask read errors */ }
                }
            }
            return(ImageData.Create(meta, PixelFormats.Bgr24, null, pixels, (int)meta.Width * 3));
        }
예제 #10
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.MaxOffset > uint.MaxValue ||
                !VFS.IsPathEqualsToFileName(file.Name, "ArchPac.dat"))
            {
                return(null);
            }
            foreach (var scheme in KnownSchemes.Values.Where(s => s.IndexOffset < file.MaxOffset).OrderBy(s => s.IndexOffset))
            {
                var dir = ReadIndex(file, scheme.IndexOffset, file.MaxOffset);
                if (dir != null)
                {
                    if (scheme.EventMap != null)
                    {
                        return(new SeraphArchive(file, this, dir, scheme));
                    }
                    else
                    {
                        return(new ArcFile(file, this, dir));
                    }
                }
            }
            var scnpac_name = VFS.ChangeFileName(file.Name, "ScnPac.dat");

            if (!VFS.FileExists(scnpac_name))
            {
                return(null);
            }
            using (var scnpac = VFS.OpenView(scnpac_name))
            {
                uint first_offset = scnpac.View.ReadUInt32(4);
                uint index_offset = scnpac.View.ReadUInt32(first_offset - 4);
                var  dir          = ReadIndex(scnpac, index_offset, file.MaxOffset);
                if (dir != null)
                {
                    return(new ArcFile(file, this, dir));
                }
            }
            return(null);
        }
예제 #11
0
파일: ArcSX.cs 프로젝트: x132321/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            var base_name = Path.GetFileName(file.Name);
            var sx_name   = base_name.Substring(0, 4) + "(00).sx";

            sx_name = VFS.ChangeFileName(file.Name, sx_name);
            if (!VFS.FileExists(sx_name) || file.Name.Equals(sx_name, StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }
            byte[] index_data;
            using (var sx = VFS.OpenView(sx_name))
            {
                if (sx.MaxOffset <= 0x10)
                {
                    return(null);
                }
                if (!sx.View.AsciiEqual(0, "SSXXDEFL"))
                {
                    return(null);
                }
                int key          = Binary.BigEndian(sx.View.ReadInt32(8));
                int length       = (int)(sx.MaxOffset - 0x10);
                var index_packed = sx.View.ReadBytes(0x10, (uint)length);

                long lkey = (long)key + length;
                lkey = key ^ (961 * lkey - 124789) ^ DefaultKey;
                uint key_lo = (uint)lkey;
                uint key_hi = (uint)(lkey >> 32) ^ 0x2E6;
                DecryptData(index_packed, key_lo, key_hi);

                index_data = UnpackZstd(index_packed);
            }
            using (var index = new BinMemoryStream(index_data))
            {
                var reader = new SxIndexDeserializer(index, file.MaxOffset);
                var dir    = reader.Deserialize();
                return(new ArcFile(file, this, dir));
            }
        }
예제 #12
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            var idx_name = VFS.ChangeFileName(file.Name, "index.idx");

            if (!VFS.FileExists(idx_name))
            {
                return(null);
            }
            using (var index = VFS.OpenBinaryStream(idx_name))
            {
                var dir = new List <Entry>();
                while (index.PeekByte() != -1)
                {
                    var name = index.ReadCString(0x34);
                    if (string.IsNullOrEmpty(name))
                    {
                        break;
                    }
                    var entry = Create <Entry> (name);
                    entry.Offset = index.ReadUInt32();
                    entry.Size   = index.ReadUInt32();
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                if (0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
예제 #13
0
파일: ArcDAT.cs 프로젝트: ziyuejun/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".dat") || VFS.IsPathEqualsToFileName(file.Name, "00000000.dat"))
            {
                return(null);
            }
            var index_name = VFS.ChangeFileName(file.Name, "00000000.dat");

            if (!VFS.FileExists(index_name))
            {
                return(null);
            }
            var arc_name = Path.GetFileName(file.Name);

            using (var index = VFS.OpenView(index_name))
            {
                var dir = ReadIndex(index, arc_name, file.MaxOffset);
                if (null == dir)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
예제 #14
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            var arc_name = Path.GetFileName(file.Name);
            var match    = IndexNameRe.Match(arc_name);

            if (!match.Success)
            {
                return(null);
            }
            var base_name = match.Groups[2].Value;

            base_name = VFS.ChangeFileName(file.Name, base_name);
            var index_name = base_name + ".pcg";

            if (!VFS.FileExists(index_name))
            {
                index_name = base_name + ".spf";
                if (!VFS.FileExists(index_name))
                {
                    return(null);
                }
            }
            arc_name = match.Groups[1].Value;
            using (var index = VFS.OpenView(index_name))
            {
                int parts_count = index.View.ReadInt32(0);
                int count       = index.View.ReadInt32(4);
                if (parts_count > 10 || !IsSaneCount(count))
                {
                    return(null);
                }
                int entry_size = (int)(index.MaxOffset - 0x198) / count;
                if (entry_size < 0x30)
                {
                    return(null);
                }
                int first_index = -1, last_index = -1;
                for (int i = 0; i < parts_count; ++i)
                {
                    int name_pos = 8 + i * 0x20;
                    var name     = index.View.ReadString(name_pos, 0x20);
                    if (name == arc_name)
                    {
                        int first_index_pos = 0x148 + i * 4;
                        int last_index_pos  = 0x170 + i * 4;
                        first_index = index.View.ReadInt32(first_index_pos);
                        last_index  = index.View.ReadInt32(last_index_pos);
                        break;
                    }
                }
                if (first_index < 0 || first_index >= last_index || last_index > count)
                {
                    return(null);
                }

                uint name_size    = entry_size >= 0x48 ? 0x40u : 0x20u;
                int  index_offset = 0x198 + entry_size * first_index;
                var  dir          = new List <Entry> (last_index - first_index);
                for (int i = first_index; i < last_index; ++i)
                {
                    var name  = index.View.ReadString(index_offset, name_size);
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Size   = index.View.ReadUInt32(index_offset + name_size);
                    entry.Offset = index.View.ReadUInt32(index_offset + name_size + 4);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += entry_size;
                }
                return(new ArcFile(file, this, dir));
            }
        }
예제 #15
0
파일: ArcCPZ.cs 프로젝트: ziyuejun/GARbro
        ArchiveKey FindArchiveKey(string arc_name)
        {
            // look for "start.ps3" in the same directory as an archive
            var start_name = VFS.ChangeFileName(arc_name, "start.ps3");

            if (!VFS.FileExists(start_name))
            {
                return(null);
            }
            byte[] start_data;
            using (var start = VFS.OpenView(start_name))
            {
                if (!start.View.AsciiEqual(0, "PS2A"))
                {
                    return(null);
                }
                start_data = start.View.ReadBytes(0, (uint)start.MaxOffset);
            }
            arc_name   = Path.GetFileName(arc_name);
            start_data = UnpackPs2(start_data);

            int table_count    = start_data.ToInt32(0x10);
            int strings_offset = 0x30 + table_count * 4 + start_data.ToInt32(0x14);
            int strings_size   = start_data.ToInt32(0x1C);

            if (strings_offset < 0x30 || strings_offset + strings_size > start_data.Length)
            {
                return(null);
            }

            // search strings table for archive name
            int string_pos  = strings_offset;
            int strings_end = strings_offset + strings_size;
            int arc_id      = -1;

            while (string_pos < strings_end)
            {
                int end_pos = Array.IndexOf <byte> (start_data, 0, string_pos);
                if (-1 == end_pos)
                {
                    end_pos = strings_offset + strings_size;
                }
                if (end_pos != string_pos)
                {
                    var text = Encodings.cp932.GetString(start_data, string_pos, end_pos - string_pos);
                    if (VFS.IsPathEqualsToFileName(text, arc_name))
                    {
                        arc_id = string_pos - strings_offset;
                        break;
                    }
                }
                string_pos = end_pos + 1;
            }
            if (-1 == arc_id)
            {
                return(null);
            }

            // search bytecode for a reference to archive name found above
            var id_bytes = new byte[4];

            LittleEndian.Pack(arc_id, id_bytes, 0);
            for (int data_pos = 0x30 + table_count * 4; data_pos + 4 <= strings_offset; ++data_pos)
            {
                if (start_data[data_pos + 0] == id_bytes[0] && start_data[data_pos + 1] == id_bytes[1] &&
                    start_data[data_pos + 2] == id_bytes[2] && start_data[data_pos + 3] == id_bytes[3])
                {
                    if (start_data[data_pos - 0x33] == 2 && start_data[data_pos - 0x32] == 0 &&
                        start_data[data_pos - 0x31] == 1)
                    {
                        return(new ArchiveKey {
                            IndexDirKey = start_data.ToUInt32(data_pos - 0x0C),
                            IndexEntryKey = start_data.ToUInt32(data_pos - 0x18),
                            EntryDataKey1 = start_data.ToUInt32(data_pos - 0x24),
                            EntryDataKey2 = start_data.ToUInt32(data_pos - 0x30),
                        });
                    }
                }
            }
            return(null);
        }
예제 #16
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count) || VFS.IsPathEqualsToFileName(file.Name, "00.mpk"))
            {
                return(null);
            }
            var           list_name = VFS.ChangeFileName(file.Name, "00.mpk");
            List <string> filelist;

            if (VFS.FileExists(list_name))
            {
                using (var s = VFS.OpenStream(list_name))
                    using (var xs = new XoredStream(s, 0xA))
                        using (var reader = new StreamReader(xs, Encodings.cp932))
                        {
                            filelist = new List <string> (count);
                            string filename;
                            while ((filename = reader.ReadLine()) != null)
                            {
                                filelist.Add(filename);
                            }
                        }
            }
            else
            {
                var base_name = Path.GetFileNameWithoutExtension(file.Name);
                filelist = Enumerable.Range(0, count).Select(x => string.Format("{0}#{1:D4}", base_name, x)).ToList();
            }
            bool has_sizes    = file.View.ReadByte(3) != 'P';
            uint index_offset = 8;
            uint record_size  = has_sizes ? 8u : 4u;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = FormatCatalog.Instance.Create <Entry> (filelist[i]);
                entry.Offset = file.View.ReadUInt32(index_offset);
                if (has_sizes)
                {
                    entry.Size = file.View.ReadUInt32(index_offset + 4);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                }
                else if (entry.Offset > file.MaxOffset)
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += record_size;
            }
            if (!has_sizes)
            {
                for (int i = 1; i < count; ++i)
                {
                    dir[i - 1].Size = (uint)(dir[i].Offset - dir[i - 1].Offset);
                }
                dir[dir.Count - 1].Size = (uint)(file.MaxOffset - dir[dir.Count - 1].Offset);
            }
            return(new ArcFile(file, this, dir));
        }