241 lines
5.6 KiB
Java
241 lines
5.6 KiB
Java
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
|
/* JOrbis
|
|
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
|
*
|
|
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
|
*
|
|
* Many thanks to
|
|
* Monty <monty@xiph.org> and
|
|
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
|
* JOrbis has been based on their awesome works, Vorbis codec.
|
|
*
|
|
* This program 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 program 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 program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
package com.jcraft.jorbis;
|
|
|
|
import com.jcraft.jogg.*;
|
|
|
|
// the comments are not part of vorbis_info so that vorbis_info can be
|
|
// static storage
|
|
public class Comment {
|
|
private static byte[] _vorbis = "vorbis".getBytes();
|
|
private static byte[] _vendor = "Xiphophorus libVorbis I 20000508".getBytes();
|
|
|
|
private static final int OV_EIMPL = -130;
|
|
|
|
// unlimited user comment fields.
|
|
public byte[][] user_comments;
|
|
public int[] comment_lengths;
|
|
public int comments;
|
|
public byte[] vendor;
|
|
|
|
public void init() {
|
|
user_comments = null;
|
|
comments = 0;
|
|
vendor = null;
|
|
}
|
|
|
|
public void add(String comment) {
|
|
add(comment.getBytes());
|
|
}
|
|
|
|
private void add(byte[] comment) {
|
|
byte[][] foo = new byte[comments + 2][];
|
|
if (user_comments != null) {
|
|
System.arraycopy(user_comments, 0, foo, 0, comments);
|
|
}
|
|
user_comments = foo;
|
|
|
|
int[] goo = new int[comments + 2];
|
|
if (comment_lengths != null) {
|
|
System.arraycopy(comment_lengths, 0, goo, 0, comments);
|
|
}
|
|
comment_lengths = goo;
|
|
|
|
byte[] bar = new byte[comment.length + 1];
|
|
System.arraycopy(comment, 0, bar, 0, comment.length);
|
|
user_comments[comments] = bar;
|
|
comment_lengths[comments] = comment.length;
|
|
comments++;
|
|
user_comments[comments] = null;
|
|
}
|
|
|
|
public void add_tag(String tag, String contents) {
|
|
if (contents == null)
|
|
contents = "";
|
|
add(tag + "=" + contents);
|
|
}
|
|
|
|
static boolean tagcompare(byte[] s1, byte[] s2, int n) {
|
|
int c = 0;
|
|
byte u1, u2;
|
|
while (c < n) {
|
|
u1 = s1[c];
|
|
u2 = s2[c];
|
|
if ('Z' >= u1 && u1 >= 'A')
|
|
u1 = (byte) (u1 - 'A' + 'a');
|
|
if ('Z' >= u2 && u2 >= 'A')
|
|
u2 = (byte) (u2 - 'A' + 'a');
|
|
if (u1 != u2) {
|
|
return false;
|
|
}
|
|
c++;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public String query(String tag) {
|
|
return query(tag, 0);
|
|
}
|
|
|
|
public String query(String tag, int count) {
|
|
int foo = query(tag.getBytes(), count);
|
|
if (foo == -1)
|
|
return null;
|
|
byte[] comment = user_comments[foo];
|
|
for (int i = 0; i < comment_lengths[foo]; i++) {
|
|
if (comment[i] == '=') {
|
|
return new String(comment, i + 1, comment_lengths[foo] - (i + 1));
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private int query(byte[] tag, int count) {
|
|
int i = 0;
|
|
int found = 0;
|
|
int fulltaglen = tag.length + 1;
|
|
byte[] fulltag = new byte[fulltaglen];
|
|
System.arraycopy(tag, 0, fulltag, 0, tag.length);
|
|
fulltag[tag.length] = (byte) '=';
|
|
|
|
for (i = 0; i < comments; i++) {
|
|
if (tagcompare(user_comments[i], fulltag, fulltaglen)) {
|
|
if (count == found) {
|
|
// We return a pointer to the data, not a copy
|
|
// return user_comments[i] + taglen + 1;
|
|
return i;
|
|
} else {
|
|
found++;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int unpack(Buffer opb) {
|
|
int vendorlen = opb.read(32);
|
|
if (vendorlen < 0) {
|
|
clear();
|
|
return (-1);
|
|
}
|
|
vendor = new byte[vendorlen + 1];
|
|
opb.read(vendor, vendorlen);
|
|
comments = opb.read(32);
|
|
if (comments < 0) {
|
|
clear();
|
|
return (-1);
|
|
}
|
|
user_comments = new byte[comments + 1][];
|
|
comment_lengths = new int[comments + 1];
|
|
|
|
for (int i = 0; i < comments; i++) {
|
|
int len = opb.read(32);
|
|
if (len < 0) {
|
|
clear();
|
|
return (-1);
|
|
}
|
|
comment_lengths[i] = len;
|
|
user_comments[i] = new byte[len + 1];
|
|
opb.read(user_comments[i], len);
|
|
}
|
|
if (opb.read(1) != 1) {
|
|
clear();
|
|
return (-1);
|
|
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
int pack(Buffer opb) {
|
|
// preamble
|
|
opb.write(0x03, 8);
|
|
opb.write(_vorbis);
|
|
|
|
// vendor
|
|
opb.write(_vendor.length, 32);
|
|
opb.write(_vendor);
|
|
|
|
// comments
|
|
opb.write(comments, 32);
|
|
if (comments != 0) {
|
|
for (int i = 0; i < comments; i++) {
|
|
if (user_comments[i] != null) {
|
|
opb.write(comment_lengths[i], 32);
|
|
opb.write(user_comments[i]);
|
|
} else {
|
|
opb.write(0, 32);
|
|
}
|
|
}
|
|
}
|
|
opb.write(1, 1);
|
|
return (0);
|
|
}
|
|
|
|
public int header_out(Packet op) {
|
|
Buffer opb = new Buffer();
|
|
opb.writeinit();
|
|
|
|
if (pack(opb) != 0)
|
|
return OV_EIMPL;
|
|
|
|
op.packet_base = new byte[opb.bytes()];
|
|
op.packet = 0;
|
|
op.bytes = opb.bytes();
|
|
System.arraycopy(opb.buffer(), 0, op.packet_base, 0, op.bytes);
|
|
op.b_o_s = 0;
|
|
op.e_o_s = 0;
|
|
op.granulepos = 0;
|
|
return 0;
|
|
}
|
|
|
|
void clear() {
|
|
for (int i = 0; i < comments; i++)
|
|
user_comments[i] = null;
|
|
user_comments = null;
|
|
vendor = null;
|
|
}
|
|
|
|
public String getVendor() {
|
|
return new String(vendor, 0, vendor.length - 1);
|
|
}
|
|
|
|
public String getComment(int i) {
|
|
if (comments <= i)
|
|
return null;
|
|
return new String(user_comments[i], 0, user_comments[i].length - 1);
|
|
}
|
|
|
|
public String toString() {
|
|
String foo = "Vendor: " + new String(vendor, 0, vendor.length - 1);
|
|
for (int i = 0; i < comments; i++) {
|
|
foo = foo + "\nComment: " + new String(user_comments[i], 0, user_comments[i].length - 1);
|
|
}
|
|
foo = foo + "\n";
|
|
return foo;
|
|
}
|
|
}
|