static int GetInt(IBitStream input) { int n = 1; while (input.GetNextBit() > 0) { n <<= 1; n |= input.GetNextBit(); } return(n); }
static int GetSigned(IBitStream input) { bool sign = input.GetNextBit() > 0; int n = GetInt(input); return(sign ? -n : n); }
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); }
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)); } } }
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)); } } }
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); }
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); }
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; } } }
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; } } } }
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++; } } }
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]; } } }
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; } } } }
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; } } } } }
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)); } } }
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; }