1
package org.jaudiotagger.tag.id3;
3
import java.nio.ByteBuffer;
6
* Peforms encoding/decoding of an syncsafe integer
8
* <p>Syncsafe integers are used for the size in the tag header of v23 and v24 tags, and in the frame size in
9
* the frame header of v24 frames.
11
* <p>In some parts of the tag it is inconvenient to use the
12
* unsychronisation scheme because the size of unsynchronised data is
13
* not known in advance, which is particularly problematic with size
14
* descriptors. The solution in ID3v2 is to use synchsafe integers, in
15
* which there can never be any false synchs. Synchsafe integers are
16
* integers that keep its highest bit (bit 7) zeroed, making seven bits
17
* out of eight available. Thus a 32 bit synchsafe integer can store 28
18
* bits of information.
22
* 255 (%11111111) encoded as a 16 bit synchsafe integer is 383
23
* (%00000001 01111111).
25
public class ID3SyncSafeInteger
27
public static final int INTEGRAL_SIZE = 4;
29
/** Sizes equal or smaller than this are the same whether held as sync safe integer or normal integer so
32
public static final int MAX_SAFE_SIZE = 127;
35
* Read syncsafe value from byteArray in format specified in spec and convert to int.
37
* @param buffer syncsafe integer
40
private static int bufferToValue(byte[] buffer)
42
//Note Need to && with 0xff otherwise if value is greater than 128 we get a negative number
43
//when cast byte to int
44
return (int) ((buffer[0] & 0xff) << 21)
45
+ ((buffer[1] & 0xff) << 14)
46
+ ((buffer[2] & 0xff) << 7)
47
+ ((buffer[3]) & 0xff);
51
* Read syncsafe value from buffer in format specified in spec and convert to int.
53
* The buffers position is moved to just after the location of the syscsafe integer
55
* @param buffer syncsafe integer
58
protected static int bufferToValue(ByteBuffer buffer)
60
byte byteBuffer [] = new byte[INTEGRAL_SIZE];
61
buffer.get(byteBuffer,0,INTEGRAL_SIZE);
62
return bufferToValue(byteBuffer);
66
* Is buffer holding a value that is definently not sysncsafe
68
* We cannot guarantee a buffer is holding a syncsafe integer but there are some checks
69
* we can do to show that it definently is not.
71
* The buffer is NOT moved after reading.
73
* This function is useful for reading ID3v24 frames created in iTunes because iTunes does not use syncsafe
74
* integers in its frames.
77
* @return true if this buffer is definently not holding a syncsafe integer
79
protected static boolean isBufferNotSyncSafe(ByteBuffer buffer)
81
int position = buffer.position();
84
for(int i=0;i<INTEGRAL_SIZE;i++)
86
byte nextByte = buffer.get(position+i);
87
if((nextByte & 0x80)>0)
96
* Checks if the buffer just contains zeros
98
* This can be used to identify when accessing padding of a tag
101
* @return true if buffer only contains zeros
103
protected static boolean isBufferEmpty(byte[] buffer)
105
for (byte aBuffer : buffer)
116
* Convert int value to syncsafe value held in bytearray
119
* @return buffer syncsafe integer
121
protected static byte[] valueToBuffer(int size)
123
byte[] buffer = new byte[4];
124
buffer[0] = (byte) ((size & 0x0FE00000) >> 21);
125
buffer[1] = (byte) ((size & 0x001FC000) >> 14);
126
buffer[2] = (byte) ((size & 0x00003F80) >> 7);
127
buffer[3] = (byte) (size & 0x0000007F);