예제 #1
0
        public IarImage(IarArchive iarc, Entry entry)
        {
            int flags = iarc.File.View.ReadUInt16(entry.Offset);
            int bpp;

            switch (flags & 0x3E)
            {
            case 0x02:  bpp = 8; break;

            case 0x1C:  bpp = 24; break;

            case 0x3C:  bpp = 32; break;

            default:    throw new NotSupportedException("Not supported IAR image format");
            }
            var offset = entry.Offset;

            m_info = new IarImageInfo
            {
                Flags        = flags,
                BPP          = bpp,
                Compressed   = iarc.File.View.ReadByte(offset + 3) != 0,
                Width        = iarc.File.View.ReadUInt32(offset + 0x20),
                Height       = iarc.File.View.ReadUInt32(offset + 0x24),
                Stride       = iarc.File.View.ReadInt32(offset + 0x28),
                OffsetX      = iarc.File.View.ReadInt32(offset + 0x18),
                OffsetY      = iarc.File.View.ReadInt32(offset + 0x1C),
                UnpackedSize = iarc.File.View.ReadInt32(offset + 8),
                PaletteSize  = iarc.File.View.ReadUInt32(offset + 0xC),
                PackedSize   = iarc.File.View.ReadInt32(offset + 0x10),
            };
            uint header_size = 1 == iarc.Version ? 0x30u : iarc.Version < 4 ? 0x40u : 0x48u;

            offset += header_size;
            uint input_size = entry.Size - header_size;

            if (m_info.PaletteSize > 0)
            {
                m_palette = new byte[m_info.PaletteSize];
                iarc.File.View.Read(offset, m_palette, 0, m_info.PaletteSize);
                offset     += m_info.PaletteSize;
                input_size -= m_info.PaletteSize;
            }
            m_output = new byte[m_info.UnpackedSize];
            using (var input = iarc.File.CreateStream(offset, input_size))
            {
                if (m_info.Compressed)
                {
                    using (var reader = new IarDecompressor(input))
                        reader.Unpack(m_output);
                }
                else
                {
                    input.Read(m_output, 0, m_output.Length);
                }
            }
        }
예제 #2
0
        IarImage CombineImage(IarImage overlay, IarArchive iarc)
        {
            using (var input = new BinMemoryStream(overlay.Data))
            {
                var dir        = (List <Entry>)iarc.Dir;
                int base_index = input.ReadInt32();
                if (base_index >= dir.Count)
                {
                    throw new InvalidFormatException("Invalid base image index");
                }
                int diff_y     = input.ReadInt32();
                int diff_count = input.ReadInt32();

                var    overlay_info = overlay.Info;
                int    pixel_size   = overlay_info.BPP / 8;
                var    base_image   = new IarImage(iarc, dir[base_index]);
                byte[] output       = base_image.Data;
                if (overlay_info.Height != base_image.Info.Height || overlay_info.Stride != base_image.Info.Stride)
                {
                    int    src_height = (int)Math.Min(overlay_info.Height, base_image.Info.Height);
                    int    src_stride = Math.Min(overlay_info.Stride, base_image.Info.Stride);
                    byte[] src        = base_image.Data;
                    output = new byte[overlay_info.Height * overlay_info.Stride];
                    int dst_pos = 0;
                    if (base_image.Info.OffsetY < overlay_info.OffsetY)
                    {
                        dst_pos += (-base_image.Info.OffsetY + overlay_info.OffsetY) * overlay_info.Stride;
                    }
                    if (base_image.Info.OffsetX < overlay_info.OffsetX)
                    {
                        dst_pos += (-base_image.Info.OffsetX + overlay_info.OffsetX) * pixel_size;
                    }
                    for (int y = 0; y < src_height; ++y)
                    {
                        Buffer.BlockCopy(src, y * base_image.Info.Stride, output, dst_pos, src_stride);
                        dst_pos += overlay_info.Stride;
                    }
                }
                int dst = diff_y * overlay_info.Stride;
                for (int i = 0; i < diff_count; ++i)
                {
                    int chunk_count = input.ReadUInt16();
                    int x           = 0;
                    for (int j = 0; j < chunk_count; ++j)
                    {
                        int skip_count = pixel_size * input.ReadUInt16();
                        int copy_count = pixel_size * input.ReadUInt16();

                        x += skip_count;
                        input.Read(output, dst + x, copy_count);
                        x += copy_count;
                    }
                    dst += overlay_info.Stride;
                }
                return(new IarImage(overlay_info, output, overlay.Palette));
            }
        }
예제 #3
0
        IarImage CombineLayers(IarImage layers, IarArchive iarc)
        {
            layers.Info.Stride = (int)layers.Info.Width * 4;
            layers.Info.BPP    = 32;
            var pixels = new byte[layers.Info.Stride * (int)layers.Info.Height];
            var output = new IarImage(layers.Info, pixels);

            using (var mem = new MemoryStream(layers.Data))
                using (var input = new BinaryReader(mem))
                {
                    int offset_x = 0, offset_y = 0;
                    var dir = (List <Entry>)iarc.Dir;
                    while (input.BaseStream.Position < input.BaseStream.Length)
                    {
                        int cmd = input.ReadByte();
                        switch (cmd)
                        {
                        case 0x21:
                            offset_x += input.ReadInt16();
                            offset_y += input.ReadInt16();
                            break;

                        case 0x00:
                        case 0x20:
                        {
                            int index = input.ReadInt32();
                            if (index < 0 || index >= dir.Count)
                            {
                                throw new InvalidFormatException("Invalid image layer index");
                            }
                            var layer = new IarImage(iarc, dir[index]);
                            layer.Info.OffsetX -= offset_x;
                            layer.Info.OffsetY -= offset_y;
                            if (0x20 == cmd)
                            {
                                output.ApplyMask(layer);
                            }
                            else
                            {
                                output.Blend(layer);
                            }
                        }
                        break;

                        default:
                            Trace.WriteLine(string.Format("Unknown layer type 0x{0:X2}", cmd), "IAR");
                            break;
                        }
                    }
                    return(output);
                }
        }
예제 #4
0
파일: ArcIAR.cs 프로젝트: Casidi/GARbro
        public IarImage(IarArchive iarc, Entry entry)
        {
            int flags = iarc.File.View.ReadUInt16 (entry.Offset);
            int bpp;
            switch (flags & 0x3E)
            {
            case 0x02:  bpp = 8; break;
            case 0x1C:  bpp = 24; break;
            case 0x3C:  bpp = 32; break;
            default:    throw new NotSupportedException ("Not supported IAR image format");
            }
            var offset = entry.Offset;
            m_info = new IarImageInfo
            {
                Flags   = flags,
                BPP     = bpp,
                Compressed = iarc.File.View.ReadByte (offset+3) != 0,
                Width   = iarc.File.View.ReadUInt32 (offset+0x20),
                Height  = iarc.File.View.ReadUInt32 (offset+0x24),
                Stride  = iarc.File.View.ReadInt32 (offset+0x28),
                OffsetX = iarc.File.View.ReadInt32 (offset+0x18),
                OffsetY = iarc.File.View.ReadInt32 (offset+0x1C),
                UnpackedSize = iarc.File.View.ReadInt32 (offset+8),
                PaletteSize = iarc.File.View.ReadUInt32 (offset+0xC),
                PackedSize = iarc.File.View.ReadInt32 (offset+0x10),
            };
            uint header_size = 1 == iarc.Version ? 0x30u : iarc.Version < 4 ? 0x40u : 0x48u;
            offset += header_size;
            uint input_size = entry.Size - header_size;

            if (m_info.PaletteSize > 0)
            {
                m_palette = new byte[m_info.PaletteSize];
                iarc.File.View.Read (offset, m_palette, 0, m_info.PaletteSize);
                offset += m_info.PaletteSize;
                input_size -= m_info.PaletteSize;
            }
            m_output = new byte[m_info.UnpackedSize];
            using (var input = iarc.File.CreateStream (offset, input_size))
            {
                if (m_info.Compressed)
                {
                    using (var reader = new IarDecompressor (input))
                        reader.Unpack (m_output);
                }
                else
                    input.Read (m_output, 0, m_output.Length);
            }
        }
예제 #5
0
파일: ArcIAR.cs 프로젝트: Casidi/GARbro
        IarImage CombineLayers(IarImage layers, IarArchive iarc)
        {
            layers.Info.Stride = (int)layers.Info.Width * 4;
            layers.Info.BPP = 32;
            var pixels = new byte[layers.Info.Stride * (int)layers.Info.Height];
            var output = new IarImage (layers.Info, pixels);
            using (var mem = new MemoryStream (layers.Data))
            using (var input = new BinaryReader (mem))
            {
                int offset_x = 0, offset_y = 0;
                var dir = (List<Entry>)iarc.Dir;
                while (input.BaseStream.Position < input.BaseStream.Length)
                {
                    int cmd = input.ReadByte();
                    switch (cmd)
                    {
                    case 0x21:
                        offset_x += input.ReadInt16();
                        offset_y += input.ReadInt16();
                        break;

                    case 0x00:
                    case 0x20:
                        {
                            int index = input.ReadInt32();
                            if (index < 0 || index >= dir.Count)
                                throw new InvalidFormatException ("Invalid image layer index");
                            var layer = new IarImage (iarc, dir[index]);
                            layer.Info.OffsetX -= offset_x;
                            layer.Info.OffsetY -= offset_y;
                            if (0x20 == cmd)
                                output.ApplyMask (layer);
                            else
                                output.Blend (layer);
                        }
                        break;

                    default:
                        Trace.WriteLine (string.Format ("Unknown layer type 0x{0:X2}", cmd), "IAR");
                        break;
                    }
                }
                return output;
            }
        }
예제 #6
0
파일: ArcIAR.cs 프로젝트: Casidi/GARbro
        IarImage CombineImage(IarImage overlay, IarArchive iarc)
        {
            using (var mem = new MemoryStream (overlay.Data))
            using (var input = new BinaryReader (mem))
            {
                var dir = (List<Entry>)iarc.Dir;
                int base_index = input.ReadInt32();
                if (base_index >= dir.Count)
                    throw new InvalidFormatException ("Invalid base image index");
                int diff_y      = input.ReadInt32();
                int diff_count  = input.ReadInt32();

                var overlay_info = overlay.Info;
                var base_image = new IarImage (iarc, dir[base_index]);
                byte[] output = base_image.Data;
                if (overlay_info.Height != base_image.Info.Height || overlay_info.Stride != base_image.Info.Stride)
                {
                    int src_height = (int)Math.Min (overlay_info.Height, base_image.Info.Height);
                    int src_stride = Math.Min (overlay_info.Stride, base_image.Info.Stride);
                    byte[] src = base_image.Data;
                    output = new byte[overlay_info.Height * overlay_info.Stride];
                    int dst_pos = 0;
                    for (int y = 0; y < src_height; ++y)
                    {
                        Buffer.BlockCopy (src, y * base_image.Info.Stride, output, dst_pos, src_stride);
                        dst_pos += overlay_info.Stride;
                    }
                }
                int pixel_size = overlay_info.BPP / 8;
                int dst = diff_y * overlay_info.Stride;
                for (int i = 0; i < diff_count; ++i)
                {
                    int chunk_count = input.ReadUInt16();
                    int x = 0;
                    for (int j = 0; j < chunk_count; ++j)
                    {
                        int skip_count = pixel_size * input.ReadUInt16();
                        int copy_count = pixel_size * input.ReadUInt16();

                        x += skip_count;
                        input.Read (output, dst+x, copy_count);
                        x += copy_count;
                    }
                    dst += overlay_info.Stride;
                }
                return new IarImage (overlay_info, output, overlay.Palette);
            }
        }