/*
* Entagged Audio Tag library
* Copyright (c) 2003-2005 Rapha�l Slinckx <raphael@slinckx.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package entagged.audioformats.mp3.util.id3frames;
import java.io.UnsupportedEncodingException;
import entagged.audioformats.generic.TagField;
public class ApicId3Frame extends TextId3Frame {
private byte[] data;
private String mime;
private byte pictureType;
private boolean unsupportedState = false;
public ApicId3Frame(byte[] rawContent, byte version)
throws UnsupportedEncodingException {
super("APIC", rawContent, version);
}
public ApicId3Frame(String description, String mime, byte pictureType,
byte[] data) {
super("APIC", description);
this.mime = mime;
this.pictureType = pictureType;
this.data = data;
}
protected byte[] build() throws UnsupportedEncodingException {
if (unsupportedState) {
return this.data;
}
byte[] contentB = getBytes(this.content, getEncoding());
byte[] mimeB = getBytes(this.mime, "ISO-8859-1");
byte[] b = new byte[4 + 4 + flags.length + 1 + mimeB.length + 1
+ contentB.length + data.length];
int offset = 0;
copy(getIdBytes(), b, offset);
offset += 4;
copy(getSize(b.length - 10), b, offset);
offset += 4;
copy(flags, b, offset);
offset += flags.length;
b[offset] = this.encoding;
offset += 1;
copy(mimeB, b, offset);
offset += mimeB.length;
b[offset] = this.pictureType;
offset += 1;
copy(contentB, b, offset);
offset += contentB.length;
copy(data, b, offset);
offset += data.length;
return b;
}
public void copyContent(TagField field) {
super.copyContent(field);
if (field instanceof ApicId3Frame) {
if (!((ApicId3Frame) field).unsupportedState) {
this.mime = ((ApicId3Frame) field).getMimeType();
this.pictureType = ((ApicId3Frame) field).getPictureType();
this.data = ((ApicId3Frame) field).getData();
} else {
this.data = ((ApicId3Frame) field).data;
this.unsupportedState = true;
}
}
}
public byte[] getData() {
return data;
}
public String getMimeType() {
return mime;
}
public byte getPictureType() {
return pictureType;
}
public String getPictureTypeAsString() {
switch (pictureType & 0xFF) {
case 0x00:
return "Other";
case 0x01:
return "32x32 pixels file icon";
case 0x02:
return "Other file icon";
case 0x03:
return "Cover (front)";
case 0x04:
return "Cover (back)";
case 0x05:
return "Leaflet page";
case 0x06:
return "Media (e.g. lable side of CD)";
case 0x07:
return "Lead artist/lead performer/soloist";
case 0x08:
return "Artist/performer";
case 0x09:
return "Conductor";
case 0x0A:
return "Band/Orchestra";
case 0x0B:
return "Composer";
case 0x0C:
return "Lyricist/text writer";
case 0x0D:
return "Recording Location";
case 0x0E:
return "During recording";
case 0x0F:
return "During performance";
case 0x10:
return "Movie/video screen capture";
case 0x11:
return "A bright coloured fish";
case 0x12:
return "Illustration";
case 0x13:
return "Band/artist logotype";
case 0x14:
return "Publisher/Studio logotype";
}
return "Unknown";
}
public boolean isBinary() {
return true;
}
public boolean isEmpty() {
return super.isEmpty() && data.length == 0 && mime.equals("");
}
/*
* Text encoding $xx MIME type <text string> $00 Picture type $xx
* Description <text string according to encoding> $00 (00) Picture data
* <binary data>
*/
protected void populate(byte[] raw) throws UnsupportedEncodingException {
// Will create empty data, because there are multiple conditions under
// which
// no data is available. Hoewever the implementation of this class
// relies on the
// fact, that data is never null
this.data = new byte[0];
this.encoding = raw[flags.length];
if (this.encoding < 0 || this.encoding > 3)
this.encoding = 0;
int offset = indexOfFirstNull(raw, flags.length + 1);
this.mime = getString(raw, flags.length + 1, offset - flags.length - 1,
"ISO-8859-1");
if (this.mime == null) {
// Set state to Invalid
return;
}
if (this.mime.trim().equals("-->")) {
// Now the Picture Data represents a URL to the real picutre
// For now unsupported
unsupportedState = true;
this.data = raw;
return;
}
this.pictureType = raw[offset + 1];
int nextoffset = indexOfFirstNull(raw, offset + 2);
this.content = getString(raw, offset + 2, nextoffset - offset - 2,
getEncoding());
// Again the encoding
if (this.encoding == 2 || this.encoding == 3) {
nextoffset++;
}
nextoffset++;
if (raw.length > nextoffset) {
this.data = new byte[raw.length - nextoffset];
System.arraycopy(raw, nextoffset, data, 0, data.length);
} else {
System.err
.println("ApicId3Frame-> No space for picture data left.");
}
}
public String toString() {
return "[" + mime + " (" + getPictureTypeAsString() + ")] "
+ super.toString();
}
}