예제 #1
0
        public override ImageData Read(IBinaryStream stream, ImageMetaData info)
        {
            var meta = (HizMetaData)info;

            var pixels = new byte[meta.UnpackedSize];

            stream.Position = meta.DataOffset;
            using (var lzss = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
            {
                var channel = new byte[info.Width * info.Height];
                for (int p = 0; p < 4; ++p)
                {
                    if (channel.Length != lzss.Read(channel, 0, channel.Length))
                    {
                        throw new InvalidFormatException("Unexpected end of file");
                    }
                    int src = 0;
                    for (int i = p; i < pixels.Length; i += 4)
                    {
                        pixels[i] = channel[src++];
                    }
                }
                return(ImageData.Create(info, PixelFormats.Bgra32, null, pixels));
            }
        }
예제 #2
0
파일: ImageCBF.cs 프로젝트: zxc120/GARbro
        void UnpackV1()
        {
            m_input.Position = 0x18;
            using (var lzss = new LzssStream(m_input.AsStream, LzssMode.Decompress, true))
                lzss.Read(m_output, 0, m_output.Length);
            for (int i = 3; i < m_output.Length; ++i)
            {
                m_output[i] += m_output[i - 3];
            }
            var pixels  = new byte[m_output.Length];
            int src     = 0;
            var z_order = GetZigzagBlock();

            for (int y = 0; y < m_height; y += 8)
            {
                for (int x = 0; x < m_stride; x += 24)
                {
                    int dst = x + y * m_stride;
                    for (int i = 0; i < 64; ++i)
                    {
                        int pos = z_order[i];
                        pixels[dst + pos++] = m_output[src++];
                        pixels[dst + pos++] = m_output[src++];
                        pixels[dst + pos++] = m_output[src++];
                    }
                }
            }
            m_output = pixels;
        }
예제 #3
0
 public override ImageMetaData ReadMetaData(IBinaryStream file)
 {
     using (var lzs = new LzssStream(file.AsStream, LzssMode.Decompress, true))
     {
         if (lzs.ReadByte() != 'B' || lzs.ReadByte() != 'M')
         {
             return(null);
         }
         var bmp = new byte[0x26];
         if (0x24 != lzs.Read(bmp, 2, 0x24))
         {
             return(null);
         }
         int file_size  = LittleEndian.ToInt32(bmp, 2);
         int width      = LittleEndian.ToInt32(bmp, 0x12);
         int height     = LittleEndian.ToInt32(bmp, 0x16);
         int bpp        = LittleEndian.ToInt16(bmp, 0x1C);
         int image_size = LittleEndian.ToInt32(bmp, 0x22);
         if (0 == image_size)
         {
             image_size = width * height * (bpp / 8);
         }
         return(new GrMetaData
         {
             Width = (uint)width,
             Height = (uint)height,
             BPP = bpp,
             UnpackedSize = 24 == bpp ? file_size : (image_size + 0x36),
         });
     }
 }
예제 #4
0
파일: ImageMD.cs 프로젝트: zxc120/GARbro
        IBinaryStream OpenBitmap(IBinaryStream input)
        {
            input.Position = 0xA;
            var stream = new LzssStream(input.AsStream, LzssMode.Decompress, true);

            return(new BinaryStream(stream, input.Name));
        }
예제 #5
0
        public ImageData Unpack()
        {
            Stream input = new StreamRegion(m_input.AsStream, 0x18, m_info.PackedLength, true);

            if (m_info.IsEncrypted)
            {
                input = new InputCryptoStream(input, new SjTransform(m_info.Key));
            }
            using (input = new LzssStream(input))
            {
                var header = new byte[0x28];
                input.Read(header, 0, header.Length);
                if (8 == m_info.BPP)
                {
                    Palette = ImageFormat.ReadPalette(input);
                }
                input.Read(m_output, 0, m_output.Length);
            }
            if (m_info.AlphaLength > 0 && m_info.BPP == 8)
            {
                m_input.Position = 0x18 + m_info.PackedLength;
                var alpha = new byte[m_info.AlphaLength];
                using (var lzss = new LzssStream(m_input.AsStream, LzssMode.Decompress, true))
                    lzss.Read(alpha, 0, alpha.Length);
                return(ApplyAlpha(alpha));
            }
            return(ImageData.CreateFlipped(m_info, Format, Palette, m_output, Stride));
        }
예제 #6
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var pent = entry as PackedEntry;

            if (null == pent)
            {
                return(base.OpenEntry(arc, entry));
            }
            if (!pent.IsPacked)
            {
                if (!arc.File.View.AsciiEqual(entry.Offset, "LZS\0"))
                {
                    return(base.OpenEntry(arc, entry));
                }
                pent.IsPacked     = true;
                pent.UnpackedSize = arc.File.View.ReadUInt32(entry.Offset + 4);
            }
            var  input        = arc.File.CreateStream(entry.Offset + 8, entry.Size - 8);
            bool embedded_lzs = (input.Signature & ~0xF0u) == 0x535A4C0F; // 'LZS'
            var  lzs          = new LzssStream(input);

            if (embedded_lzs)
            {
                var header = new byte[8];
                lzs.Read(header, 0, 8);
                pent.UnpackedSize = header.ToUInt32(4);
                lzs = new LzssStream(lzs);
            }
            return(lzs);
        }
예제 #7
0
        public override ImageData Read(IBinaryStream stream, ImageMetaData info)
        {
            int stride = (int)info.Width * 3;
            var pixels = new byte[stride * (int)info.Height];

            stream.Position = 0x24;
            using (var lz = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
            {
                if (pixels.Length != lz.Read(pixels, 0, pixels.Length))
                {
                    throw new InvalidFormatException();
                }
            }
            int src = 0;

            for (int i = 3; i < stride; ++i)
            {
                pixels[i] += pixels[src++];
            }
            src = 0;
            for (int i = stride; i < pixels.Length; ++i)
            {
                pixels[i] += pixels[src++];
            }
            var meta = (MagMetaData)info;

            if (0 == meta.AlphaOffset)
            {
                return(ImageData.CreateFlipped(info, PixelFormats.Bgr24, null, pixels, stride));
            }

            stream.Position = 0x24 + meta.AlphaOffset;
            var alpha = new byte[meta.BackWidth * meta.BackHeight];

            using (var lz = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
            {
                if (alpha.Length != lz.Read(alpha, 0, alpha.Length))
                {
                    throw new InvalidFormatException();
                }
            }
            int img_stride = (int)info.Width * 4;
            var img        = new byte[img_stride * (int)info.Height];
            int dst        = 0;
            int alpha_y    = meta.BackHeight - (meta.OffsetY + (int)meta.Height);

            for (int y = (int)meta.Height - 1; y >= 0; --y)
            {
                src = stride * y;
                int src_alpha = meta.BackWidth * (alpha_y + y) + meta.OffsetX;
                for (int i = 0; i < img_stride; i += 4)
                {
                    img[dst++] = pixels[src++];
                    img[dst++] = pixels[src++];
                    img[dst++] = pixels[src++];
                    img[dst++] = alpha[src_alpha++];
                }
            }
            return(ImageData.Create(info, PixelFormats.Bgra32, null, img, img_stride));
        }
예제 #8
0
            bool ReadV1(Stream input)
            {
                // NOTE CryptoStream will close an input stream
                using (var xored = new CryptoStream(input, new NotTransform(), CryptoStreamMode.Read))
                    using (var lzss = new LzssStream(xored))
                        lzss.Read(m_index, 0, m_index.Length);

                int index_offset = Array.IndexOf(m_index, (byte)0);

                if (-1 == index_offset || 0 == index_offset)
                {
                    return(false);
                }
                Password = m_index.Take(index_offset++).ToArray();
                long base_offset = 0x20 + m_packed_size;

                for (int i = 0; i < m_count; ++i)
                {
                    var entry = new PackedEntry();
                    entry.Offset       = LittleEndian.ToUInt32(m_index, index_offset) + base_offset;
                    entry.Size         = LittleEndian.ToUInt32(m_index, index_offset + 4);
                    entry.UnpackedSize = LittleEndian.ToUInt32(m_index, index_offset + 8);
                    entry.IsPacked     = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement(m_file.MaxOffset))
                    {
                        return(false);
                    }
                    int name_len = LittleEndian.ToInt32(m_index, index_offset + 0xC);
                    entry.Name = Encodings.cp932.GetString(m_index, index_offset + 0x18, name_len);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                    m_dir.Value.Add(entry);
                    index_offset += 0x18 + name_len;
                }
                return(true);
            }
예제 #9
0
        public Stream UnpackStream()
        {
            var lzss = new LzssStream(new MemoryStream(m_input));

            lzss.Config.FrameFill = 0x20;
            return(lzss);
        }
예제 #10
0
        // Exile ~Blood Royal 2~      : flipped == true
        // Gakuen ~Nerawareta Chitai~ : flipped == false
        private ImageData ReadV3(bool flipped)
        {
            using (var lzs = new LzssStream(m_input, LzssMode.Decompress, true))
            {
                if (8 == m_info.BPP)
                {
                    var palette_data = new byte[0x400];
                    if (palette_data.Length != lzs.Read(palette_data, 0, palette_data.Length))
                    {
                        throw new InvalidFormatException("Unexpected end of file");
                    }
                    SetPalette(palette_data);
                }
                m_image_data = new byte[m_stride * (int)m_info.Height];
                if (m_image_data.Length != lzs.Read(m_image_data, 0, m_image_data.Length))
                {
                    throw new InvalidFormatException();
                }

                if (flipped)
                {
                    return(ImageData.CreateFlipped(m_info, Format, Palette, m_image_data, m_stride));
                }
                else
                {
                    return(ImageData.Create(m_info, Format, Palette, m_image_data, m_stride));
                }
            }
        }
예제 #11
0
파일: ArcSDT.cs 프로젝트: zxc120/GARbro
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var snd_ent = (SdtEntry)entry;
            var header  = arc.File.View.ReadBytes(entry.Offset, snd_ent.HeaderSize);

            using (var mem = new MemoryStream((int)snd_ent.HeaderSize + 0x18))
                using (var fmt = new BinaryWriter(mem))
                {
                    uint total_size = snd_ent.Size + 0x18;
                    fmt.Write(AudioFormat.Wav.Signature);
                    fmt.Write(total_size);
                    fmt.Write(0x45564157); // 'WAVE'
                    fmt.Write(0x20746d66); // 'fmt '
                    fmt.Write(header.Length);
                    fmt.Write(header, 0, header.Length);
                    fmt.Write(0x61746164); // 'data'
                    fmt.Write(snd_ent.UnpackedSize);
                    fmt.Flush();
                    header = mem.ToArray();
                }
            Stream input = arc.File.CreateStream(entry.Offset + snd_ent.HeaderSize, snd_ent.UnpackedSize);

            if (snd_ent.IsPacked)
            {
                input = new LzssStream(input);
            }
            return(new PrefixStream(header, input));
        }
예제 #12
0
 public override ImageData Read(Stream stream, ImageMetaData info)
 {
     stream.Position = 4;
     using (var lzss = new LzssStream(stream, LzssMode.Decompress, true))
         using (var input = new SeekableStream(lzss))
             return(base.Read(input, info));
 }
예제 #13
0
파일: ArcDAT.cs 프로젝트: minhrg/GARbro
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var rent = entry as RepiEntry;

            if (null == rent || !rent.HasEncryptionKey)
            {
                return(arc.File.CreateStream(entry.Offset, entry.Size));
            }
            var  key        = rent.CreateKey();
            uint enc_length = Math.Min((uint)key.Length, entry.Size);

            byte[] encrypted = arc.File.View.ReadBytes(entry.Offset, enc_length);
            DecryptEntry(encrypted, key);
            Stream input;

            if (enc_length == entry.Size)
            {
                input = new BinMemoryStream(encrypted, entry.Name);
            }
            else
            {
                input = arc.File.CreateStream(entry.Offset + enc_length, entry.Size - enc_length);
                input = new PrefixStream(encrypted, input);
            }
            if (rent.IsPacked)
            {
                input = new LzssStream(input);
            }
            return(input);
        }
예제 #14
0
        private ImageData ReadV1()
        {
            if (8 == m_info.BPP)
            {
                Palette = ImageFormat.ReadPalette(m_input);
            }

            var packed = new byte[m_info.PackedSize];

            if (packed.Length != m_input.Read(packed, 0, packed.Length))
            {
                throw new InvalidFormatException("Unexpected end of file");
            }
            for (int i = 0; i < packed.Length; ++i)
            {
                packed[i] ^= (byte)i;
            }

            using (var input = new MemoryStream(packed))
                using (var lzs = new LzssStream(input))
                {
                    m_image_data = new byte[m_info.UnpackedSize];
                    // flip pixels vertically
                    for (int dst = m_stride * (m_info.iHeight - 1); dst >= 0; dst -= m_stride)
                    {
                        lzs.Read(m_image_data, dst, m_stride);
                    }
                }
            return(ImageData.Create(m_info, Format, Palette, m_image_data, m_stride));
        }
예제 #15
0
파일: ArcGM.cs 프로젝트: zxc120/GARbro
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var header = arc.File.View.ReadBytes(entry.Offset, 25);

            if (header[0] < 'B' || header[0] > 'E' || header[1] != '1')
            {
                return(arc.File.CreateStream(entry.Offset, entry.Size));
            }
            if ('E' == header[0])
            {
                byte t = header[17];
                header[17] = header[23];
                header[23] = t;
                t          = header[19];
                header[19] = header[24];
                header[24] = t;
            }
            int    unpacked_size = header.ToInt32(6);
            var    data          = new byte[unpacked_size];
            Stream input         = arc.File.CreateStream(entry.Offset + header.Length, entry.Size - (uint)header.Length);

            input          = new PrefixStream(header, input);
            input.Position = 10;
            using (input = new LzssStream(input))
                input.Read(data, 0, unpacked_size);
            if (data.AsciiEqual("BPR01"))
            {
                return(new PackedStream <BprDecompressor> (Stream.Null, new BprDecompressor(data)));
            }
            else
            {
                return(new BinMemoryStream(data, entry.Name));
            }
        }
예제 #16
0
        IBinaryStream UnpackedStream(IBinaryStream input)
        {
            input.Position = 0xB;
            var unpacked = new LzssStream(input.AsStream, LzssMode.Decompress, true);

            return(new BinaryStream(unpacked, input.Name));
        }
예제 #17
0
        public override ImageData Read(IBinaryStream file, ImageMetaData info)
        {
            file.Position = 0x1B;
            int plane_size = info.iWidth * info.iHeight;
            var pixels     = new byte[plane_size * 4];

            using (var input = new LzssStream(file.AsStream, LzssMode.Decompress, true))
            {
                var plane = new byte[plane_size];
                int dst;
                for (int c = 0; c < 3; ++c)
                {
                    input.Read(plane, 0, plane_size);
                    dst = c;
                    for (int src = 0; src < plane_size; ++src)
                    {
                        pixels[dst] = plane[src];
                        dst        += 4;
                    }
                }
                // alpha channel is inverted
                input.Read(plane, 0, plane_size);
                dst = 3;
                for (int src = 0; src < plane_size; ++src)
                {
                    pixels[dst] = (byte)(0xFF - plane[src]);
                    dst        += 4;
                }
            }
            return(ImageData.CreateFlipped(info, PixelFormats.Bgra32, null, pixels, info.iWidth * 4));
        }
예제 #18
0
 public LzssOption(LzssStream lzss)
 {
     N         = lzss.WindowSize;
     F         = lzss.MaxMatchLength;
     THRESHOLD = lzss.MatchThresold;
     FILL      = lzss.CharFiller;
 }
예제 #19
0
파일: ArcPACK.cs 프로젝트: zxc120/GARbro
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var larc = arc as LunaArchive;

            if (null == arc || !arc.File.View.AsciiEqual(entry.Offset, "LZSS"))
            {
                return(base.OpenEntry(arc, entry));
            }

            uint   unpacked_size = arc.File.View.ReadUInt32(entry.Offset + 4);
            Stream input         = arc.File.CreateStream(entry.Offset + 8, entry.Size - 8);

            if (larc.Key != null)
            {
                var bf = new Blowfish(larc.Key);
                input = new InputCryptoStream(input, bf.CreateDecryptor());
                return(new LimitStream(input, unpacked_size));
            }
            else
            {
                var lz = new LzssStream(input);
                lz.Config.FrameInitPos = 0xFF0;
                return(lz);
            }
        }
예제 #20
0
        List <Entry> ReadIndex(string ini_file, string arc_name)
        {
            if (null == LastAccessedIndex ||
                !LastAccessedIndex.Item1.Equals(ini_file, StringComparison.InvariantCultureIgnoreCase))
            {
                LastAccessedIndex = null;
                using (var ini = VFS.OpenView(ini_file))
                {
                    if (!ini.View.AsciiEqual(0, "S4IC") && !ini.View.AsciiEqual(0, "S3IC"))
                    {
                        return(null);
                    }
                    uint packed_size = ini.View.ReadUInt32(0x134);
                    using (var packed = ini.CreateStream(0x138, packed_size))
                        using (var unpacked = new LzssStream(packed))
                            using (var index = new BinaryReader(unpacked))
                            {
                                int arc_count  = index.ReadInt32();
                                var name_buf   = new byte[0x100];
                                var file_table = new Dictionary <string, List <Entry> > (arc_count, StringComparer.InvariantCultureIgnoreCase);
                                var arc_list   = new List <List <Entry> > (arc_count);
                                for (int i = 0; i < arc_count; ++i)
                                {
                                    index.Read(name_buf, 0, name_buf.Length);
                                    var file_list = new List <Entry>();
                                    file_table.Add(Binary.GetCString(name_buf, 0, name_buf.Length), file_list);
                                    arc_list.Add(file_list);
                                }
                                int file_count = index.ReadInt32();
                                for (int i = 0; i < file_count; ++i)
                                {
                                    index.Read(name_buf, 0, 0x40);
                                    int arc_id = index.ReadInt32();
                                    if (arc_id < 0 || arc_id >= arc_list.Count)
                                    {
                                        return(null);
                                    }
                                    index.ReadInt32(); // file number
                                    uint offset = index.ReadUInt32();
                                    uint size   = index.ReadUInt32();
                                    var  name   = Binary.GetCString(name_buf, 0, 0x40);
                                    if ("@" == name)
                                    {
                                        continue;
                                    }
                                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                                    entry.Offset = offset;
                                    entry.Size   = size;
                                    arc_list[arc_id].Add(entry);
                                }
                                LastAccessedIndex = Tuple.Create(ini_file, file_table);
                            }
                }
            }
            List <Entry> dir = null;

            LastAccessedIndex.Item2.TryGetValue(arc_name, out dir);
            return(dir);
        }
예제 #21
0
파일: ImageAKB.cs 프로젝트: zxc120/GARbro
        public byte[] Unpack(byte[] background = null)
        {
            if (0 == m_info.InnerWidth || 0 == m_info.InnerHeight)
            {
                return(background ?? CreateBackground());
            }

            m_input.Position = m_info.DataOffset;
            int inner_stride = m_info.InnerWidth * m_pixel_size;
            var pixels       = new byte[m_info.InnerHeight * inner_stride];

            using (var lz = new LzssStream(m_input, LzssMode.Decompress, true))
            {
                for (int pos = pixels.Length - inner_stride; pos >= 0; pos -= inner_stride)
                {
                    if (inner_stride != lz.Read(pixels, pos, inner_stride))
                    {
                        throw new InvalidFormatException();
                    }
                }
            }
            RestoreDelta(pixels, inner_stride);
            if (null == background && m_info.InnerWidth == m_info.Width && m_info.InnerHeight == m_info.Height)
            {
                return(pixels);
            }

            var    image = background ?? CreateBackground();
            int    src   = 0;
            int    dst   = m_info.OffsetY * Stride + m_info.OffsetX * m_pixel_size;
            Action blend_row;

            if (null == background)
            {
                blend_row = () => Buffer.BlockCopy(pixels, src, image, dst, inner_stride);
            }
            else
            {
                blend_row = () => {
                    for (int x = 0; x < inner_stride; x += m_pixel_size)
                    {
                        if (0x00 != pixels[src + x] || 0xFF != pixels[src + x + 1] || 0x00 != pixels[src + x + 2])
                        {
                            for (int i = 0; i < m_pixel_size; ++i)
                            {
                                image[dst + x + i] = pixels[src + x + i];
                            }
                        }
                    }
                };
            }
            for (int y = 0; y < m_info.InnerHeight; ++y)
            {
                blend_row();
                dst += Stride;
                src += inner_stride;
            }
            return(image);
        }
예제 #22
0
파일: ImageGRD.cs 프로젝트: zxc120/GARbro
        internal IBinaryStream DecompressStream(IBinaryStream stream)
        {
            stream.Position = 12;
            var input = new LzssStream(stream.AsStream, LzssMode.Decompress, true);

            input.Config.FrameFill = 0x20;
            return(new BinaryStream(input, stream.Name));
        }
예제 #23
0
파일: ImagePBM.cs 프로젝트: uboaa/GARbro
        IBinaryStream OpenBitmapStream(IBinaryStream file, uint unpacked_size)
        {
            file.Position = 4;
            Stream input = new LzssStream(file.AsStream, LzssMode.Decompress, true);

            input = new LimitStream(input, unpacked_size);
            return(new BinaryStream(input, file.Name));
        }
예제 #24
0
파일: ImageCRZ.cs 프로젝트: ziyuejun/GARbro
        internal Stream OpenCrzStream(IBinaryStream file)
        {
            var lz = new LzssStream(file.AsStream, LzssMode.Decompress, true);

            lz.Config.FrameSize    = 0x1000;
            lz.Config.FrameFill    = 0x20;
            lz.Config.FrameInitPos = 0x1000 - 0x10;
            return(lz);
        }
예제 #25
0
파일: ArcTactics.cs 프로젝트: zxc120/GARbro
            bool ReadV0(Stream input)
            {
                long current_offset    = 0x20 + m_packed_size;
                uint offset_table_size = (uint)m_count * 0x10;

                if (offset_table_size > m_file.View.Reserve(current_offset, offset_table_size))
                {
                    return(false);
                }

                using (var lzss = new LzssStream(input, LzssMode.Decompress, true))
                    if (m_index.Length != lzss.Read(m_index, 0, m_index.Length))
                    {
                        return(false);
                    }

                for (int i = 0; i < m_index.Length; ++i)
                {
                    m_index[i] = (byte)(~m_index[i] - 5);
                }
                int index_offset = Array.IndexOf <byte> (m_index, 0);

                if (-1 == index_offset || 0 == index_offset)
                {
                    return(false);
                }
                index_offset++;
//                Password = m_index.Take (index_offset++).ToArray();

                for (int i = 0; i < m_count && index_offset < m_index.Length; ++i)
                {
                    int name_end = Array.IndexOf <byte> (m_index, 0, index_offset);
                    if (-1 == name_end)
                    {
                        name_end = m_index.Length;
                    }
                    if (index_offset == name_end)
                    {
                        return(false);
                    }
                    var entry = new PackedEntry();
                    entry.Offset       = m_file.View.ReadUInt32(current_offset);
                    entry.Size         = m_file.View.ReadUInt32(current_offset + 4);
                    entry.UnpackedSize = m_file.View.ReadUInt32(current_offset + 8);
                    entry.IsPacked     = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement(m_file.MaxOffset))
                    {
                        return(false);
                    }
                    entry.Name = Encodings.cp932.GetString(m_index, index_offset, name_end - index_offset);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                    m_dir.Value.Add(entry);
                    index_offset    = name_end + 1;
                    current_offset += 0x10;
                }
                return(true);
            }
예제 #26
0
 void UnpackLzss(byte[] packed)
 {
     using (var mem = new MemoryStream(packed))
         using (var lz = new LzssStream(mem))
             if (m_output.Length != lz.Read(m_output, 0, m_output.Length))
             {
                 throw new EndOfStreamException();
             }
 }
예제 #27
0
        void ReadAlpha()
        {
            int    alpha_stride = (m_width + 3) & ~3;
            Stream alpha_stream;

            if (m_info.AlphaSize == alpha_stride * m_height)
            {
                alpha_stream = new StreamRegion(m_input, m_input.Position, true);
            }
            else
            {
                alpha_stream = new LzssStream(m_input, LzssMode.Decompress, true);
            }
            using (alpha_stream)
            {
                int  src_stride   = Stride;
                int  new_stride   = m_width * 4;
                bool extend_alpha = 3 != m_info.Flags;
                var  alpha_line   = new byte[alpha_stride];
                var  pixels       = new byte[new_stride * m_height];
                for (int y = 0; y < m_height; ++y)
                {
                    int src = y * src_stride;
                    int dst = y * new_stride;
                    if (alpha_line.Length != alpha_stream.Read(alpha_line, 0, alpha_line.Length))
                    {
                        throw new EndOfStreamException();
                    }
                    for (int x = 0; x < m_width; ++x)
                    {
                        if (8 == m_info.BPP)
                        {
                            var color = Palette.Colors[m_output[src++]];
                            pixels[dst++] = color.B;
                            pixels[dst++] = color.G;
                            pixels[dst++] = color.R;
                        }
                        else
                        {
                            pixels[dst++] = m_output[src++];
                            pixels[dst++] = m_output[src++];
                            pixels[dst++] = m_output[src++];
                        }
                        int alpha = alpha_line[x];
                        if (extend_alpha)
                        {
                            alpha = alpha >= 0x10 ? 0xFF : alpha * 0x10;
                        }
                        pixels[dst++] = (byte)alpha;
                    }
                }
                Stride   = new_stride;
                Palette  = null;
                m_output = pixels;
            }
        }
예제 #28
0
        IBinaryStream OpenLzStream(IBinaryStream input)
        {
            input.Position = 0xE;
            var lz = new LzssStream(input.AsStream, LzssMode.Decompress, true);

            lz.Config.FrameSize    = 0x1000;
            lz.Config.FrameFill    = 0x20;
            lz.Config.FrameInitPos = 0x1000 - 0x10;
            return(new BinaryStream(lz, input.Name)); // XXX stream is unseekable
        }
예제 #29
0
 public override ImageData Read(IBinaryStream file, ImageMetaData info)
 {
     file.Position = 0x10;
     using (var lzss = new LzssStream(file.AsStream, LzssMode.Decompress, true))
     {
         var pixels = new byte[info.Width * info.Height];
         lzss.Read(pixels, 0, pixels.Length);
         return(ImageData.CreateFlipped(info, PixelFormats.Gray8, null, pixels, (int)info.Width));
     }
 }
예제 #30
0
파일: ImageTEX.cs 프로젝트: ziyuejun/GARbro
        Stream OpenLzStream(IBinaryStream input)
        {
            input.Position = 0xE;
            var lz = new LzssStream(input.AsStream, LzssMode.Decompress, true);

            lz.Config.FrameSize    = 0x1000;
            lz.Config.FrameFill    = 0x20;
            lz.Config.FrameInitPos = 0x1000 - 0x10;
            return(lz);
        }