Пример #1
0
 void LzUnpack(Stream input, byte[] output)
 {
     using (var bits = new MsbBitStream(input, true))
     {
         int dst = 0;
         while (dst < output.Length)
         {
             int ctl = bits.GetNextBit();
             if (-1 == ctl)
             {
                 break;
             }
             if (0 == ctl)
             {
                 output[dst++] = (byte)bits.GetBits(8);
             }
             else
             {
                 int offset = bits.GetBits(8);
                 int count  = bits.GetBits(8);
                 if (offset <= 0)
                 {
                     break;
                 }
                 Binary.CopyOverlapped(output, dst - offset, dst, count);
                 dst += count;
             }
         }
     }
 }
Пример #2
0
        void LzUnpack(Stream input, byte[] output)
        {
            var frame     = new byte[0x1000];
            int frame_pos = 1;
            int dst       = 0;

            using (var bits = new MsbBitStream(input))
            {
                while (dst < output.Length)
                {
                    if (0 != bits.GetNextBit())
                    {
                        byte b = (byte)bits.GetBits(8);
                        output[dst++] = b;
                        frame[frame_pos++ & 0xFFF] = b;
                    }
                    else
                    {
                        int offset = bits.GetBits(12);
                        int count  = bits.GetBits(4) + 2;
                        for (int i = 0; i < count; ++i)
                        {
                            byte b = frame[(offset + i) & 0xFFF];
                            output[dst++] = b;
                            frame[frame_pos++ & 0xFFF] = b;
                        }
                    }
                }
            }
        }
Пример #3
0
        byte[] ReadBytes(MsbBitStream input)
        {
            int buf_size = ReadInt32(input);
            var buf      = new byte[buf_size];
            int dst      = 0;
            var rnd      = new RandomGenerator((uint)buf_size);

            while (dst < buf_size)
            {
                int count   = (int)rnd.GetNext() & 3;
                int skipped = input.GetBits(count + 1);
                if (-1 == skipped)
                {
                    return(null);
                }
                rnd.GetNext();

                int v = input.GetBits(8);
                if (-1 == v)
                {
                    return(null);
                }
                buf[dst++] = (byte)v;
            }
            return(buf);
        }
Пример #4
0
        int GetInt()
        {
            int count = m_input.GetBits(4);

            switch (count)
            {
            case 0: return(0);

            case 1: return(1);

            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                return(m_input.GetBits(count - 1) + (1 << (count - 1)));

            case 8: return(-1);

            case 9: return(-2);

            default:
                return(m_input.GetBits(count - 9) - (2 << (count - 9)));

            case -1: throw new EndOfStreamException();
            }
        }
Пример #5
0
        ushort[] ReadEncryptedChars(MsbBitStream input)
        {
            int buf_size = ReadInt32(input);
            var buf      = new ushort[buf_size];
            int dst      = 0;
            var rnd      = new RandomGenerator((uint)buf_size);

            while (dst < buf_size)
            {
                int count   = (int)rnd.GetNext() & 3;
                int skipped = input.GetBits(count + 1);
                if (-1 == skipped)
                {
                    return(null);
                }
                rnd.GetNext();

                int lo = input.GetBits(8);
                int hi = input.GetBits(8);
                if (-1 == lo || -1 == hi)
                {
                    return(null);
                }
                buf[dst++] = (ushort)(lo | hi << 8);
            }
            return(buf);
        }
Пример #6
0
        void LzUnpack(Stream input, byte[] output, int dst)
        {
            var frame     = new byte[0x4000];
            int frame_pos = 1;

            using (var bits = new MsbBitStream(input, true))
            {
                while (dst < output.Length)
                {
                    int ctl = bits.GetNextBit();
                    if (-1 == ctl)
                    {
                        break;
                    }
                    if (ctl != 0)
                    {
                        int v = bits.GetBits(8);
                        output[dst++] = frame[frame_pos++ & 0x3FFF] = (byte)v;
                    }
                    else
                    {
                        int offset = bits.GetBits(14);
                        int count  = bits.GetBits(4) + 3;
                        while (count-- > 0)
                        {
                            byte v = frame[offset++ & 0x3FFF];
                            output[dst++] = frame[frame_pos++ & 0x3FFF] = v;
                        }
                    }
                }
            }
        }
Пример #7
0
        protected override IEnumerator <int> Unpack()
        {
            m_token = 256;
            ushort root = CreateTree();

            for (;;)
            {
                ushort symbol = root;
                while (symbol >= 0x100)
                {
                    int bit = m_input.GetBits(1);
                    if (-1 == bit)
                    {
                        yield break;
                    }
                    if (bit != 0)
                    {
                        symbol = rhs[symbol];
                    }
                    else
                    {
                        symbol = lhs[symbol];
                    }
                }
                m_buffer[m_pos++] = (byte)symbol;
                if (0 == --m_length)
                {
                    yield return(m_pos);
                }
            }
        }
Пример #8
0
 void FillLine()
 {
     for (int dst = 0; dst < m_width;)
     {
         int length = m_input.GetBits(3);
         if (-1 == length)
         {
             throw new EndOfStreamException();
         }
         int count = GetCount() + 1;
         if (length != 0)
         {
             for (int j = 0; j < count; ++j)
             {
                 m_line_buf[dst++] = (byte)m_input.GetBits(length + 1);
             }
         }
         else
         {
             for (int j = 0; j < count; ++j)
             {
                 m_line_buf[dst++] = 0;
             }
         }
     }
     for (int i = 1; i < m_width; ++i)
     {
         m_line_buf[i] = DeltaTable[m_line_buf[i], m_line_buf[i - 1]];
     }
 }
Пример #9
0
        static int ReadInt32(MsbBitStream input)
        {
            int b0 = input.GetBits(8);
            int b1 = input.GetBits(8);
            int b2 = input.GetBits(8);
            int b3 = input.GetBits(8);

            return(b3 << 24 | b2 << 16 | b1 << 8 | b0);
        }
Пример #10
0
        void ReadDimensions()
        {
            int rsize = m_bits.GetBits(5);

            m_dim.X      = GetSignedBits(rsize);
            m_dim.Y      = GetSignedBits(rsize);
            m_dim.Width  = GetSignedBits(rsize) - m_dim.X;
            m_dim.Height = GetSignedBits(rsize) - m_dim.Y;
        }
Пример #11
0
        protected override IEnumerator <int> Unpack()
        {
            var frame     = new byte[0x1000];
            int dst       = 0;
            int frame_pos = 1;

            while (dst < m_unpacked_size)
            {
                int bit = m_input.GetNextBit();
                if (bit != 0)
                {
                    if (-1 == bit)
                    {
                        yield break;
                    }
                    int v = m_input.GetBits(8);
                    if (-1 == v)
                    {
                        yield break;
                    }
                    frame[frame_pos++ & 0xFFF] = m_buffer[m_pos++] = (byte)v;
                    dst++;
                    if (0 == --m_length)
                    {
                        yield return(m_pos);
                    }
                }
                else
                {
                    int offset = m_input.GetBits(12);
                    if (-1 == offset)
                    {
                        yield break;
                    }
                    int count = m_input.GetBits(4);
                    if (-1 == count)
                    {
                        yield break;
                    }
                    count += 2;
                    dst   += count;
                    while (count-- > 0)
                    {
                        byte v = frame[offset++ & 0xFFF];
                        frame[frame_pos++ & 0xFFF] = v;
                        m_buffer[m_pos++]          = v;
                        if (0 == --m_length)
                        {
                            yield return(m_pos);
                        }
                    }
                }
            }
        }
Пример #12
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            if (entry.Size < 0x10 || !arc.File.View.AsciiEqual(entry.Offset, "CRILAYLA"))
            {
                return(base.OpenEntry(arc, entry));
            }

            var unpacked_size = arc.File.View.ReadInt32(entry.Offset + 8);
            var packed_size   = arc.File.View.ReadUInt32(entry.Offset + 12);

            if (unpacked_size < 0 || packed_size > entry.Size - 0x10)
            {
                return(base.OpenEntry(arc, entry));
            }
            uint prefix_size = entry.Size - (0x10 + packed_size);
            var  output      = new byte[unpacked_size + prefix_size];
            var  packed      = arc.File.View.ReadBytes(entry.Offset + 0x10, packed_size);

            Array.Reverse(packed);
            using (var mem = new MemoryStream(packed))
                using (var input = new MsbBitStream(mem))
                {
                    byte[] sizes = { 2, 3, 5, 8 };
                    int    dst   = (int)prefix_size;
                    while (dst < output.Length)
                    {
                        if (0 == input.GetNextBit())
                        {
                            output[dst++] = (byte)input.GetBits(8);
                            continue;
                        }
                        int count = 3;
                        int offset = input.GetBits(13) + 3;
                        int rank = 0;
                        int bits, step;
                        do
                        {
                            bits   = sizes[rank];
                            step   = input.GetBits(bits);
                            count += step;
                            if (rank < 3)
                            {
                                rank++;
                            }
                        }while (((1 << bits) - 1) == step);
                        Binary.CopyOverlapped(output, dst - offset, dst, count);
                        dst += count;
                    }
                }
            Array.Reverse(output, (int)prefix_size, unpacked_size);
            arc.File.View.Read(entry.Offset + 0x10 + packed_size, output, 0, prefix_size);
            return(new BinMemoryStream(output, entry.Name));
        }
Пример #13
0
        protected override IEnumerator <int> Unpack()
        {
            var frame     = new byte[0x400];
            int frame_pos = 1;

            for (;;)
            {
                int bit = m_input.GetNextBit();
                if (-1 == bit)
                {
                    yield break;
                }
                if (bit != 0)
                {
                    int v = m_input.GetBits(8);
                    if (-1 == v)
                    {
                        yield break;
                    }
                    m_buffer[m_pos++] = frame[frame_pos++ & 0x3FF] = (byte)v;
                    if (0 == --m_length)
                    {
                        yield return(m_pos);
                    }
                }
                else
                {
                    int offset = m_input.GetBits(10);
                    if (-1 == offset)
                    {
                        yield break;
                    }
                    int count = m_input.GetBits(5);
                    if (-1 == count)
                    {
                        yield break;
                    }
                    count += 2;
                    while (count-- > 0)
                    {
                        byte v = frame[offset++ & 0x3FF];
                        m_buffer[m_pos++] = frame[frame_pos++ & 0x3FF] = v;
                        if (0 == --m_length)
                        {
                            yield return(m_pos);
                        }
                    }
                }
            }
        }
Пример #14
0
        internal byte[] Decompress(IBinaryStream input, int unpacked_size)
        {
            input.Position = 0x12;
            int data_pos    = input.ReadInt32();
            int bits_length = Math.Min(data_pos - 0x10, (unpacked_size + 7) / 8);
            var ctl_bits    = input.ReadBytes(bits_length);

            input.Position = 6 + data_pos;
            var output = new byte[unpacked_size];

            using (var mem = new MemoryStream(ctl_bits))
                using (var bits = new MsbBitStream(mem))
                    using (var data = new MsbBitStream(input.AsStream, true))
                    {
                        int dst = 0;
                        while (dst < unpacked_size)
                        {
                            int ctl = bits.GetNextBit();
                            if (-1 == ctl)
                            {
                                break;
                            }
                            if (ctl != 0)
                            {
                                output[dst++] = (byte)data.GetBits(8);
                            }
                            else
                            {
                                int offset, count;
                                if (bits.GetNextBit() != 0)
                                {
                                    offset = data.GetBits(14);
                                    count  = data.GetBits(4) + 3;
                                }
                                else
                                {
                                    offset = data.GetBits(9);
                                    count  = data.GetBits(3) + 2;
                                }
                                count = Math.Min(count, output.Length - dst);
                                Binary.CopyOverlapped(output, dst - offset - 1, dst, count);
                                dst += count;
                            }
                        }
                        return(output);
                    }
        }
Пример #15
0
        public void DecodeFrame(int channel, short[] output)
        {
            int offset       = channel;
            var prev_samples = m_prev_samples[channel];
            int scale        = (short)m_input.GetBits(16) + 1;

            for (int i = 0; i < m_samples_per_frame; ++i)
            {
                int sample = NibbleToSigned(m_input.GetBits(BitsPerSample));
                int adjust = (m_prev_scale0 * prev_samples[0] + m_prev_scale1 * prev_samples[1]) >> 12;
                sample          = Clamp16(sample * scale + adjust);
                output[offset]  = (short)sample;
                offset         += m_format.Channels;
                prev_samples[1] = prev_samples[0];
                prev_samples[0] = sample;
            }
        }
Пример #16
0
            bool DecodeStream(uint data_pos, uint index_size)
            {
                ReadIndex(index_size);
                m_input.Position = data_pos;
                m_bits.Reset();

                bool small_index = index_size < 0x1002;

                m_index_length_limit = small_index ? 6 : 14;
                int index_bit_length = small_index ? 3 : 4;

                while (m_dst_size > 0)
                {
                    int dst_count    = 1;
                    int index_length = m_bits.GetBits(index_bit_length);
                    if (0 == index_length)
                    {
                        dst_count    = m_bits.GetBits(4) + 2;
                        index_length = m_bits.GetBits(index_bit_length);
                    }
                    if (0 == index_length)
                    {
                        return(false);
                    }

                    int index = GetIndex(index_length);
                    if (index >= index_size)
                    {
                        return(false);
                    }

                    if (dst_count > m_dst_size)
                    {
                        return(false);
                    }
                    m_dst_size -= dst_count;
                    ushort word = m_index[index];
                    do
                    {
                        LittleEndian.Pack(word, m_data, edi);
                        edi += 4;
                    } while (0 != --dst_count);
                }
                return(true);
            }
Пример #17
0
 public List <Entry> Read()
 {
     byte[] packed;
     using (var input = m_file.CreateStream(12, m_data_offset - 12))
         using (var bits = new MsbBitStream(input))
         {
             bits.GetNextBit();
             m_dict = ReadBytes(bits);
             if (null == m_dict)
             {
                 return(null);
             }
             int packed_size   = ReadInt32(bits);
             int unpacked_size = ReadInt32(bits);
             packed = new byte[packed_size];
             for (int i = 0; i < packed_size; ++i)
             {
                 packed[i] = (byte)bits.GetBits(8);
             }
         }
     using (var bstr = new BinMemoryStream(packed))
         using (var zstr = new ZLibStream(bstr, CompressionMode.Decompress))
             using (var index = new MsbBitStream(zstr))
             {
                 index.GetNextBit();
                 int count = ReadInt32(index);
                 if (!ArchiveFormat.IsSaneCount(count))
                 {
                     return(null);
                 }
                 var dir = new List <Entry> (count);
                 for (int i = 0; i < count; ++i)
                 {
                     if (index.GetBits(2) == -1)
                     {
                         break;
                     }
                     var name_buf = ReadEncryptedChars(index);
                     if (null == name_buf)
                     {
                         return(null);
                     }
                     var name  = DecryptString(name_buf, name_buf.Length);
                     var entry = FormatCatalog.Instance.Create <Entry> (name);
                     ReadInt32(index);
                     ReadInt32(index);
                     entry.Offset = (uint)ReadInt32(index) + m_data_offset;
                     entry.Size   = (uint)ReadInt32(index);
                     if (!entry.CheckPlacement(m_file.MaxOffset))
                     {
                         return(null);
                     }
                     dir.Add(entry);
                 }
                 return(dir);
             }
 }
Пример #18
0
        public byte[] Unpack()
        {
            int dst       = 0;
            int frame_pos = 1;

            while (dst < m_output.Length)
            {
                int bit = m_input.GetNextBit();
                if (bit != 0)
                {
                    if (-1 == bit)
                    {
                        break;
                    }
                    int v = m_input.GetBits(8);
                    if (-1 == v)
                    {
                        break;
                    }
                    m_frame[frame_pos++ & 0xFFF] = m_output[dst++] = (byte)v;
                }
                else
                {
                    int offset = m_input.GetBits(12);
                    if (-1 == offset)
                    {
                        break;
                    }
                    int count = m_input.GetBits(4);
                    if (-1 == count)
                    {
                        break;
                    }
                    count += 2;
                    while (count-- > 0)
                    {
                        byte v = m_frame[offset++ & 0xFFF];
                        m_output[dst++] = v;
                        m_frame[frame_pos++ & 0xFFF] = v;
                    }
                }
            }
            return(m_output);
        }
Пример #19
0
        void UncompressRgba(byte[] input, byte[] output)
        {
            int src = input.ToInt32(0);

            using (var mem = new MemoryStream(input, 4, src - 4))
                using (var bits = new MsbBitStream(mem))
                {
                    int dst = 0;
                    for (int y = 0; y < m_h; ++y)
                    {
                        int rgb   = 0;
                        int alpha = 0;
                        int x     = 0;
                        while (x < m_w)
                        {
                            int len = input[src++];
                            if (alpha != 0)
                            {
                                for (int i = 0; i < len; ++i)
                                {
                                    if (bits.GetNextBit() != 0)
                                    {
                                        int b = ReadABits(bits, rgb) + 3;
                                        int g = ReadABits(bits, rgb >> 8) + 3;
                                        int r = ReadABits(bits, rgb >> 16) + 3;
                                        rgb = r << 16 | g << 8 | b;
                                    }
                                    LittleEndian.Pack(rgb | alpha << 24, output, dst);
                                    dst += 4;
                                }
                            }
                            else
                            {
                                dst += 4 * len;
                            }
                            x += len;
                            if (x >= m_w)
                            {
                                break;
                            }
                            if (bits.GetNextBit() != 0)
                            {
                                alpha = (bits.GetBits(7) << 1) + 1;
                            }
                            else if (bits.GetNextBit() != 0)
                            {
                                alpha = 0xFF;
                            }
                            else
                            {
                                alpha = 0;
                            }
                        }
                    }
                }
        }
Пример #20
0
 internal static void Unpack(Stream input, byte[] output, int dst = 0)
 {
     using (var bits = new MsbBitStream(input, true))
     {
         bits.GetNextBit();
         while (dst < output.Length)
         {
             int count = bits.GetBits(8);
             if (-1 == count)
             {
                 break;
             }
             if (count > 0x7F)
             {
                 int offset = bits.GetBits(10);
                 if (-1 == offset)
                 {
                     throw new EndOfStreamException();
                 }
                 count = Math.Min(count & 0x7F, output.Length - dst);
                 Binary.CopyOverlapped(output, dst - offset, dst, count);
                 dst += count;
             }
             else
             {
                 if (0 == count)
                 {
                     break;
                 }
                 for (int i = 0; i < count && dst < output.Length; i++)
                 {
                     int v = bits.GetBits(8);
                     if (-1 == v)
                     {
                         throw new EndOfStreamException();
                     }
                     output[dst++] = (byte)v;
                 }
             }
         }
     }
 }
Пример #21
0
        public void Unpack()
        {
            int dst       = 0;
            int frame_pos = 1;

            byte[] frame      = new byte[4096];
            int    frame_mask = frame.Length - 1;

            while (dst < m_output.Length)
            {
                int bit = m_input.GetNextBit();
                if (-1 == bit)
                {
                    break;
                }
                if (0 != bit)
                {
                    int data = m_input.GetBits(8);
                    m_output[dst++]    = (byte)data;
                    frame[frame_pos++] = (byte)data;
                    frame_pos         &= frame_mask;
                }
                else
                {
                    int win_offset = m_input.GetBits(12);
                    if (-1 == win_offset || 0 == win_offset)
                    {
                        break;
                    }

                    int count = m_input.GetBits(4) + 2;
                    for (int i = 0; i < count; i++)
                    {
                        byte data = frame[(win_offset + i) & frame_mask];
                        m_output[dst++]    = data;
                        frame[frame_pos++] = data;
                        frame_pos         &= frame_mask;
                    }
                }
            }
        }
Пример #22
0
        void UnpackGyu(byte[] packed)
        {
            using (var mem = new MemoryStream(packed, 4, packed.Length - 4))
                using (var bits = new MsbBitStream(mem))
                {
                    int dst = 0;
                    m_output[dst++] = (byte)mem.ReadByte();
                    while (dst < m_output.Length)
                    {
                        int b = bits.GetNextBit();
                        if (-1 == b)
                        {
                            throw new EndOfStreamException();
                        }
                        if (1 == b)
                        {
                            m_output[dst++] = (byte)mem.ReadByte();
                            continue;
                        }
                        int count;
                        int offset;
                        if (1 == bits.GetNextBit())
                        {
                            count  = mem.ReadByte() << 8;
                            count |= mem.ReadByte();
                            offset = -1 << 13 | count >> 3;
                            count &= 7;

                            if (0 != count)
                            {
                                ++count;
                            }
                            else
                            {
                                count = mem.ReadByte();
                                if (0 == count)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            count  = 1 + bits.GetBits(2);
                            offset = -1 << 8 | mem.ReadByte();
                        }

                        Binary.CopyOverlapped(m_output, dst + offset, dst, ++count);
                        dst += count;
                    }
                }
        }
Пример #23
0
        void Unpack(IBinaryStream input, byte[] output)
        {
            int offset_bits = input.ReadUInt8();
            int count_bits  = input.ReadUInt8();
            int dst         = 0;

            using (var bits = new MsbBitStream(input.AsStream, true))
            {
                while (dst < output.Length)
                {
                    if (bits.GetNextBit() != 0)
                    {
                        int v = bits.GetBits(8);
                        if (v < 0)
                        {
                            break;
                        }
                        output[dst++] = (byte)v;
                    }
                    else
                    {
                        int src = bits.GetBits(offset_bits);
                        if (src < 0)
                        {
                            break;
                        }
                        int count = bits.GetBits(count_bits);
                        if (count < 0)
                        {
                            break;
                        }
                        count = Math.Min(output.Length - dst, count + 1);
                        Binary.CopyOverlapped(output, src, dst, count);
                        dst += count;
                    }
                }
            }
        }
Пример #24
0
        int ReadToken()
        {
            if (m_last_token - 256 >= m_token_limit)
            {
                m_token_limit <<= 1;
                m_token_bits   += 1;
            }
            int token = m_input.GetNextBit();

            if (token > 0)
            {
                token = m_input.GetBits(m_token_bits);
                if (token != -1)
                {
                    token += 256;
                }
            }
            else if (0 == token)
            {
                token = m_input.GetBits(8);
            }
            return(token);
        }
Пример #25
0
        protected override ImageData GetImageData()
        {
            m_input.Position = 0x28;
            int palette_size = m_input.ReadInt32();

            if (24 == Info.BPP)
            {
                var palette = m_input.ReadBytes(palette_size * 3);
                int stride  = 3 * (int)Info.Width;
                var pixels  = new byte[stride * (int)Info.Height];
                int dst     = 0;
                while (dst < pixels.Length)
                {
                    int src = m_input.ReadUInt16();
                    if (src >= palette_size)
                    {
                        throw new InvalidFormatException();
                    }
                    int color = src * 3;
                    pixels[dst++] = palette[color + 2];
                    pixels[dst++] = palette[color + 1];
                    pixels[dst++] = palette[color];
                }
                return(ImageData.CreateFlipped(Info, PixelFormats.Bgr24, null, pixels, stride));
            }
            else
            {
                int bits_length = m_input.ReadInt32();
                var palette     = m_input.ReadBytes(palette_size * 2);
                int color_bits  = GetColorBits(palette_size);
                int stride      = 2 * (int)Info.Width;
                var pixels      = new byte[stride * (int)Info.Height];
                int dst         = 0;
                using (var bits = new MsbBitStream(m_input.AsStream, true))
                {
                    while (dst < pixels.Length)
                    {
                        int src = bits.GetBits(color_bits);
                        if (src >= palette_size)
                        {
                            throw new InvalidFormatException();
                        }
                        int color = src * 2;
                        pixels[dst++] = palette[color];
                        pixels[dst++] = palette[color + 1];
                    }
                    return(ImageData.CreateFlipped(Info, PixelFormats.Bgr555, null, pixels, stride));
                }
            }
        }
Пример #26
0
 ushort CreateHuffmanTree()
 {
     if (0 != m_input.GetNextBit())
     {
         ushort v = m_token++;
         m_tree[0, v - 256] = CreateHuffmanTree();
         m_tree[1, v - 256] = CreateHuffmanTree();
         return(v);
     }
     else
     {
         return((ushort)m_input.GetBits(8));
     }
 }
Пример #27
0
        byte[] UnpackEntry(Stream input, uint unpacked_size)
        {
            const int dict_size = 0x10;
            var       output    = new byte[unpacked_size];

            using (var bits = new MsbBitStream(input, true))
            {
                var dict     = new byte[dict_size];
                int dict_pos = 0;
                for (int dst = 0; dst < output.Length; ++dst)
                {
                    byte cur_byte;
                    if (bits.GetNextBit() != 0)
                    {
                        int offset = GetBitLength(bits);
                        int pos    = dict_pos - offset;
                        if (pos < 0)
                        {
                            pos += dict_size;
                        }
                        if (pos < 0 || pos >= dict_size)
                        {
                            throw new InvalidDataException("Invalid compressed data.");
                        }
                        cur_byte = dict[pos];
                    }
                    else
                    {
                        cur_byte = (byte)bits.GetBits(8);
                    }
                    output[dst]      = cur_byte;
                    dict[dict_pos++] = cur_byte;
                    dict_pos        &= 0xF;
                }
            }
            return(output);
        }
Пример #28
0
 int UnpackHuffman(byte[] input, int input_length, byte[] output)
 {
     using (var mem = new MemoryStream(input, 0, input_length))
     {
         var    tree = new HuffmanNode[0x201];
         ushort root = BuildHuffmanTree(tree, mem);
         using (var bits = new MsbBitStream(mem))
         {
             int dst = 0;
             for (;;)
             {
                 ushort symbol = root;
                 while (symbol > 0x100)
                 {
                     int bit = bits.GetBits(1);
                     if (-1 == bit)
                     {
                         return(dst);
                     }
                     if (bit != 0)
                     {
                         symbol = tree[symbol].RChild;
                     }
                     else
                     {
                         symbol = tree[symbol].LChild;
                     }
                 }
                 if (0x100 == symbol)
                 {
                     return(dst);
                 }
                 output[dst++] = (byte)symbol;
             }
         }
     }
 }
Пример #29
0
        public void Unpack()
        {
            int dst         = 0;
            var lzw_dict    = new int[0x8900];
            int token_width = 9;
            int dict_pos    = 0;

            while (dst < m_output.Length)
            {
                int token = m_input.GetBits(token_width);
                if (-1 == token)
                {
                    throw new EndOfStreamException("Invalid compressed stream");
                }
                else if (0x100 == token) // end of input
                {
                    break;
                }
                else if (0x101 == token) // increase token width
                {
                    ++token_width;
                    if (token_width > 24)
                    {
                        throw new InvalidFormatException("Invalid comressed stream");
                    }
                }
                else if (0x102 == token) // reset dictionary
                {
                    token_width = 9;
                    dict_pos    = 0;
                }
                else
                {
                    if (dict_pos >= lzw_dict.Length)
                    {
                        throw new InvalidFormatException("Invalid comressed stream");
                    }
                    lzw_dict[dict_pos++] = dst;
                    if (token < 0x100)
                    {
                        m_output[dst++] = (byte)token;
                    }
                    else
                    {
                        token -= 0x103;
                        if (token >= dict_pos)
                        {
                            throw new InvalidFormatException("Invalid comressed stream");
                        }
                        int src   = lzw_dict[token];
                        int count = Math.Min(m_output.Length - dst, lzw_dict[token + 1] - src + 1);
                        if (count < 0)
                        {
                            throw new InvalidFormatException("Invalid comressed stream");
                        }
                        Binary.CopyOverlapped(m_output, src, dst, count);
                        dst += count;
                    }
                }
            }
        }
Пример #30
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            if (entry.Size < 0x10 || !arc.File.View.AsciiEqual (entry.Offset, "CRILAYLA"))
                return base.OpenEntry (arc, entry);

            var unpacked_size = arc.File.View.ReadInt32 (entry.Offset+8);
            var packed_size = arc.File.View.ReadUInt32 (entry.Offset+12);
            if (unpacked_size < 0 || packed_size > entry.Size - 0x10)
                return base.OpenEntry (arc, entry);
            uint prefix_size = entry.Size - (0x10+packed_size);
            var output = new byte[unpacked_size+prefix_size];
            var packed = arc.File.View.ReadBytes (entry.Offset+0x10, packed_size);
            Array.Reverse (packed);
            using (var mem = new MemoryStream (packed))
            using (var input = new MsbBitStream (mem))
            {
                byte[] sizes = { 2, 3, 5, 8 };
                int dst = (int)prefix_size;
                while (dst < output.Length)
                {
                    if (0 == input.GetNextBit())
                    {
                        output[dst++] = (byte)input.GetBits (8);
                        continue;
                    }
                    int count = 3;
                    int offset = input.GetBits (13) + 3;
                    int rank = 0;
                    int bits, step;
                    do
                    {
                        bits = sizes[rank];
                        step = input.GetBits (bits);
                        count += step;
                        if (rank < 3)
                            rank++;
                    }
                    while (((1 << bits) - 1) == step);
                    Binary.CopyOverlapped (output, dst-offset, dst, count);
                    dst += count;
                }
            }
            Array.Reverse (output, (int)prefix_size, unpacked_size);
            arc.File.View.Read (entry.Offset+0x10+packed_size, output, 0, prefix_size);
            return new MemoryStream (output);
        }
Пример #31
0
        public void UnpackBlock(int offset, int length, int dst)
        {
            using (var input = new MemoryStream(this.Input, offset, length))
                using (var reader = new MsbBitStream(input))
                {
                    int block_size = CbgReader.ReadInteger(input);
                    if (-1 == block_size)
                    {
                        return;
                    }
                    var color_data = new short[block_size];
                    int acc        = 0;
                    for (int i = 0; i < block_size && input.Position < input.Length; i += 64)
                    {
                        int count = Tree1.DecodeToken(reader);
                        if (count != 0)
                        {
                            int v = reader.GetBits(count);
                            if (0 == (v >> (count - 1)))
                            {
                                v = (-1 << count | v) + 1;
                            }
                            acc += v;
                        }
                        color_data[i] = (short)acc;
                    }

                    if (0 != (reader.CacheSize & 7))
                    {
                        reader.GetBits(reader.CacheSize & 7);
                    }

                    for (int i = 0; i < block_size && input.Position < input.Length; i += 64)
                    {
                        int index = 1;
                        while (index < 64 && input.Position < input.Length)
                        {
                            int code = Tree2.DecodeToken(reader);
                            if (0 == code)
                            {
                                break;
                            }
                            if (0xF == code)
                            {
                                index += 0x10;
                                continue;
                            }
                            index += code & 0xF;
                            if (index >= block_fill_order.Length)
                            {
                                break;
                            }
                            code >>= 4;
                            int v = reader.GetBits(code);
                            if (code != 0 && 0 == (v >> (code - 1)))
                            {
                                v = (-1 << code | v) + 1;
                            }
                            color_data[i + block_fill_order[index]] = (short)v;
                            ++index;
                        }
                    }
                    if (8 == BPP)
                    {
                        DecodeGrayscale(color_data, dst);
                    }
                    else
                    {
                        DecodeRGB(color_data, dst);
                    }
                }
        }
Пример #32
0
        public void UnpackBlock(int offset, int length, int dst)
        {
            using (var input = new MemoryStream (this.Input, offset, length))
            using (var reader = new MsbBitStream (input))
            {
                int block_size = CbgReader.ReadInteger (input);
                if (-1 == block_size)
                    return;
                var color_data = new short[block_size];
                int acc = 0;
                for (int i = 0; i < block_size && input.Position < input.Length; i += 64)
                {
                    int count = Tree1.DecodeToken (reader);
                    if (count != 0)
                    {
                        int v = reader.GetBits (count);
                        if (0 == (v >> (count - 1)))
                            v = (-1 << count | v) + 1;
                        acc += v;
                    }
                    color_data[i] = (short)acc;
                }

                if (0 != (reader.CacheSize & 7))
                    reader.GetBits (reader.CacheSize & 7);

                for (int i = 0; i < block_size && input.Position < input.Length; i += 64)
                {
                    int index = 1;
                    while (index < 64 && input.Position < input.Length)
                    {
                        int code = Tree2.DecodeToken (reader);
                        if (0 == code)
                            break;
                        if (0xF == code)
                        {
                            index += 0x10;
                            continue;
                        }
                        index += code & 0xF;
                        if (index >= block_fill_order.Length)
                            break;
                        code >>= 4;
                        int v = reader.GetBits (code);
                        if (code != 0 && 0 == (v >> (code - 1)))
                            v = (-1 << code | v) + 1;
                        color_data[i + block_fill_order[index]] = (short)v;
                        ++index;
                    }
                }
                if (8 == BPP)
                    DecodeGrayscale (color_data, dst);
                else
                    DecodeRGB (color_data, dst);
            }
        }