Exemplo n.º 1
0
        static int GetInt(IBitStream input)
        {
            int n = 1;

            while (input.GetNextBit() > 0)
            {
                n <<= 1;
                n  |= input.GetNextBit();
            }
            return(n);
        }
Exemplo n.º 2
0
        static int GetSigned(IBitStream input)
        {
            bool sign = input.GetNextBit() > 0;
            int  n    = GetInt(input);

            return(sign ? -n : n);
        }
Exemplo n.º 3
0
        static int GetBitLength(IBitStream input)
        {
            int count = 0;

            while (0 == input.GetNextBit())
            {
                ++count;
            }
            int n = 1 << count;

            if (count > 0)
            {
                n |= input.GetBits(count);
            }
            return(n);
        }
Exemplo n.º 4
0
        int ReadABits(IBitStream input, int prev)
        {
            prev &= 0xFC;
            if (input.GetNextBit() == 0)
            {
                if (input.GetNextBit() == 0)
                {
                    return(prev);
                }
                else
                {
                    return(input.GetBits(6) << 2);
                }
            }
            else if (input.GetNextBit() == 0)
            {
                if (input.GetNextBit() == 0)
                {
                    return(prev + 4);
                }
                else
                {
                    return(prev - 4);
                }
            }
            else if (input.GetNextBit() == 0)
            {
                if (input.GetNextBit() == 0)
                {
                    return(prev + 8);
                }
                else
                {
                    return(prev - 8);
                }
            }
            else
            {
                switch (input.GetBits(2))
                {
                case 0:  return(Math.Min(prev + 16, 0xFC));

                case 1:  return(Math.Max(prev - 16, 0));

                case 2:  return(Math.Min(prev + 24, 0xFC));

                default: return(Math.Max(prev - 24, 0));
                }
            }
        }
Exemplo n.º 5
0
        int ReadShort(IBitStream input, int prev)
        {
            prev &= 0xFE;
            if (input.GetNextBit() == 0)
            {
                if (input.GetNextBit() == 0)
                {
                    return(prev);
                }
                else
                {
                    return(input.GetBits(6) << 2);
                }
            }
            else if (input.GetNextBit() == 0)
            {
                if (input.GetNextBit() == 0)
                {
                    return(prev + 2);
                }
                else
                {
                    return(prev - 2);
                }
            }
            else if (input.GetNextBit() == 0)
            {
                if (input.GetNextBit() == 0)
                {
                    return(prev + 4);
                }
                else
                {
                    return(prev - 4);
                }
            }
            else
            {
                switch (input.GetBits(2))
                {
                case 0:  return(Math.Min(prev + 8, 0xFE));

                case 1:  return(Math.Max(prev - 8, 0));

                case 2:  return(Math.Min(prev + 12, 0xFE));

                default: return(Math.Max(prev - 12, 0));
                }
            }
        }
Exemplo n.º 6
0
        int LzeGetInteger(IBitStream bits)
        {
            int length = 0;

            for (int i = 0; i < 16; ++i)
            {
                if (0 != bits.GetNextBit())
                {
                    break;
                }
                ++length;
            }
            int v = 1 << length;

            if (length > 0)
            {
                v |= bits.GetBits(length);
            }
            return(v);
        }
Exemplo n.º 7
0
        public int DecodeToken(IBitStream input)
        {
            int node_index = m_nodes.Length - 1;

            do
            {
                int bit = input.GetNextBit();
                if (-1 == bit)
                {
                    throw new EndOfStreamException();
                }
                if (0 == bit)
                {
                    node_index = m_nodes[node_index].LeftChildIndex;
                }
                else
                {
                    node_index = m_nodes[node_index].RightChildIndex;
                }
            }while (m_nodes[node_index].IsParent);
            return(node_index);
        }
Exemplo n.º 8
0
        void UncompressRgb3(IBitStream input, byte[] output)
        {
            int stride = m_width * 4;
            int rgb    = 0;

            for (int dst_row = output.Length - stride; dst_row >= 0; dst_row -= stride)
            {
                int dst = dst_row;
                for (int x = 0; x < m_width; ++x)
                {
                    if (input.GetNextBit() != 0)
                    {
                        int b = ReadLong(input, rgb) + 3;
                        int g = ReadShort(input, rgb >> 8) + 1;
                        int r = ReadLong(input, rgb >> 16) + 3;
                        rgb = r << 16 | g << 8 | b;
                    }
                    LittleEndian.Pack(rgb, output, dst);
                    dst += 4;
                }
            }
        }
Exemplo n.º 9
0
        void UnpackL(IBitStream input)
        {
            int dst       = 0;
            var frame     = new byte[0x10000];
            int frame_pos = 1;

            while (dst < m_output.Length)
            {
                int bit = input.GetNextBit();
                if (-1 == bit)
                {
                    break;
                }
                if (0 != bit)
                {
                    byte v = (byte)input.GetBits(8);
                    m_output[dst++]             = v;
                    frame[frame_pos++ & 0xFFFF] = v;
                }
                else
                {
                    int offset = input.GetBits(16);
                    int count  = input.GetBits(4);
                    if (-1 == offset || -1 == count)
                    {
                        break;
                    }
                    count += 3;
                    while (count-- > 0)
                    {
                        byte v = frame[offset++ & 0xFFFF];
                        m_output[dst++]             = v;
                        frame[frame_pos++ & 0xFFFF] = v;
                    }
                }
            }
        }
Exemplo n.º 10
0
        void UnpackHuffman(IBitStream input, byte[] output)
        {
            var tree       = new HuffmanNode[0x10000];
            var buf        = new byte[0x10000];
            int node_count = 0;
            int dst        = 0;

            while (dst < output.Length)
            {
                int index = -1;
                int bit   = input.GetNextBit();
                if (-1 == bit)
                {
                    break;
                }

                if (bit != 0)
                {
                    int node_bits = node_count == tree.Length ? node_count - 1 : node_count;
                    index = input.GetNextBit();
                    for (int shift = 1; node_bits > 1; ++shift)
                    {
                        index      |= input.GetNextBit() << shift;
                        node_bits >>= 1;
                    }
                    int chunk_length = 0;
                    int curr_index   = index;
                    do
                    {
                        buf[chunk_length++] = tree[curr_index].Value;
                        curr_index          = tree[curr_index].Parent;
                    }while (curr_index != -1);

                    while (chunk_length-- > 0)
                    {
                        output[dst++] = buf[chunk_length];
                    }
                }

                int bits_count = 2;
                while (input.GetNextBit() > 0)
                {
                    bits_count++;
                }

                int c = 0;
                while (bits_count-- > 0)
                {
                    c |= input.GetNextBit() << bits_count;
                }
                if (c < 0)
                {
                    break;
                }

                byte symbol = m_symbol_table[c];
                output[dst++] = symbol;

                if (node_count < tree.Length)
                {
                    tree[node_count].Parent = index;
                    tree[node_count].Value  = symbol;
                    node_count++;
                }
            }
        }
Exemplo n.º 11
0
        void UnpackP(IBitStream input)
        {
            int dst = 0;

            for (int i = 0; i < m_output.Length; ++i)
            {
                m_output[i] = 0xFF;
            }
            int width = (int)m_info.Width;

            while (dst < m_output.Length)
            {
                int count = input.GetBits(2);
                if (-1 == count)
                {
                    break;
                }
                if (2 == count)
                {
                    count = input.GetBits(2) + 2;
                }
                else if (3 == count)
                {
                    int n = 3;
                    while (input.GetNextBit() > 0)
                    {
                        ++n;
                    }
                    if (n >= 24)
                    {
                        break;
                    }
                    count = (1 << n | input.GetBits(n)) - 2;
                }
                dst               += 3 * count;
                m_output [dst]     = (byte)input.GetBits(8);
                m_output [dst + 1] = (byte)input.GetBits(8);
                m_output [dst + 2] = (byte)input.GetBits(8);
                if (input.GetNextBit() > 0)
                {
                    int copy_dst = dst;
                    for (;;)
                    {
                        int ctl = input.GetBits(2);
                        if (0 == ctl)
                        {
                            if (input.GetNextBit() <= 0)
                            {
                                break;
                            }
                            if (input.GetNextBit() > 0)
                            {
                                copy_dst += (width + 2) * 3;
                            }
                            else
                            {
                                copy_dst += (width - 2) * 3;
                            }
                        }
                        else if (1 == ctl)
                        {
                            copy_dst += (width - 1) * 3;
                        }
                        else if (2 == ctl)
                        {
                            copy_dst += width * 3;
                        }
                        else if (3 == ctl)
                        {
                            copy_dst += (width + 1) * 3;
                        }
                        else if (-1 == ctl)
                        {
                            break;
                        }
                        m_output[copy_dst]     = m_output[dst];
                        m_output[copy_dst + 1] = m_output[dst + 1];
                        m_output[copy_dst + 2] = m_output[dst + 2];
                    }
                }
                dst += 3;
            }
            byte b = 0, g = 0, r = 0;

            for (dst = 0; dst < m_output.Length; dst += 3)
            {
                if (0xFF == m_output[dst] && 0xFF == m_output[dst + 1] && 0xFF == m_output[dst + 2])
                {
                    m_output[dst]     = b;
                    m_output[dst + 1] = g;
                    m_output[dst + 2] = r;
                }
                else
                {
                    b = m_output[dst];
                    g = m_output[dst + 1];
                    r = m_output[dst + 2];
                }
            }
        }
Exemplo n.º 12
0
        void UncompressRgba(IBitStream input, byte[] output)
        {
            int stride   = 4 * m_width;
            int q        = CompressInfo[0];
            int b_bits   = CompressInfo[4];
            int g_bits   = CompressInfo[5];
            int r_bits   = CompressInfo[6];
            int b_shift  = 8 - b_bits;
            int g_shift  = 16 - g_bits;
            int r_shift  = 24 - r_bits;
            int dst_pos  = m_y * stride + m_x * 4;
            int baseline = 0xFF >> b_bits | (0xFF >> g_bits | (0xFF >> r_bits << 8)) << 8;
            var line_buf = new int[m_w];

            for (int y = 0; y < m_h; ++y)
            {
                int  alpha        = 0;
                int  rgb          = 0;
                int  repeat_count = 0;
                bool repeat       = true;
                int  dst          = dst_pos + y * stride;
                int  x            = 0;
                int  chunk_size   = 0;
                while (x < m_w)
                {
                    if (0 == chunk_size)
                    {
                        int alpha_inc = 0;
                        if (input.GetNextBit() > 0)
                        {
                            alpha_inc = GetSigned(input);
                        }
                        alpha += alpha_inc;
                        if (0 == alpha || 31 == alpha)
                        {
                            chunk_size = GetInt(input);
                        }
                    }
                    if (alpha != 0)
                    {
                        if (31 == alpha)
                        {
                            --chunk_size;
                        }
                        if (0 == repeat_count)
                        {
                            repeat_count = GetInt(input);
                            repeat       = !repeat;
                        }
                        --repeat_count;
                        if (!repeat)
                        {
                            if (input.GetNextBit() > 0)
                            {
                                rgb = line_buf[x];
                            }
                            else
                            {
                                int g = 0;
                                if (input.GetNextBit() > 0)
                                {
                                    g = GetSigned(input);
                                }
                                int b_inc = 0;
                                if (input.GetNextBit() > 0)
                                {
                                    bool sign = input.GetNextBit() > 0;
                                    int  v    = GetInt(input);
                                    b_inc = tblQuantTransfer[q, v];
                                    if (sign)
                                    {
                                        b_inc = -b_inc;
                                    }
                                }
                                int r_inc = 0;
                                if (input.GetNextBit() > 0)
                                {
                                    bool sign = input.GetNextBit() > 0;
                                    int  v    = GetInt(input);
                                    r_inc = tblQuantTransfer[q, v];
                                    if (sign)
                                    {
                                        r_inc = -r_inc;
                                    }
                                }
                                int c1 = (0xFF >> b_shift) & (int)((uint)rgb >> b_shift);
                                c1 = -c1;
                                if (g >= c1)
                                {
                                    int c2 = (0xFF >> b_shift) + c1;
                                    c1 = g;
                                    if (g > c2)
                                    {
                                        c1 = c2;
                                    }
                                }
                                int b = c1 + b_inc;
                                c1 = (0xFF0000 >> r_shift) & (int)((uint)rgb >> r_shift);
                                c1 = -c1;
                                if (g >= c1)
                                {
                                    int c2 = (0xFF0000 >> r_shift) + c1;
                                    c1 = g;
                                    if (g > c2)
                                    {
                                        c1 = c2;
                                    }
                                }
                                int r = c1 + r_inc;
                                rgb += (b << b_shift) + (r << r_shift) + (g << g_shift);
                            }
                        }
                        uint pixel = (uint)(baseline + rgb);
                        if (31 == alpha)
                        {
                            pixel |= 0xFF000000u;
                        }
                        else
                        {
                            pixel |= (uint)(alpha << 27);
                        }
                        LittleEndian.Pack(pixel, output, dst);
                        dst          += 4;
                        line_buf[x++] = rgb;
                    }
                    else
                    {
                        dst       += 4 * chunk_size;
                        x         += chunk_size;
                        chunk_size = 0;
                    }
                }
            }
        }
Exemplo n.º 13
0
        void UncompressRgb(IBitStream input, byte[] output)
        {
            int  stride    = m_width * 4;
            int  q         = CompressInfo[0];
            int  b_bits    = CompressInfo[4];
            int  g_bits    = CompressInfo[5];
            int  r_bits    = CompressInfo[6];
            bool is_bgr676 = 6 == b_bits && 7 == g_bits && 6 == r_bits;
            int  b_shift   = 8 - b_bits;
            int  g_shift   = 16 - g_bits;
            int  r_shift   = 24 - r_bits;
            int  baseline  = 0xFF >> b_bits | (0xFF >> g_bits | (0xFF >> r_bits | 0xFF00) << 8) << 8;
            {
                for (int y = 0; y < m_height; ++y)
                {
                    int rgb = 0, rgb_ = 0;
                    int dst = y * stride;
                    int x   = 0;
                    while (x < m_width)
                    {
                        int count = GetInt(input);
                        x += count;
                        do
                        {
                            if (input.GetNextBit() > 0)
                            {
                                rgb = LittleEndian.ToInt32(output, dst - stride);
                                if (rgb != 0)
                                {
                                    rgb -= baseline;
                                }
                                rgb_ = rgb;
                            }
                            else
                            {
                                int r = 0, g = 0, b = 0;
                                if (input.GetNextBit() > 0)
                                {
                                    g = GetSigned(input);
                                }
                                int b_inc = 0;
                                if (input.GetNextBit() > 0)
                                {
                                    bool sign = input.GetNextBit() > 0;
                                    int  v    = GetInt(input);
                                    b_inc = tblQuantTransfer[q, v];
                                    if (sign)
                                    {
                                        b_inc = -b_inc;
                                    }
                                }
                                int r_inc = 0;
                                if (input.GetNextBit() > 0)
                                {
                                    bool sign = input.GetNextBit() > 0;
                                    int  v    = GetInt(input);
                                    r_inc = tblQuantTransfer[q, v];
                                    if (sign)
                                    {
                                        r_inc = -r_inc;
                                    }
                                }
                                int gg = g;
                                if (is_bgr676)
                                {
                                    gg >>= 1;
                                }
                                if (CompressInfo[3] != 0)
                                {
                                    int c1 = (0xFF >> b_shift) & (int)((uint)rgb_ >> b_shift);
                                    c1 = -c1;
                                    if (gg >= c1)
                                    {
                                        int c2 = (0xFF >> b_shift) + c1;
                                        c1 = c2;
                                        if (gg <= c2)
                                        {
                                            c1 = gg;
                                        }
                                    }
                                    b  = c1 + b_inc;
                                    c1 = (0xFF0000 >> r_shift) & (int)((uint)rgb_ >> r_shift);
                                    c1 = -c1;
                                    if (gg >= c1)
                                    {
                                        int c2 = (0xFF0000 >> r_shift) + c1;
                                        c1 = c2;
                                        if (gg <= c2)
                                        {
                                            c1 = gg;
                                        }
                                    }
                                    r = c1 + r_inc;
                                }
                                else
                                {
                                    b = gg + b_inc;
                                    r = gg + r_inc;
                                }
                                rgb_ += (b << b_shift) + (r << r_shift) + (g << g_shift);
                                rgb   = rgb_;
                            }
                            if (rgb != 0)
                            {
                                rgb += baseline;
                            }
                            LittleEndian.Pack(rgb, output, dst);
                            dst += 4;
                            --count;
                        }while (count > 0);
                        if (x >= m_width)
                        {
                            break;
                        }

                        count = GetInt(input);
                        x    += count;
                        while (count-- > 0)
                        {
                            LittleEndian.Pack(rgb, output, dst);
                            dst += 4;
                        }
                    }
                }
            }
        }
Exemplo n.º 14
0
        int ReadLong(IBitStream input, int prev)
        {
            prev &= 0xFC;
            if ((prev >> 2) == 0)
            {
                if (input.GetNextBit() == 0)
                {
                    return(prev);
                }
                else if (input.GetNextBit() == 0)
                {
                    return(input.GetBits(6) << 2);
                }
                else if (input.GetNextBit() == 0)
                {
                    return(4);
                }
                else if (input.GetNextBit() == 0)
                {
                    return(8);
                }
                else
                {
                    return(12);
                }
            }
            else if ((prev >> 2) == 1)
            {
                if (input.GetNextBit() == 0)
                {
                    return(input.GetNextBit() << 2);
                }
                else if (input.GetNextBit() == 0)
                {
                    return(input.GetBits(6) << 2);
                }
                else if (input.GetNextBit() == 0)
                {
                    return(8);
                }
                else if (input.GetNextBit() == 0)
                {
                    return(12);
                }
                else
                {
                    return(16);
                }
            }
            else if ((prev >> 2) == 0x3F)
            {
                if (input.GetNextBit() == 0)
                {
                    return(0xFC);
                }
                else if (input.GetNextBit() == 0)
                {
                    return(input.GetBits(6) << 2);
                }
                else if (input.GetNextBit() != 0)
                {
                    return(0xF4 + (-input.GetNextBit() & 0xFC));
                }
                else
                {
                    return(0xF8);
                }
            }
            else
            {
                if (input.GetNextBit() == 0)
                {
                    if (input.GetNextBit() == 0)
                    {
                        return(prev);
                    }
                    return(input.GetBits(6) << 2);
                }
                if (input.GetNextBit() == 0)
                {
                    if (input.GetNextBit() != 0)
                    {
                        return(prev - 4);
                    }
                    else
                    {
                        return(prev + 4);
                    }
                }
                if (input.GetNextBit() == 0)
                {
                    if (input.GetNextBit() != 0)
                    {
                        return(prev - 8);
                    }
                    else
                    {
                        return(prev + 8);
                    }
                }
                switch (input.GetBits(2))
                {
                case 0:  return(Math.Min(prev + 16, 0xFC));

                case 1:  return(Math.Max(prev - 16, 0));

                case 2:  return(Math.Min(prev + 24, 0xFC));

                default: return(Math.Max(prev - 24, 0));
                }
            }
        }
Exemplo n.º 15
0
 public int DecodeToken(IBitStream input)
 {
     int node_index = m_nodes.Length-1;
     do
     {
         int bit = input.GetNextBit();
         if (-1 == bit)
             throw new EndOfStreamException();
         if (0 == bit)
             node_index = m_nodes[node_index].LeftChildIndex;
         else
             node_index = m_nodes[node_index].RightChildIndex;
     }
     while (m_nodes[node_index].IsParent);
     return node_index;
 }