/**
  * 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;
     }
 }