protected int fillInternalBuffer() throws IOException {
        int numRead = 0;
        // start decompression,  haven't tried to optimized this one yet for
        // speed or for memory.

        if (firstTime) {
            firstTime = false;
            old_code = code = inb.getBits(code_len);
        } else if (inb.atEndOfFile())
            return -1;

        do {
            if (code == 256) {
                initCodeTable();
            } else if (code == 257) {
                break;
            } else {
                if (codes[code] != null) {
                    Stack stack = new Stack();
                    codes[code].getString(stack);
                    Code c = (Code) stack.pop();
                    addToBuffer(c.c, numRead);
                    numRead++;
                    //System.err.println((char)c.c);
                    byte first = c.c;
                    while (!stack.empty()) {
                        c = (Code) stack.pop();
                        addToBuffer(c.c, numRead);
                        numRead++;
                        //System.err.println((char)c.c);
                    }
                    //							while (codes[last_code]!=null) last_code++;
                    codes[last_code++] = new Code(codes[old_code], first);
                } else {
                    //System.err.println("MISS: "+last_code+" "+code);
                    if (code != last_code)
                        throw new RuntimeException("LZWDecode failure");
                    Stack stack = new Stack();
                    codes[old_code].getString(stack);
                    Code c = (Code) stack.pop();
                    addToBuffer(c.c, numRead);
                    numRead++;
                    //System.err.println((char)c.c);
                    byte first = c.c;
                    while (!stack.empty()) {
                        c = (Code) stack.pop();
                        addToBuffer(c.c, numRead);
                        numRead++;
                        //System.err.println((char)c.c);
                    }
                    addToBuffer(first, numRead);
                    numRead++;
                    codes[code] = new Code(codes[old_code], first);
                    last_code++;
                }
            }
            if (code_len < 12 && last_code == (1 << code_len) - earlyChange) {
                //System.err.println(last_code+" "+code_len);
                code_len++;
            }
            old_code = code;
            code = inb.getBits(code_len);

            if (inb.atEndOfFile())
                break;
        } while (numRead < (buffer.length - 512));

        return numRead;
    }