static int zhuffman_decode_slowpath(zbuf a, zhuffman z) { int b, s, k; // not resolved by fast table, so compute it the slow way // use jpeg approach, which requires MSbits at top k = bit_reverse((int)a.code_buffer, 16); for (s = ZFAST_BITS + 1; ; ++s) { if (k < z.maxcode[s]) { break; } } if (s == 16) { return(-1); // invalid code! } // code size is s, so: b = (k >> (16 - s)) - z.firstcode[s] + z.firstsymbol[s]; Debug.Assert(z.size[b] == s); a.code_buffer >>= s; a.num_bits -= s; return(z.value[b]); }
static int zbuild_huffman(zhuffman z, byte[] sizelist, int num, int sizelistOffset = 0) { int i, k = 0; int code; int[] next_code = new int[16]; int[] sizes = new int[17]; // DEFLATE spec for generating codes Array.Clear(z.fast, 0, z.fast.Length); for (i = 0; i < num; ++i) { ++sizes[sizelist[i + sizelistOffset]]; } sizes[0] = 0; for (i = 1; i < 16; ++i) { Debug.Assert(sizes[i] <= (1 << i)); } code = 0; for (i = 1; i < 16; ++i) { next_code[i] = code; z.firstcode[i] = (ushort)code; z.firstsymbol[i] = (ushort)k; code = (code + sizes[i]); if (sizes[i] != 0) { if (code - 1 >= (1 << i)) { throw new Exception("bad codelengths,Corrupt JPEG"); } } z.maxcode[i] = code << (16 - i); // preshift for inner loop code <<= 1; k += sizes[i]; } z.maxcode[16] = 0x10000; // sentinel for (i = 0; i < num; ++i) { int s = sizelist[i + sizelistOffset]; if (s != 0) { int c = next_code[s] - z.firstcode[s] + z.firstsymbol[s]; ushort fastv = (ushort)((s << 9) | i); z.size[c] = (byte)s; z.value[c] = (ushort)i; if (s <= ZFAST_BITS) { int kk = bit_reverse(next_code[s], s); while (kk < (1 << ZFAST_BITS)) { z.fast[kk] = fastv; kk += (1 << s); } } ++next_code[s]; } } return(1); }
static int compute_huffman_codes(zbuf a) { zhuffman z_codelength = new zhuffman(); byte[] lencodes = new byte[286 + 32 + 137];//padding for maximum single op byte[] codelength_sizes = new byte[19]; int i, n; int hlit = (int)zreceive(a, 5) + 257; int hdist = (int)zreceive(a, 5) + 1; int hclen = (int)zreceive(a, 4) + 4; for (i = 0; i < hclen; ++i) { int s = (int)zreceive(a, 3); codelength_sizes[length_dezigzag[i]] = (byte)s; } if (zbuild_huffman(z_codelength, codelength_sizes, 19) == 0) return 0; n = 0; while (n < hlit + hdist) { int c = zhuffman_decode(a, z_codelength); Debug.Assert(c >= 0 && c < 19); if (c < 16) lencodes[n++] = (byte)c; else if (c == 16) { c = (int)zreceive(a, 2) + 3; { byte value = lencodes[n - 1]; int last = n + c; for (int idx = n; idx < last; idx++) lencodes[idx] = value; } n += c; } else if (c == 17) { c = (int)zreceive(a, 3) + 3; Array.Clear(lencodes, n, c); n += c; } else { Debug.Assert(c == 18); c = (int)zreceive(a, 7) + 11; Array.Clear(lencodes, n, c); n += c; } } if (n != hlit + hdist) throw new Exception("bad codelengths,Corrupt PNG"); if (zbuild_huffman(a.z_length, lencodes, hlit) == 0) return 0; if (zbuild_huffman(a.z_distance, lencodes, hdist, hlit) == 0) return 0; return 1; }
static int zhuffman_decode(zbuf a, zhuffman z) { int b, s; if (a.num_bits < 16) { fill_bits(a); } b = z.fast[a.code_buffer & ZFAST_MASK]; if (b != 0) { s = b >> 9; a.code_buffer >>= s; a.num_bits -= s; return(b & 511); } return(zhuffman_decode_slowpath(a, z)); }
static int zhuffman_decode_slowpath(zbuf a, zhuffman z) { int b, s, k; // not resolved by fast table, so compute it the slow way // use jpeg approach, which requires MSbits at top k = bit_reverse((int)a.code_buffer, 16); for (s = ZFAST_BITS + 1; ; ++s) if (k < z.maxcode[s]) break; if (s == 16) return -1; // invalid code! // code size is s, so: b = (k >> (16 - s)) - z.firstcode[s] + z.firstsymbol[s]; Debug.Assert(z.size[b] == s); a.code_buffer >>= s; a.num_bits -= s; return z.value[b]; }
static int zhuffman_decode(zbuf a, zhuffman z) { int b, s; if (a.num_bits < 16) fill_bits(a); b = z.fast[a.code_buffer & ZFAST_MASK]; if (b != 0) { s = b >> 9; a.code_buffer >>= s; a.num_bits -= s; return b & 511; } return zhuffman_decode_slowpath(a, z); }
static int zbuild_huffman(zhuffman z, byte[] sizelist, int num, int sizelistOffset = 0) { int i, k = 0; int code; int[] next_code = new int[16]; int[] sizes = new int[17]; // DEFLATE spec for generating codes Array.Clear(z.fast, 0, z.fast.Length); for (i = 0; i < num; ++i) ++sizes[sizelist[i + sizelistOffset]]; sizes[0] = 0; for (i = 1; i < 16; ++i) Debug.Assert(sizes[i] <= (1 << i)); code = 0; for (i = 1; i < 16; ++i) { next_code[i] = code; z.firstcode[i] = (ushort)code; z.firstsymbol[i] = (ushort)k; code = (code + sizes[i]); if (sizes[i] != 0) if (code - 1 >= (1 << i)) throw new Exception("bad codelengths,Corrupt JPEG"); z.maxcode[i] = code << (16 - i); // preshift for inner loop code <<= 1; k += sizes[i]; } z.maxcode[16] = 0x10000; // sentinel for (i = 0; i < num; ++i) { int s = sizelist[i + sizelistOffset]; if (s != 0) { int c = next_code[s] - z.firstcode[s] + z.firstsymbol[s]; ushort fastv = (ushort)((s << 9) | i); z.size[c] = (byte)s; z.value[c] = (ushort)i; if (s <= ZFAST_BITS) { int kk = bit_reverse(next_code[s], s); while (kk < (1 << ZFAST_BITS)) { z.fast[kk] = fastv; kk += (1 << s); } } ++next_code[s]; } } return 1; }
static int compute_huffman_codes(zbuf a) { zhuffman z_codelength = new zhuffman(); byte[] lencodes = new byte[286 + 32 + 137];//padding for maximum single op byte[] codelength_sizes = new byte[19]; int i, n; int hlit = (int)zreceive(a, 5) + 257; int hdist = (int)zreceive(a, 5) + 1; int hclen = (int)zreceive(a, 4) + 4; for (i = 0; i < hclen; ++i) { int s = (int)zreceive(a, 3); codelength_sizes[length_dezigzag[i]] = (byte)s; } if (zbuild_huffman(z_codelength, codelength_sizes, 19) == 0) { return(0); } n = 0; while (n < hlit + hdist) { int c = zhuffman_decode(a, z_codelength); Debug.Assert(c >= 0 && c < 19); if (c < 16) { lencodes[n++] = (byte)c; } else if (c == 16) { c = (int)zreceive(a, 2) + 3; { byte value = lencodes[n - 1]; int last = n + c; for (int idx = n; idx < last; idx++) { lencodes[idx] = value; } } n += c; } else if (c == 17) { c = (int)zreceive(a, 3) + 3; Array.Clear(lencodes, n, c); n += c; } else { Debug.Assert(c == 18); c = (int)zreceive(a, 7) + 11; Array.Clear(lencodes, n, c); n += c; } } if (n != hlit + hdist) { throw new Exception("bad codelengths,Corrupt PNG"); } if (zbuild_huffman(a.z_length, lencodes, hlit) == 0) { return(0); } if (zbuild_huffman(a.z_distance, lencodes, hdist, hlit) == 0) { return(0); } return(1); }