コード例 #1
0
 bool ReadFromStream(Stream input, int name_length)
 {
     m_dir.Clear();
     using (var index = new ArcView.Reader(input))
     {
         for (int i = 0; i < m_count; ++i)
         {
             if (name_length != index.Read(m_name_buffer, 0, name_length))
             {
                 return(false);
             }
             var name = Binary.GetCString(m_name_buffer, 0, name_length);
             if (string.IsNullOrWhiteSpace(name))
             {
                 return(false);
             }
             var entry = FormatCatalog.Instance.Create <PackedEntry> (name);
             entry.Offset       = index.ReadUInt32();
             entry.UnpackedSize = index.ReadUInt32();
             entry.Size         = index.ReadUInt32();
             if (!entry.CheckPlacement(m_file.MaxOffset))
             {
                 return(false);
             }
             entry.IsPacked = m_pack_type != 0 && (m_pack_type != 4 || entry.Size != entry.UnpackedSize);
             m_dir.Add(entry);
         }
         return(true);
     }
 }
コード例 #2
0
ファイル: ArcADS.cs プロジェクト: zxc120/GARbro
 List <Entry> ReadIndex(Stream arc, byte[] key, string arc_name)
 {
     arc.Position = 8;
     using (var reader = new ArcView.Reader(arc))
     {
         int count = reader.ReadInt32();
         if (!IsSaneCount(count))
         {
             return(null);
         }
         uint base_offset = reader.ReadUInt32();
         uint index_size  = 4u * (uint)count;
         var  max_offset  = arc.Length;
         if (base_offset >= max_offset || base_offset < (0x10 + index_size))
         {
             return(null);
         }
         var index = new List <uint> (count);
         for (int i = 0; i < count; ++i)
         {
             uint offset = reader.ReadUInt32();
             if (offset != 0xffffffff)
             {
                 if (offset >= max_offset - base_offset)
                 {
                     return(null);
                 }
                 index.Add(base_offset + offset);
             }
         }
         var name_buffer = new byte[0x20];
         var dir         = new List <Entry> (index.Count);
         for (int i = 0; i < index.Count; ++i)
         {
             long offset = index[i];
             reader.BaseStream.Position = offset;
             reader.Read(name_buffer, 0, 0x20);
             string name = Binary.GetCString(name_buffer, 0, 0x20);
             Entry  entry;
             if (0 == name.Length)
             {
                 entry = new Entry {
                     Name = string.Format("{0}#{1:D5}", arc_name, i), Type = "image"
                 }
             }
             ;
             else
             {
                 entry = FormatCatalog.Instance.Create <Entry> (name);
             }
             entry.Offset = offset + 0x24;
             entry.Size   = reader.ReadUInt32();
             dir.Add(entry);
         }
         return(dir);
     }
 }
コード例 #3
0
ファイル: ImageAG.cs プロジェクト: tenyuhuang/GARbro
 public AgReader(Stream stream, ImageMetaData info)
 {
     m_width         = (int)info.Width;
     m_height        = (int)info.Height;
     stream.Position = 0x0c;
     using (var input = new ArcView.Reader(stream))
     {
         uint offset1 = input.ReadUInt32();
         int  size1   = input.ReadInt32();
         uint offset2 = input.ReadUInt32();
         int  size2   = input.ReadInt32();
         uint offset3 = input.ReadUInt32();
         int  size3   = input.ReadInt32();
         uint offset4 = input.ReadUInt32();
         int  size4   = input.ReadInt32();
         uint offset5 = input.ReadUInt32();
         int  size5   = input.ReadInt32();
         uint offset6 = input.ReadUInt32();
         int  size6   = input.ReadInt32();
         input.Read(m_first, 0, 3);
         if (size1 != 0)
         {
             in1 = ReadSection(stream, offset1, size1);
         }
         if (size2 != 0)
         {
             in2 = ReadSection(stream, offset2, size2);
         }
         if (size3 != 0)
         {
             in3 = ReadSection(stream, offset3, size3);
         }
         if (size4 != 0)
         {
             in4 = ReadSection(stream, offset4, size4);
         }
         if (size5 != 0)
         {
             in5 = ReadSection(stream, offset5, size5);
         }
         if (size6 != 0)
         {
             input.BaseStream.Position = offset6;
             m_alpha = new byte[m_height * m_width];
             RleDecode(input, m_alpha);
             Format       = PixelFormats.Bgra32;
             m_pixel_size = 4;
         }
         else
         {
             Format       = PixelFormats.Bgr24;
             m_pixel_size = 3;
         }
         m_output = new byte[m_width * m_height * m_pixel_size];
     }
 }
コード例 #4
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(8);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint base_offset = file.View.ReadUInt32(0xC);

            if (base_offset <= 0x18 || base_offset >= file.MaxOffset)
            {
                return(null);
            }
            uint packed_size = file.View.ReadUInt32(0x10);
            int  index_size  = file.View.ReadInt32(0x14);

            if (packed_size > file.MaxOffset || index_size / IndexEntrySize != count)
            {
                return(null);
            }
            var name_buffer = new byte[30];

            using (var packed = file.CreateStream(0x18, packed_size))
                using (var lzss = new LzssStream(packed))
                    using (var index = new ArcView.Reader(lzss))
                    {
                        var dir = new List <Entry> (count);
                        for (int i = 0; i < count; ++i)
                        {
                            if (name_buffer.Length != index.Read(name_buffer, 0, name_buffer.Length))
                            {
                                return(null);
                            }
                            var name  = Binary.GetCString(name_buffer, 0, name_buffer.Length);
                            var entry = FormatCatalog.Instance.Create <Entry> (name);
                            if (name.EndsWith(".acd", StringComparison.InvariantCultureIgnoreCase))
                            {
                                entry.Type = "script";
                            }
                            entry.Offset = index.ReadUInt32() + base_offset;
                            entry.Size   = index.ReadUInt32();
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                        return(new ArcFile(file, this, dir));
                    }
        }
コード例 #5
0
 Stream Unpack(Stream input)
 {
     using (var reader = new ArcView.Reader(input))
     {
         var output = new MemoryStream();
         var buffer = new byte[0x10000];
         for (;;)
         {
             int ctl = input.ReadByte();
             if (-1 == ctl || 0xFF == ctl)
             {
                 break;
             }
             int count = reader.ReadInt32();
             if (3 == ctl)
             {
                 byte b = reader.ReadByte();
                 for (int i = 0; i < count; ++i)
                 {
                     output.WriteByte(b);
                 }
             }
             else
             {
                 while (count > 0)
                 {
                     int chunk = Math.Min(count, buffer.Length);
                     int read  = reader.Read(buffer, 0, chunk);
                     output.Write(buffer, 0, read);
                     count -= chunk;
                 }
             }
         }
         output.Position = 0;
         return(output);
     }
 }
コード例 #6
0
ファイル: ImageTLG.cs プロジェクト: tenyuhuang/GARbro
        ImageData ReadV5(Stream stream, TlgMetaData info)
        {
            using (var src = new ArcView.Reader(stream))
            {
                int width       = (int)info.Width;
                int height      = (int)info.Height;
                int colors      = info.BPP / 8;
                int blockheight = src.ReadInt32();
                int blockcount  = (height - 1) / blockheight + 1;

                // skip block size section
                src.BaseStream.Seek(blockcount * 4, SeekOrigin.Current);

                int stride     = width * 4;
                var image_bits = new byte[height * stride];
                var text       = new byte[4096];
                for (int i = 0; i < 4096; ++i)
                {
                    text[i] = 0;
                }

                var       inbuf  = new byte[blockheight * width + 10];
                byte [][] outbuf = new byte[4][];
                for (int i = 0; i < colors; i++)
                {
                    outbuf[i] = new byte[blockheight * width + 10];
                }

                int z        = 0;
                int prevline = -1;
                for (int y_blk = 0; y_blk < height; y_blk += blockheight)
                {
                    // read file and decompress
                    for (int c = 0; c < colors; c++)
                    {
                        byte mark = src.ReadByte();
                        int  size;
                        size = src.ReadInt32();
                        if (mark == 0)
                        {
                            // modified LZSS compressed data
                            if (size != src.Read(inbuf, 0, size))
                            {
                                return(null);
                            }
                            z = TVPTLG5DecompressSlide(outbuf[c], inbuf, size, text, z);
                        }
                        else
                        {
                            // raw data
                            src.Read(outbuf[c], 0, size);
                        }
                    }

                    // compose colors and store
                    int y_lim = y_blk + blockheight;
                    if (y_lim > height)
                    {
                        y_lim = height;
                    }
                    int outbuf_pos = 0;
                    for (int y = y_blk; y < y_lim; y++)
                    {
                        int current     = y * stride;
                        int current_org = current;
                        if (prevline >= 0)
                        {
                            // not first line
                            switch (colors)
                            {
                            case 3:
                                TVPTLG5ComposeColors3To4(image_bits, current, prevline,
                                                         outbuf, outbuf_pos, width);
                                break;

                            case 4:
                                TVPTLG5ComposeColors4To4(image_bits, current, prevline,
                                                         outbuf, outbuf_pos, width);
                                break;
                            }
                        }
                        else
                        {
                            // first line
                            switch (colors)
                            {
                            case 3:
                                for (int pr = 0, pg = 0, pb = 0, x = 0;
                                     x < width; x++)
                                {
                                    int b = outbuf[0][outbuf_pos + x];
                                    int g = outbuf[1][outbuf_pos + x];
                                    int r = outbuf[2][outbuf_pos + x];
                                    b += g; r += g;
                                    image_bits[current++] = (byte)(pb += b);
                                    image_bits[current++] = (byte)(pg += g);
                                    image_bits[current++] = (byte)(pr += r);
                                    image_bits[current++] = 0xff;
                                }
                                break;

                            case 4:
                                for (int pr = 0, pg = 0, pb = 0, pa = 0, x = 0;
                                     x < width; x++)
                                {
                                    int b = outbuf[0][outbuf_pos + x];
                                    int g = outbuf[1][outbuf_pos + x];
                                    int r = outbuf[2][outbuf_pos + x];
                                    int a = outbuf[3][outbuf_pos + x];
                                    b += g; r += g;
                                    image_bits[current++] = (byte)(pb += b);
                                    image_bits[current++] = (byte)(pg += g);
                                    image_bits[current++] = (byte)(pr += r);
                                    image_bits[current++] = (byte)(pa += a);
                                }
                                break;
                            }
                        }
                        outbuf_pos += width;
                        prevline    = current_org;
                    }
                }
                PixelFormat format = 4 == colors ? PixelFormats.Bgra32 : PixelFormats.Bgr32;
                return(ImageData.Create(info, format, null, image_bits, stride));
            }
        }
コード例 #7
0
ファイル: ImageTLG.cs プロジェクト: tenyuhuang/GARbro
        ImageData ReadV6(Stream stream, TlgMetaData info)
        {
            using (var src = new ArcView.Reader(stream))
            {
                int width          = (int)info.Width;
                int height         = (int)info.Height;
                int colors         = info.BPP / 8;
                int max_bit_length = src.ReadInt32();

                int x_block_count = ((width - 1) / TVP_TLG6_W_BLOCK_SIZE) + 1;
                int y_block_count = ((height - 1) / TVP_TLG6_H_BLOCK_SIZE) + 1;
                int main_count    = width / TVP_TLG6_W_BLOCK_SIZE;
                int fraction      = width - main_count * TVP_TLG6_W_BLOCK_SIZE;

                var image_bits   = new uint[height * width];
                var bit_pool     = new byte[max_bit_length / 8 + 5];
                var pixelbuf     = new uint[width * TVP_TLG6_H_BLOCK_SIZE + 1];
                var filter_types = new byte[x_block_count * y_block_count];
                var zeroline     = new uint[width];
                var LZSS_text    = new byte[4096];

                // initialize zero line (virtual y=-1 line)
                uint zerocolor = 3 == colors ? 0xff000000 : 0x00000000;
                for (var i = 0; i < width; ++i)
                {
                    zeroline[i] = zerocolor;
                }

                uint[] prevline       = zeroline;
                int    prevline_index = 0;

                // initialize LZSS text (used by chroma filter type codes)
                int p = 0;
                for (uint i = 0; i < 32 * 0x01010101; i += 0x01010101)
                {
                    for (uint j = 0; j < 16 * 0x01010101; j += 0x01010101)
                    {
                        LZSS_text[p++] = (byte)(i & 0xff);
                        LZSS_text[p++] = (byte)(i >> 8 & 0xff);
                        LZSS_text[p++] = (byte)(i >> 16 & 0xff);
                        LZSS_text[p++] = (byte)(i >> 24 & 0xff);
                        LZSS_text[p++] = (byte)(j & 0xff);
                        LZSS_text[p++] = (byte)(j >> 8 & 0xff);
                        LZSS_text[p++] = (byte)(j >> 16 & 0xff);
                        LZSS_text[p++] = (byte)(j >> 24 & 0xff);
                    }
                }
                // read chroma filter types.
                // chroma filter types are compressed via LZSS as used by TLG5.
                {
                    int    inbuf_size = src.ReadInt32();
                    byte[] inbuf      = src.ReadBytes(inbuf_size);
                    if (inbuf_size != inbuf.Length)
                    {
                        return(null);
                    }
                    TVPTLG5DecompressSlide(filter_types, inbuf, inbuf_size, LZSS_text, 0);
                }

                // for each horizontal block group ...
                for (int y = 0; y < height; y += TVP_TLG6_H_BLOCK_SIZE)
                {
                    int ylim = y + TVP_TLG6_H_BLOCK_SIZE;
                    if (ylim >= height)
                    {
                        ylim = height;
                    }

                    int pixel_count = (ylim - y) * width;

                    // decode values
                    for (int c = 0; c < colors; c++)
                    {
                        // read bit length
                        int bit_length = src.ReadInt32();

                        // get compress method
                        int method = (bit_length >> 30) & 3;
                        bit_length &= 0x3fffffff;

                        // compute byte length
                        int byte_length = bit_length / 8;
                        if (0 != (bit_length % 8))
                        {
                            byte_length++;
                        }

                        // read source from input
                        src.Read(bit_pool, 0, byte_length);

                        // decode values
                        // two most significant bits of bitlength are
                        // entropy coding method;
                        // 00 means Golomb method,
                        // 01 means Gamma method (not yet suppoted),
                        // 10 means modified LZSS method (not yet supported),
                        // 11 means raw (uncompressed) data (not yet supported).

                        switch (method)
                        {
                        case 0:
                            if (c == 0 && colors != 1)
                            {
                                TVPTLG6DecodeGolombValuesForFirst(pixelbuf, pixel_count, bit_pool);
                            }
                            else
                            {
                                TVPTLG6DecodeGolombValues(pixelbuf, c * 8, pixel_count, bit_pool);
                            }
                            break;

                        default:
                            throw new InvalidFormatException("Unsupported entropy coding method");
                        }
                    }

                    // for each line
                    int ft        = (y / TVP_TLG6_H_BLOCK_SIZE) * x_block_count; // within filter_types
                    int skipbytes = (ylim - y) * TVP_TLG6_W_BLOCK_SIZE;

                    for (int yy = y; yy < ylim; yy++)
                    {
                        int curline = yy * width;

                        int dir     = (yy & 1) ^ 1;
                        int oddskip = ((ylim - yy - 1) - (yy - y));
                        if (0 != main_count)
                        {
                            int start =
                                ((width < TVP_TLG6_W_BLOCK_SIZE) ? width : TVP_TLG6_W_BLOCK_SIZE) *
                                (yy - y);
                            TVPTLG6DecodeLineGeneric(
                                prevline, prevline_index,
                                image_bits, curline,
                                width, 0, main_count,
                                filter_types, ft,
                                skipbytes,
                                pixelbuf, start,
                                zerocolor, oddskip, dir);
                        }

                        if (main_count != x_block_count)
                        {
                            int ww = fraction;
                            if (ww > TVP_TLG6_W_BLOCK_SIZE)
                            {
                                ww = TVP_TLG6_W_BLOCK_SIZE;
                            }
                            int start = ww * (yy - y);
                            TVPTLG6DecodeLineGeneric(
                                prevline, prevline_index,
                                image_bits, curline,
                                width, main_count, x_block_count,
                                filter_types, ft,
                                skipbytes,
                                pixelbuf, start,
                                zerocolor, oddskip, dir);
                        }
                        prevline       = image_bits;
                        prevline_index = curline;
//                        Array.Copy (image_bits, curline, prevline, 0, width);
                    }
                }
                unsafe
                {
                    fixed(void *data = image_bits)
                    {
                        int         stride = width * 4;
                        PixelFormat format = 32 == info.BPP ? PixelFormats.Bgra32 : PixelFormats.Bgr32;
                        var         bitmap = BitmapSource.Create(width, height, ImageData.DefaultDpiX, ImageData.DefaultDpiY,
                                                                 format, null, (IntPtr)data, height * stride, stride);

                        bitmap.Freeze();
                        return(new ImageData(bitmap, info));
                    }
                }
            }
        }