public final void readInputStream(InputStream input) throws IOException, ID3ReaderException {
    int rc;
    readerPosition = 0;
    char[] tagHeaderSource = readBytes(input, HEADER_LENGTH);
    tagHeader = createTagHeader(tagHeaderSource);
    if (tagHeader == null) {
      onNoTagHeaderFound();
    } else {
      rc = onStartTagHeader(tagHeader);
      if (rc == ACTION_SKIP) {
        onEndTag();
      } else {
        while (readerPosition < tagHeader.getSize()) {
          FrameHeader frameHeader = createFrameHeader(readBytes(input, HEADER_LENGTH));
          if (checkForNullString(frameHeader.getId())) {
            break;
          } else {
            rc = onStartFrameHeader(frameHeader, input);
            if (rc == ACTION_SKIP) {

              if (frameHeader.getSize() + readerPosition > tagHeader.getSize()) {
                break;
              } else {
                skipBytes(input, frameHeader.getSize());
              }
            }
          }
        }
        onEndTag();
      }
    }
  }
  private FrameHeader createFrameHeader(char[] source) throws ID3ReaderException {
    if (source.length != HEADER_LENGTH) {
      throw new ID3ReaderException("Length of header must be " + HEADER_LENGTH);
    }
    String id = new String(source, 0, FRAME_ID_LENGTH);

    int size =
        (((int) source[4]) << 24)
            | (((int) source[5]) << 16)
            | (((int) source[6]) << 8)
            | source[7];
    if (tagHeader != null && tagHeader.getVersion() >= 0x0400) {
      size = unsynchsafe(size);
    }
    char flags = (char) ((source[8] << 8) | source[9]);
    return new FrameHeader(id, size, flags);
  }