protected Header readHeaderFromBuffer(ByteBuffer buffer) throws WWRuntimeException {
    // Read file code - first byte
    int fileCode = buffer.get();
    if (fileCode > 5) {
      String message = Logging.getMessage("SHP.NotADBaseFile", file.getPath());
      Logging.logger().log(java.util.logging.Level.SEVERE, message);
      throw new WWRuntimeException(message);
    }

    // Last update date
    int yy = 0xFF & buffer.get(); // unsigned
    int mm = buffer.get();
    int dd = buffer.get();

    // Number of records
    int numRecords = buffer.getInt();

    // Header struct length
    int headerLength = buffer.getShort();

    // Record length
    int recordLength = buffer.getShort();

    // Assemble header
    Header header = new Header();
    header.fileCode = fileCode;
    Calendar cal = Calendar.getInstance();
    cal.set(1900 + yy, mm - 1, dd);
    header.lastModificationDate = cal.getTime();
    header.numberOfRecords = numRecords;
    header.headerLength = headerLength;
    header.recordLength = recordLength;

    return header;
  }
  protected Header readHeaderFromStream(InputStream is) throws IOException {
    ReadableByteChannel channel = Channels.newChannel(is);
    // Read header fixed portion
    ByteBuffer headerBuffer = ShapefileUtils.readByteChannelToBuffer(channel, FIXED_HEADER_LENGTH);
    Header header = this.readHeaderFromBuffer(headerBuffer);
    // Read fields description header
    int fieldsHeaderLength = header.headerLength - FIXED_HEADER_LENGTH;
    header.fieldsHeaderBuffer = ShapefileUtils.readByteChannelToBuffer(channel, fieldsHeaderLength);

    return header;
  }