// ID3v2ExtendedHeader.java // // $Id: ID3v2ExtendedHeader.java,v 1.3 2008/01/03 04:35:51 dmitriy Exp $ // // de.vdheide.mp3: Access MP3 properties, ID3 and ID3v2 tags // Copyright (C) 1999 Jens Vonderheide <jens@vdheide.de> // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the // Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. /** * This class contains an ID3v2 extended header */ package de.vdheide.mp3; import java.io.IOException; import java.io.Serializable; public class ID3v2ExtendedHeader implements Serializable { /********** Constructors **********/ /** * Creates an extended header with preferences * * @params head Header an array of bytes */ public ID3v2ExtendedHeader() { this(false, 0, 0); } /** * Creates an extended header * * @param use_crc Use CRC? * @param crc CRC of frames (will be set to 0 if <code>use_crc</code> == false) * @param padding_size Size of padding */ public ID3v2ExtendedHeader(boolean use_crc, int crc, int padding_size) { // TODO needs to be revised accordingly http://www.id3.org/id3v2.4.0-structure crc_present = use_crc; if (crc_present == true) { this.crc = crc; } else { this.crc = 0; } this.padding_size = padding_size; } /** * Creates an extended header from a stream. * Stream must be positioned to * the first byte of the extended header. * * @param in Stream to read from * @param use_unsynch If true, unsynchronization is used * @exception IOException If an I/O error occurs */ public ID3v2ExtendedHeader(IOAdapter in) throws IOException { // read ext header byte []head = new byte[10]; in.read(head); // decode size int size = (int)(new Bytes(head, 0, 4).getValue()); // decode extended flags if (((head[4] & 0xff) & FLAG_CRC_PRESENT) > 0) { crc_present = true; } // decode size of padding padding_size = (int)(new Bytes(head, 6, 4).getValue()); // read crc if present if (crc_present == true) { byte []crc_array = new byte[4]; in.read(crc_array); crc = (int)new Bytes(crc_array).getValue(); } } /********** Public methods **********/ /** * @return Size of extended header */ public int getSize() { return (crc_present==true ? 10 : 6); } /** * @return Size of padding */ public int getPaddingSize() { return padding_size; } /** * Set size of padding * * @param size Size of padding */ public void setPaddingSize(int size) { padding_size = size; } /** * @return true if CRC is used */ public boolean hasCRC() { return crc_present; } /** * Set if CRC is used * * @param crc True: CRC is used */ public void setHasCRC(boolean act) { if (act = false) { crc = 0; } crc_present = act; } /** * @return CRC stored in extended header */ public long getCRC() { return crc; } /** * Set CRC. This automatically sets <code>hasCRC</code> * to return <code>true</code>. * * @param crc CRC to set */ public void setCRC(int crc) { this.crc = crc; crc_present = true; } /** * Returns an array of bytes representing this extended header. * <p> * Note: This is not unsynchronized! * * @return Extended header as bytes, ready to write */ public byte []getBytes() { byte ret[]; if (crc_present == true) { // extended header needs 10 + 4 bytes ret = new byte[14]; // write size ret[0] = 0; ret[1] = 0; ret[2] = 0; ret[3] = 10; // write flags ret[4]=(byte)(1 << 7); ret[5]=0; } else { ret = new byte[10]; // write size ret[0] = 0; ret[1] = 0; ret[2] = 0; ret[3] = 10; // write flags ret[4] = 0; ret[5] = 0; } // write size of padding byte []pad_byte = (new Bytes(padding_size, 4)).getBytes(); System.arraycopy(pad_byte, 0, ret, 6, 4); // write crc if present if (crc_present == true) { byte []crc_byte = (new Bytes(crc, 4)).getBytes(); System.arraycopy(crc_byte, 0, ret, 10, 4); } return ret; } /********** Private variables **********/ private int padding_size = 0; private boolean crc_present = false; private int crc = 0; private final static byte FLAG_CRC_PRESENT = (byte)(1<<7); }