private static void addLookupTreeNode(
     short code, NonLeafLookupTreeNode root, LookupTreeNode leaf) {
   int codeLength = code >> 8;
   int pattern = code & 0xFF;
   NonLeafLookupTreeNode node = root;
   for (int p = codeLength - 1; p > 0; p--) {
     int bit = (pattern >> p) & 0x01;
     LookupTreeNode child = node.get(bit);
     if (child == null) {
       child = new NonLeafLookupTreeNode();
       node.set(bit, child);
     }
     if (child instanceof NonLeafLookupTreeNode) {
       node = (NonLeafLookupTreeNode) child;
     } else {
       throw new IllegalStateException(
           "NonLeafLookupTreeNode expected, was " + child.getClass().getName());
     }
   }
   int bit = pattern & 0x01;
   if (node.get(bit) != null) {
     throw new IllegalStateException("Two codes conflicting in lookup tree");
   }
   node.set(bit, leaf);
 }
 public CodeWord getNextCodeWord(CCITTFaxG31DDecodeInputStream decoder) throws IOException {
   int bit = decoder.readBit();
   if (bit < 0) {
     return null;
   }
   LookupTreeNode node = get(bit);
   if (node != null) {
     return node.getNextCodeWord(decoder);
   }
   throw new IOException("Invalid code word encountered");
 }
 private boolean decodeLine() throws IOException {
   if (encodedByteAlign && this.bitPos != 0) {
     readByte();
   }
   if (this.bits < 0) {
     return false; // Shortcut after EOD
   }
   this.y++;
   // System.out.println("decodeLine " + this.y);
   int x = 0;
   if (this.rows > 0 && this.y >= this.rows) {
     return false; // All rows decoded, ignore further bits
   }
   this.decodedLine.clear();
   this.decodedWritePos = 0;
   int expectRTC = 6;
   boolean white = true;
   while (x < this.columns || this.accumulatedRunLength > 0) {
     CodeWord code;
     LookupTreeNode root = white ? WHITE_LOOKUP_TREE_ROOT : BLACK_LOOKUP_TREE_ROOT;
     code = root.getNextCodeWord(this);
     if (code == null) {
       // no more code words (EOD)
       if (x > 0) {
         // Have last line
         this.decodedReadPos = 0;
         return true;
       } else {
         return false;
       }
     } else if (code.getType() == SIGNAL_EOL) {
       expectRTC--;
       if (expectRTC == 0) {
         // System.out.println("Return to Control");
         return false; // Return to Control = End Of Data
       }
       if (x == 0) {
         // System.out.println("Ignoring leading EOL");
         continue; // Ignore leading EOL
       }
     } else {
       expectRTC = -1;
       x += code.execute(this);
       if (this.accumulatedRunLength == 0) {
         // Only switch if not using make-up codes
         white = !white;
       }
     }
   }
   this.decodedReadPos = 0;
   return true;
 }