예제 #1
0
파일: ImageFCB.cs 프로젝트: zxc120/GARbro
        public override ImageData Read(IBinaryStream stream, ImageMetaData info)
        {
            var meta = (FcbMetaData)info;

            byte[] input;
            if (1 == meta.Method)
            {
                stream.Position = 0x14;
                int unpacked_size = Binary.BigEndian(stream.ReadInt32());
                stream.ReadInt32(); // packed_size
                input = new byte[unpacked_size];
                using (var z = new ZLibStream(stream.AsStream, CompressionMode.Decompress, true))
                    if (unpacked_size != z.Read(input, 0, unpacked_size))
                    {
                        throw new EndOfStreamException();
                    }
            }
            else if (0 == meta.Method)
            {
                stream.Position = 0x10;
                using (var tz = new TzCompression(stream.AsStream))
                    input = tz.Unpack();
            }
            else
            {
                throw new InvalidFormatException();
            }
            var pixels = Unpack(input, info);

            return(ImageData.Create(info, PixelFormats.Bgra32, null, pixels));
        }
예제 #2
0
파일: ArcARC4.cs 프로젝트: zxc120/GARbro
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var    xent = (Arc4Entry)entry;
            Stream input;

            if (1 == xent.Segments.Count)
            {
                input = arc.File.CreateStream(entry.Offset, entry.Size);
            }
            else
            {
                input = new Arc4Stream(arc.File, xent);
            }
            if (!xent.IsPacked)
            {
                return(input);
            }
            using (input)
                using (var tz = new TzCompression(input))
                    return(new BinMemoryStream(tz.Unpack(), entry.Name));
        }
예제 #3
0
파일: ArcARC4.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (0x010000 != file.View.ReadUInt32(4))
            {
                return(null);
            }
            int count = file.View.ReadInt32(0x10);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_length  = file.View.ReadUInt32(8);
            uint alignment     = file.View.ReadUInt32(0xC);
            int  index_offset  = file.View.ReadInt32(0x14);
            int  names_offset  = file.View.ReadInt32(0x1C) - index_offset;
            int  segment_table = file.View.ReadInt32(0x24) - index_offset;
            uint base_offset   = file.View.ReadUInt32(0x2C);

            if (0 == alignment || index_offset <= 0 || names_offset <= 0 || segment_table <= 0)
            {
                return(null);
            }
            if (!file.View.AsciiEqual(index_offset, "tZ"))
            {
                return(null);
            }
            byte[] index;
            using (var packed = file.CreateStream(index_offset, index_length))
                using (var tz = new TzCompression(packed))
                    index = tz.Unpack();

            int current_offset = 0;
            var dir            = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                int name_pos    = ReadInt24(index, current_offset) * 2;
                int name_length = index[current_offset + 3];
                int chunk_count = index[current_offset + 4];
                int offset      = ReadInt24(index, current_offset + 5);
                var name        = Binary.GetCString(index, names_offset + name_pos, name_length);
                var entry       = FormatCatalog.Instance.Create <Arc4Entry> (name);
                entry.Segments = new List <long> (chunk_count);
                if (chunk_count > 1)
                {
                    int segment_pos = segment_table + 3 * offset;
                    for (int j = 0; j < chunk_count; ++j)
                    {
                        entry.Segments.Add(ReadInt24(index, segment_pos) + base_offset);
                        segment_pos += 3;
                    }
                }
                else
                {
                    entry.Segments.Add(offset + base_offset);
                }

                for (int j = 0; j < chunk_count; ++j)
                {
                    entry.Segments[j] *= alignment;
                }
                dir.Add(entry);
                current_offset += 8;
            }
            foreach (Arc4Entry entry in dir)
            {
                uint size = 0;
                foreach (var segment in entry.Segments)
                {
                    size += Binary.BigEndian(file.View.ReadUInt32(segment + 4));
                }
                entry.Offset   = entry.Segments[0] + 0x10;
                entry.Size     = size;
                entry.IsPacked = file.View.AsciiEqual(entry.Offset, "tZ");
                if (entry.IsPacked)
                {
                    entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 2);
                }
                else
                {
                    entry.UnpackedSize = size;
                }
            }
            return(new ArcFile(file, this, dir));
        }