private int stbi__zhuffman_decode(stbi__zhuffman z) { var b = 0; var s = 0; if (num_bits < 16) { stbi__fill_bits(); } b = z.fast[code_buffer & ((1 << 9) - 1)]; if (b != 0) { s = b >> 9; code_buffer >>= s; num_bits -= s; return(b & 511); } return(stbi__zhuffman_decode_slowpath(z)); }
private int stbi__zhuffman_decode_slowpath(stbi__zhuffman z) { var b = 0; var s = 0; var k = 0; k = MathExtensions.stbi__bit_reverse((int)code_buffer, 16); for (s = 9 + 1; ; ++s) { if (k < z.maxcode[s]) { break; } } if (s == 16) { return(-1); } b = (k >> (16 - s)) - z.firstcode[s] + z.firstsymbol[s]; code_buffer >>= s; num_bits -= s; return(z.value[b]); }
public static int stbi__compute_huffman_codes(stbi__zbuf *a) { var z_codelength = new stbi__zhuffman(); var lencodes = stackalloc byte[286 + 32 + 137]; var codelength_sizes = stackalloc byte[19]; var i = 0; var n = 0; var hlit = (int)(stbi__zreceive(a, 5) + 257); var hdist = (int)(stbi__zreceive(a, 5) + 1); var hclen = (int)(stbi__zreceive(a, 4) + 4); var ntot = hlit + hdist; CRuntime.memset(codelength_sizes, 0, (ulong)(19 * sizeof(byte))); for (i = 0; i < hclen; ++i) { var s = (int)stbi__zreceive(a, 3); codelength_sizes[length_dezigzag[i]] = (byte)s; } if (stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19) == 0) { return(0); } n = 0; while (n < ntot) { var c = stbi__zhuffman_decode(a, &z_codelength); if (c < 0 || c >= 19) { return(stbi__err("bad codelengths")); } if (c < 16) { lencodes[n++] = (byte)c; } else { var fill = (byte)0; if (c == 16) { c = (int)(stbi__zreceive(a, 2) + 3); if (n == 0) { return(stbi__err("bad codelengths")); } fill = lencodes[n - 1]; } else if (c == 17) { c = (int)(stbi__zreceive(a, 3) + 3); } else { c = (int)(stbi__zreceive(a, 7) + 11); } if (ntot - n < c) { return(stbi__err("bad codelengths")); } CRuntime.memset(lencodes + n, fill, (ulong)c); n += c; } } if (n != ntot) { return(stbi__err("bad codelengths")); } if (stbi__zbuild_huffman(&a->z_length, lencodes, hlit) == 0) { return(0); } if (stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist) == 0) { return(0); } return(1); }
private int stbi__compute_huffman_codes() { var z_codelength = new stbi__zhuffman(); var lencodes = new byte[286 + 32 + 137]; var codelength_sizes = new byte[19]; var i = 0; var n = 0; var hlit = (int)(stbi__zreceive(5) + 257); var hdist = (int)(stbi__zreceive(5) + 1); var hclen = (int)(stbi__zreceive(4) + 4); var ntot = hlit + hdist; codelength_sizes.Clear(); for (i = 0; i < hclen; ++i) { var s = (int)stbi__zreceive(3); codelength_sizes[length_dezigzag[i]] = (byte)s; } if (stbi__zbuild_huffman(z_codelength, new FakePtr <byte>(codelength_sizes), 19) == 0) { return(0); } n = 0; while (n < ntot) { var c = stbi__zhuffman_decode(z_codelength); if (c < 0 || c >= 19) { Decoder.stbi__err("bad codelengths"); } if (c < 16) { lencodes[n++] = (byte)c; } else { var fill = (byte)0; if (c == 16) { c = (int)(stbi__zreceive(2) + 3); if (n == 0) { Decoder.stbi__err("bad codelengths"); } fill = lencodes[n - 1]; } else if (c == 17) { c = (int)(stbi__zreceive(3) + 3); } else { c = (int)(stbi__zreceive(7) + 11); } if (ntot - n < c) { Decoder.stbi__err("bad codelengths"); } lencodes.Set(n, c, fill); n += c; } } if (n != ntot) { Decoder.stbi__err("bad codelengths"); } if (stbi__zbuild_huffman(z_length, new FakePtr <byte>(lencodes), hlit) == 0) { return(0); } if (stbi__zbuild_huffman(z_distance, new FakePtr <byte>(lencodes, hlit), hdist) == 0) { return(0); } return(1); }
private static int stbi__zbuild_huffman(stbi__zhuffman z, FakePtr <byte> sizelist, int num) { var i = 0; var k = 0; var code = 0; var next_code = new int[16]; var sizes = new int[17]; sizes.Clear(); z.fast.Clear(); for (i = 0; i < num; ++i) { ++sizes[sizelist[i]]; } sizes[0] = 0; for (i = 1; i < 16; ++i) { if (sizes[i] > 1 << i) { Decoder.stbi__err("bad sizes"); } } 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) { Decoder.stbi__err("bad codelengths"); } } z.maxcode[i] = code << (16 - i); code <<= 1; k += sizes[i]; } z.maxcode[16] = 0x10000; for (i = 0; i < num; ++i) { var s = (int)sizelist[i]; if (s != 0) { var c = next_code[s] - z.firstcode[s] + z.firstsymbol[s]; var fastv = (ushort)((s << 9) | i); z.size[c] = (byte)s; z.value[c] = (ushort)i; if (s <= 9) { var j = MathExtensions.stbi__bit_reverse(next_code[s], s); while (j < 1 << 9) { z.fast[j] = fastv; j += 1 << s; } } ++next_code[s]; } } return(1); }
//todo continue check static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__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 = stbi__bit_reverse((int)a->code_buffer, 16); for (s = STBI__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 stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) { int b, s; if (a->num_bits < 16) stbi__fill_bits(a); b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; if (b != 0) { s = b >> 9; a->code_buffer >>= s; a->num_bits -= s; return b & 511; } return stbi__zhuffman_decode_slowpath(a, z); }
static int stbi__zbuild_huffman(stbi__zhuffman* z, byte* sizelist, int num) { int i; int k = 0; int code; int* next_code = stackalloc int[16]; int* sizes = stackalloc int[17]; // DEFLATE spec for generating codes CLib.CString.memset(sizes, 0, 17 * 4); CLib.CString.memset(z->fast, 0, (1 << STBI__ZFAST_BITS) * 2); for (i = 0; i < num; ++i) ++sizes[sizelist[i]]; sizes[0] = 0; for (i = 1; i < 16; ++i) if (sizes[i] > (1 << i)) throw new Exception("bad sizes:Corrupt PNG"); 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 PNG"); 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]; 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 <= STBI__ZFAST_BITS) { int kk = stbi__bit_reverse(next_code[s], s); while (kk < (1 << STBI__ZFAST_BITS)) { z->fast[kk] = fastv; kk += (1 << s); } } ++next_code[s]; } } return 1; }