public void read(final RandomAccessFile file) throws TagException, IOException { final int size; final byte[] buffer = new byte[4]; if (seek(file) == false) { throw new TagNotFoundException(getIdentifier() + " tag not found"); } // read the major and minor @version number & flags byte file.read(buffer, 0, 3); if ((buffer[0] != 3) || (buffer[1] != 0)) { throw new TagNotFoundException(getIdentifier() + " tag not found"); } setMajorVersion(buffer[0]); setRevision(buffer[1]); this.unsynchronization = (buffer[2] & TagConstant.MASK_V23_UNSYNCHRONIZATION) != 0; this.extended = (buffer[2] & TagConstant.MASK_V23_EXTENDED_HEADER) != 0; this.experimental = (buffer[2] & TagConstant.MASK_V23_EXPERIMENTAL) != 0; // read the size file.read(buffer, 0, 4); size = byteArrayToSize(buffer); final long filePointer = file.getFilePointer(); if (this.extended) { // int is 4 bytes. final int extendedHeaderSize = file.readInt(); // the extended header is only 6 or 10 bytes. if (extendedHeaderSize != 6 && extendedHeaderSize != 10) { throw new InvalidTagException("Invalid Extended Header Size."); } file.read(buffer, 0, 2); this.crcDataFlag = (buffer[0] & TagConstant.MASK_V23_CRC_DATA_PRESENT) != 0; // if it's 10 bytes, the CRC flag must be set // and if it's 6 bytes, it must not be set if (((extendedHeaderSize == 10) && (this.crcDataFlag == false)) || ((extendedHeaderSize == 6) && (this.crcDataFlag == true))) { throw new InvalidTagException("CRC Data flag not set correctly."); } this.paddingSize = file.readInt(); if ((extendedHeaderSize == 10) && this.crcDataFlag) { this.crcData = file.readInt(); } } ID3v2_3Frame next; this.clearFrameMap(); // read all the frames. this.setFileReadBytes(size); AbstractID3v2.resetPaddingCounter(); while ((file.getFilePointer() - filePointer) <= size) { try { next = new ID3v2_3Frame(file, this); final TagIdentifier id = next.getIdentifier(); if (this.hasFrame(id)) { this.appendDuplicateFrameId(id + "; "); this.incrementDuplicateBytes(this.getFrame(id).getSize()); } this.setFrame(next); } catch (InvalidTagException ex) { if (ex.getMessage().equals("Found empty frame")) { this.incrementEmptyFrameBytes(10); } else { this.incrementInvalidFrameBytes(); } } } this.setPaddingSize(getPaddingCounter()); }