View Javadoc

1   /*
2    * Entagged Audio Tag library
3    * Copyright (c) 2003-2005 Raphaël Slinckx <raphael@slinckx.net>
4    * 
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2.1 of the License, or (at your option) any later version.
9    *  
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   * 
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18   */
19  package entagged.audioformats.mp3.util;
20  
21  import java.nio.ByteBuffer;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import entagged.audioformats.Tag;
26  import entagged.audioformats.generic.AbstractTagCreator;
27  import entagged.audioformats.mp3.Id3v2Tag;
28  
29  public class Id3v2TagCreator extends AbstractTagCreator {
30  	/***
31  	 * Default Padding size, when the tag is created from scratch (the old
32  	 * cannot be replaced)
33  	 */
34  	public final static int DEFAULT_PADDING = 4000;
35  
36  	/***
37  	 * This method will return a so called syncsafe integer with the value of
38  	 * the given <code>tempSize</code>.<br>
39  	 * 
40  	 * @param value
41  	 *            The value to be converted.
42  	 * @return A SyncSafe integer as 32-bit byte array.
43  	 */
44  	public static byte[] getSyncSafe(int value) {
45  		assert value >= 0;
46  		byte[] result = new byte[4];
47  		for (int i = 0; i < 4; i++)
48  			result[i] = (byte) (value >> ((3 - i) * 7) & 0x7f);
49  		assert ((result[0] & 0x80) == 0) && ((result[1] & 0x80) == 0)
50  				&& ((result[2] & 0x80) == 0) && ((result[3] & 0x80) == 0);
51  		return result;
52  	}
53  
54  	public void create(Tag tag, ByteBuffer buf, List fields, int tagSize,
55  			int paddingSize) {
56  
57  		// ID3------------------
58  		buf.put((byte) 73).put((byte) 68).put((byte) 51); // ID3
59  		// ----------------------------------------------------------------------------
60  		// When generation new tag
61  		// Version of tag ID3v2.xx.xx
62  		buf.put((byte) 4);
63  		buf.put((byte) 0);
64  		// ----------------------------------------------------------------------------
65  		// Create certain flags
66  		boolean[] ID3Flags = new boolean[4];
67  
68  		ID3Flags[0] = false; // unsyncronization is not done
69  		ID3Flags[1] = false; // Extended header is useless
70  		ID3Flags[2] = false;
71  		ID3Flags[3] = false;
72  		buf.put(createID3Flags(ID3Flags));
73  		// ----------------------------------------------------------------------------
74  		// On ecrit la taille du nouveau tag ID3
75  		// Tag length
76  		int tempSize = (tagSize - 10) + paddingSize;
77  		// Here we need to use sync-safe integers, so conversion must be done
78  		buf.put(getSyncSafe(tempSize));
79  		// ----------------------------------------------------------------------------
80  		// Ecriture de l'Header Etendu si le flag est==true (A COMPLETER)
81  		if (ID3Flags[1] == true) {
82  			// Create the ID3 Extended Header (not used)
83  			// This may need to be implemented
84  			// createExtendedHeader();
85  		}
86  		// ----------------------------------------------------------------------------
87  		// Ecriture des champs de texte
88  		Iterator it = fields.iterator();
89  		while (it.hasNext()) {
90  			buf.put((byte[]) it.next());
91  		}
92  
93  		// Fill the rest with \0 (padding)
94  		for (int i = 0; i < paddingSize; i++)
95  			buf.put((byte) 0);
96  	}
97  
98  	// Create a byte representing ID3 Flags using the given array
99  	private byte createID3Flags(boolean[] flag) {
100 		byte b = 0;
101 
102 		if (flag[0] == true)
103 			b += 128;
104 		if (flag[1] == true)
105 			b += 64;
106 		if (flag[2] == true)
107 			b += 32;
108 		if (flag[3] == true)
109 			b += 16;
110 		return b;
111 	}
112 
113 	protected Tag getCompatibleTag(Tag tag) {
114 		if (!(tag instanceof Id3v2Tag)) {
115 			Id3v2Tag id3Tag = new Id3v2Tag();
116 			id3Tag.merge(tag);
117 			return id3Tag;
118 		}
119 		return tag;
120 	}
121 
122 	protected int getFixedTagLength(Tag tag) {
123 		return 10;
124 	}
125 }