private void readHeader() throws IOException {
        CheckedInputStream in = new CheckedInputStream(this.in, crc);
        crc.reset();
        // Check header magic
        if (readUShort(in) != GZIP_MAGIC) {
            throw new IOException("Not in GZIP format");
        }
        // Check compression method
        if (readUByte(in) != 8) {
            throw new IOException("Unsupported compression method");
        }
        // Read flags
        int flg = readUByte(in);
        // Skip MTIME, XFL, and OS fields
        skipBytes(in, 6);
        // Skip optional extra field
        if ((flg & FEXTRA) == FEXTRA) {
            skipBytes(in, readUShort(in));
        }
        // Skip optional file name
        if ((flg & FNAME) == FNAME) {
            while (readUByte(in) != 0) ;
        }
        // Skip optional file comment
        if ((flg & FCOMMENT) == FCOMMENT) {
            while (readUByte(in) != 0) ;
        }
        // Check optional header CRC
        if ((flg & FHCRC) == FHCRC) {
            int v = (int) crc.getValue() & 0xffff;
            if (readUShort(in) != v) {
                throw new IOException("Corrupt GZIP header");
            }
        }
    }