/** * Reads the next symbol from input. The symbol is encoded using the * huffman tree. * @param input the input source. * @return the next symbol, or -1 if not enough input is available. */ public int getSymbol(StreamManipulator input) { int lookahead, symbol; if ((lookahead = input.peekBits(9)) >= 0) { if ((symbol = tree[lookahead]) >= 0) { input.dropBits(symbol & 15); return symbol >> 4; } int subtree = -(symbol >> 4); int bitlen = symbol & 15; if ((lookahead = input.peekBits(bitlen)) >= 0) { symbol = tree[subtree | (lookahead >> 9)]; input.dropBits(symbol & 15); return symbol >> 4; } else { int bits = input.getAvailableBits(); lookahead = input.peekBits(bits); symbol = tree[subtree | (lookahead >> 9)]; if ((symbol & 15) <= bits) { input.dropBits(symbol & 15); return symbol >> 4; } else return -1; } } else { int bits = input.getAvailableBits(); lookahead = input.peekBits(bits); symbol = tree[lookahead]; if (symbol >= 0 && (symbol & 15) <= bits) { input.dropBits(symbol & 15); return symbol >> 4; } else return -1; } }