obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
-
+
/**
- * This subclass of <code>FilterInputStream</code> buffers input from an
+ * This subclass of <code>FilterInputStream</code> buffers input from an
* underlying implementation to provide a possibly more efficient read
- * mechanism. It maintains the buffer and buffer state in instance
- * variables that are available to subclasses. The default buffer size
- * of 2048 bytes can be overridden by the creator of the stream.
+ * mechanism. It maintains the buffer and buffer state in instance variables
+ * that are available to subclasses. The default buffer size of 2048 bytes can
+ * be overridden by the creator of the stream.
* <p>
- * This class also implements mark/reset functionality. It is capable
- * of remembering any number of input bytes, to the limits of
- * system memory or the size of <code>Integer.MAX_VALUE</code>
+ * This class also implements mark/reset functionality. It is capable of
+ * remembering any number of input bytes, to the limits of system memory or the
+ * size of <code>Integer.MAX_VALUE</code>
* <p>
- * Please note that this class does not properly handle character
- * encodings. Consider using the <code>BufferedReader</code> class which
- * does.
- *
+ * Please note that this class does not properly handle character encodings.
+ * Consider using the <code>BufferedReader</code> class which does.
+ *
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
* @author Jeroen Frijters (jeroen@frijters.net)
*/
@LATTICE("BUF<C,IN<T")
@METHODDEFAULT("D<IN,D<C,THISLOC=D")
-public class BufferedInputStream extends FilterInputStream
-{
+public class BufferedInputStream extends FilterInputStream {
/**
* This is the default buffer size
/**
* The buffer used for storing data from the underlying stream.
*/
- @LOC("BUF") protected byte[] buf;
+ @LOC("BUF")
+ protected byte[] buf;
/**
- * The number of valid bytes currently in the buffer. It is also the index
- * of the buffer position one byte past the end of the valid data.
+ * The number of valid bytes currently in the buffer. It is also the index of
+ * the buffer position one byte past the end of the valid data.
*/
- @LOC("C") protected int count;
+ @LOC("C")
+ protected int count;
/**
- * The index of the next character that will by read from the buffer.
- * When <code>pos == count</code>, the buffer is empty.
+ * The index of the next character that will by read from the buffer. When
+ * <code>pos == count</code>, the buffer is empty.
*/
- @LOC("C") protected int pos;
+ @LOC("C")
+ protected int pos;
/**
* The value of <code>pos</code> when the <code>mark()</code> method was
- * called.
- * This is set to -1 if there is no mark set.
+ * called. This is set to -1 if there is no mark set.
*/
- @LOC("C") protected int markpos = -1;
+ @LOC("C")
+ protected int markpos = -1;
/**
- * This is the maximum number of bytes than can be read after a
- * call to <code>mark()</code> before the mark can be discarded.
- * After this may bytes are read, the <code>reset()</code> method
- * may not be called successfully.
+ * This is the maximum number of bytes than can be read after a call to
+ * <code>mark()</code> before the mark can be discarded. After this may bytes
+ * are read, the <code>reset()</code> method may not be called successfully.
*/
protected int marklimit;
/**
- * This is the initial buffer size. When the buffer is grown because
- * of marking requirements, it will be grown by bufferSize increments.
- * The underlying stream will be read in chunks of bufferSize.
+ * This is the initial buffer size. When the buffer is grown because of
+ * marking requirements, it will be grown by bufferSize increments. The
+ * underlying stream will be read in chunks of bufferSize.
*/
private final int bufferSize;
/**
* This method initializes a new <code>BufferedInputStream</code> that will
- * read from the specified subordinate stream with a default buffer size
- * of 2048 bytes
- *
- * @param in The subordinate stream to read from
+ * read from the specified subordinate stream with a default buffer size of
+ * 2048 bytes
+ *
+ * @param in
+ * The subordinate stream to read from
*/
- public BufferedInputStream(InputStream in)
- {
+ public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a new <code>BufferedInputStream</code> that will
- * read from the specified subordinate stream with a buffer size that
- * is specified by the caller.
- *
- * @param in The subordinate stream to read from
- * @param size The buffer size to use
- *
- * @exception IllegalArgumentException when size is smaller then 1
+ * read from the specified subordinate stream with a buffer size that is
+ * specified by the caller.
+ *
+ * @param in
+ * The subordinate stream to read from
+ * @param size
+ * The buffer size to use
+ *
+ * @exception IllegalArgumentException
+ * when size is smaller then 1
*/
- public BufferedInputStream(InputStream in, int size)
- {
+ public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0)
throw new IllegalArgumentException();
}
/**
- * This method returns the number of bytes that can be read from this
- * stream before a read can block. A return of 0 indicates that blocking
- * might (or might not) occur on the very next read attempt.
+ * This method returns the number of bytes that can be read from this stream
+ * before a read can block. A return of 0 indicates that blocking might (or
+ * might not) occur on the very next read attempt.
* <p>
- * The number of available bytes will be the number of read ahead bytes
- * stored in the internal buffer plus the number of available bytes in
- * the underlying stream.
- *
+ * The number of available bytes will be the number of read ahead bytes stored
+ * in the internal buffer plus the number of available bytes in the underlying
+ * stream.
+ *
* @return The number of bytes that can be read before blocking could occur
- *
- * @exception IOException If an error occurs
+ *
+ * @exception IOException
+ * If an error occurs
*/
- public synchronized int available() throws IOException
- {
+ public synchronized int available() throws IOException {
return count - pos + super.available();
}
/**
- * This method closes the underlying input stream and frees any
- * resources associated with it. Sets <code>buf</code> to <code>null</code>.
- *
- * @exception IOException If an error occurs.
+ * This method closes the underlying input stream and frees any resources
+ * associated with it. Sets <code>buf</code> to <code>null</code>.
+ *
+ * @exception IOException
+ * If an error occurs.
*/
- public void close() throws IOException
- {
+ public void close() throws IOException {
// Free up the array memory.
buf = null;
pos = count = 0;
/**
* This method marks a position in the input to which the stream can be
- * "reset" by calling the <code>reset()</code> method. The parameter
- * <code>readlimit</code> is the number of bytes that can be read from the
- * stream after setting the mark before the mark becomes invalid. For
- * example, if <code>mark()</code> is called with a read limit of 10, then
- * when 11 bytes of data are read from the stream before the
- * <code>reset()</code> method is called, then the mark is invalid and the
- * stream object instance is not required to remember the mark.
+ * "reset" by calling the <code>reset()</code> method. The parameter
+ * <code>readlimit</code> is the number of bytes that can be read from the
+ * stream after setting the mark before the mark becomes invalid. For example,
+ * if <code>mark()</code> is called with a read limit of 10, then when 11
+ * bytes of data are read from the stream before the <code>reset()</code>
+ * method is called, then the mark is invalid and the stream object instance
+ * is not required to remember the mark.
* <p>
- * Note that the number of bytes that can be remembered by this method
- * can be greater than the size of the internal read buffer. It is also
- * not dependent on the subordinate stream supporting mark/reset
- * functionality.
- *
- * @param readlimit The number of bytes that can be read before the mark
- * becomes invalid
+ * Note that the number of bytes that can be remembered by this method can be
+ * greater than the size of the internal read buffer. It is also not dependent
+ * on the subordinate stream supporting mark/reset functionality.
+ *
+ * @param readlimit
+ * The number of bytes that can be read before the mark becomes
+ * invalid
*/
- public synchronized void mark(@LOC("IN") int readlimit)
- {
- marklimit = readlimit;
+ public synchronized void mark(@LOC("IN") int readlimit) {
+ marklimit = readlimit;
markpos = pos;
}
/**
- * This method returns <code>true</code> to indicate that this class
- * supports mark/reset functionality.
- *
+ * This method returns <code>true</code> to indicate that this class supports
+ * mark/reset functionality.
+ *
* @return <code>true</code> to indicate that mark/reset functionality is
- * supported
- *
+ * supported
+ *
*/
- public boolean markSupported()
- {
+ public boolean markSupported() {
return true;
}
/**
- * This method reads an unsigned byte from the input stream and returns it
- * as an int in the range of 0-255. This method also will return -1 if
- * the end of the stream has been reached.
+ * This method reads an unsigned byte from the input stream and returns it as
+ * an int in the range of 0-255. This method also will return -1 if the end of
+ * the stream has been reached.
* <p>
* This method will block until the byte can be read.
- *
+ *
* @return The byte read or -1 if end of stream
- *
- * @exception IOException If an error occurs
+ *
+ * @exception IOException
+ * If an error occurs
*/
- public synchronized int read() throws IOException
- {
+ public synchronized int read() throws IOException {
if (pos >= count && !refill())
- return -1; // EOF
+ return -1; // EOF
return buf[pos++] & 0xFF;
}
/**
* This method reads bytes from a stream and stores them into a caller
- * supplied buffer. It starts storing the data at index <code>off</code>
- * into the buffer and attempts to read <code>len</code> bytes. This method
- * can return before reading the number of bytes requested, but it will try
- * to read the requested number of bytes by repeatedly calling the underlying
+ * supplied buffer. It starts storing the data at index <code>off</code> into
+ * the buffer and attempts to read <code>len</code> bytes. This method can
+ * return before reading the number of bytes requested, but it will try to
+ * read the requested number of bytes by repeatedly calling the underlying
* stream as long as available() for this stream continues to return a
- * non-zero value (or until the requested number of bytes have been read).
- * The actual number of bytes read is returned as an int. A -1 is returned
- * to indicate the end of the stream.
+ * non-zero value (or until the requested number of bytes have been read). The
+ * actual number of bytes read is returned as an int. A -1 is returned to
+ * indicate the end of the stream.
* <p>
* This method will block until some data can be read.
- *
- * @param b The array into which the bytes read should be stored
- * @param off The offset into the array to start storing bytes
- * @param len The requested number of bytes to read
- *
+ *
+ * @param b
+ * The array into which the bytes read should be stored
+ * @param off
+ * The offset into the array to start storing bytes
+ * @param len
+ * The requested number of bytes to read
+ *
* @return The actual number of bytes read, or -1 if end of stream.
- *
- * @exception IOException If an error occurs.
- * @exception IndexOutOfBoundsException when <code>off</code> or
- * <code>len</code> are negative, or when <code>off + len</code>
- * is larger then the size of <code>b</code>,
+ *
+ * @exception IOException
+ * If an error occurs.
+ * @exception IndexOutOfBoundsException
+ * when <code>off</code> or <code>len</code> are negative, or
+ * when <code>off + len</code> is larger then the size of
+ * <code>b</code>,
*/
- public synchronized int read(byte[] b, int off, int len) throws IOException
- {
+ public synchronized int read(byte[] b, int off, int len) throws IOException {
if (off < 0 || len < 0 || b.length - off < len)
throw new IndexOutOfBoundsException();
return 0;
if (pos >= count && !refill())
- return -1; // No bytes were read before EOF.
+ return -1; // No bytes were read before EOF.
int totalBytesRead = Math.min(count - pos, len);
System.arraycopy(buf, pos, b, off, totalBytesRead);
off += totalBytesRead;
len -= totalBytesRead;
- while (len > 0 && super.available() > 0 && refill())
- {
- int remain = Math.min(count - pos, len);
- System.arraycopy(buf, pos, b, off, remain);
- pos += remain;
- off += remain;
- len -= remain;
- totalBytesRead += remain;
- }
+ while (len > 0 && super.available() > 0 && refill()) {
+ int remain = Math.min(count - pos, len);
+ System.arraycopy(buf, pos, b, off, remain);
+ pos += remain;
+ off += remain;
+ len -= remain;
+ totalBytesRead += remain;
+ }
return totalBytesRead;
}
/**
* This method resets a stream to the point where the <code>mark()</code>
- * method was called. Any bytes that were read after the mark point was
- * set will be re-read during subsequent reads.
+ * method was called. Any bytes that were read after the mark point was set
+ * will be re-read during subsequent reads.
* <p>
- * This method will throw an IOException if the number of bytes read from
- * the stream since the call to <code>mark()</code> exceeds the mark limit
- * passed when establishing the mark.
- *
- * @exception IOException If <code>mark()</code> was never called or more
- * then <code>marklimit</code> bytes were read since the last
- * call to <code>mark()</code>
+ * This method will throw an IOException if the number of bytes read from the
+ * stream since the call to <code>mark()</code> exceeds the mark limit passed
+ * when establishing the mark.
+ *
+ * @exception IOException
+ * If <code>mark()</code> was never called or more then
+ * <code>marklimit</code> bytes were read since the last call to
+ * <code>mark()</code>
*/
- public synchronized void reset() throws IOException
- {
+ public synchronized void reset() throws IOException {
if (markpos == -1)
throw new IOException(buf == null ? "Stream closed." : "Invalid mark.");
}
/**
- * This method skips the specified number of bytes in the stream. It
- * returns the actual number of bytes skipped, which may be less than the
- * requested amount.
- *
- * @param n The requested number of bytes to skip
- *
+ * This method skips the specified number of bytes in the stream. It returns
+ * the actual number of bytes skipped, which may be less than the requested
+ * amount.
+ *
+ * @param n
+ * The requested number of bytes to skip
+ *
* @return The actual number of bytes skipped.
- *
- * @exception IOException If an error occurs
+ *
+ * @exception IOException
+ * If an error occurs
*/
- public synchronized long skip(long n) throws IOException
- {
+ public synchronized long skip(long n) throws IOException {
if (buf == null)
throw new IOException("Stream closed.");
final long origN = n;
- while (n > 0L)
- {
- if (pos >= count && !refill())
- break;
+ while (n > 0L) {
+ if (pos >= count && !refill())
+ break;
- int numread = (int) Math.min((long) (count - pos), n);
- pos += numread;
- n -= numread;
- }
+ int numread = (int) Math.min((long) (count - pos), n);
+ pos += numread;
+ n -= numread;
+ }
return origN - n;
}
/**
* Called to refill the buffer (when count is equal to pos).
- *
- * @return <code>true</code> when at least one additional byte was read
- * into <code>buf</code>, <code>false</code> otherwise (at EOF).
+ *
+ * @return <code>true</code> when at least one additional byte was read into
+ * <code>buf</code>, <code>false</code> otherwise (at EOF).
*/
- private boolean refill() throws IOException
- {
+ private boolean refill() throws IOException {
if (buf == null)
throw new IOException("Stream closed.");
- if (markpos == -1 || count - markpos >= marklimit)
- {
- markpos = -1;
- pos = count = 0;
- }
- else
- {
- byte[] newbuf = buf;
- if (markpos < bufferSize)
- {
- newbuf = new byte[count - markpos + bufferSize];
- }
- System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
- buf = newbuf;
- count -= markpos;
- pos -= markpos;
- markpos = 0;
+ if (markpos == -1 || count - markpos >= marklimit) {
+ markpos = -1;
+ pos = count = 0;
+ } else {
+ byte[] newbuf = buf;
+ if (markpos < bufferSize) {
+ newbuf = new byte[count - markpos + bufferSize];
}
+ System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
+ buf = newbuf;
+ count -= markpos;
+ pos -= markpos;
+ markpos = 0;
+ }
int numread = super.read(buf, count, bufferSize);
- if (numread <= 0) // EOF
+ if (numread <= 0) // EOF
return false;
count += numread;
--- /dev/null
+public class Enumeration {
+
+ public Enumeration() {
+ }
+
+ public boolean hasMoreElements() {
+ return false;
+ }
+
+ public Object nextElement() {
+ return null;
+ }
+}
private int fd;
public FileInputStream(String pathname) {
- fd=nativeOpen(pathname.getBytes());
+ fd = nativeOpen(pathname.getBytes());
}
public FileInputStream(File path) {
- fd=nativeOpen(path.getPath().getBytes());
+ fd = nativeOpen(path.getPath().getBytes());
}
+
public int getfd() {
return fd;
}
private static native int nativeOpen(byte[] filename);
+
private static native int nativeRead(int fd, byte[] array, int numBytes);
+
private static native int nativePeek(int fd);
+
private static native void nativeClose(int fd);
+
private static native int nativeAvailable(int fd);
public int read() {
- byte b[]=new byte[1];
- int retval=read(b);
- if (retval==-1 || retval==0)
+ byte b[] = new byte[1];
+ int retval = read(b);
+ if (retval == -1 || retval == 0)
return -1;
// if carriage return comes back, dump it
- if( b[0] == 13 ) {
+ if (b[0] == 13) {
return read();
}
public int peek() {
return nativePeek(fd);
}
-
- public int read(byte[] b, int offset, int len) {
- if (offset < 0 || len < 0 || offset + len > b.length){
+
+ public int read(byte[] b, int offset, int len) {
+ if (offset < 0 || len < 0 || offset + len > b.length) {
return -1;
- }
- byte readbuf[]=new byte[len];
- int rtr=nativeRead(fd, readbuf, len);
- for(int i=offset;i<len+offset;i++){
- b[i]=readbuf[i-offset];
+ }
+ byte readbuf[] = new byte[len];
+ int rtr = nativeRead(fd, readbuf, len);
+ for (int i = offset; i < len + offset; i++) {
+ b[i] = readbuf[i - offset];
}
return rtr;
}
// if we're already at the end of the file
// or there is an error, don't even return
// the empty string
- if( c <= 0 ) {
+ if (c <= 0) {
return null;
}
// ASCII 13 is carriage return, check for that also
- while( c != '\n' && c != 13 && c > 0 ) {
- line += (char)c;
+ while (c != '\n' && c != 13 && c > 0) {
+ line += (char) c;
c = read();
}
// returns or line feeds so the whole line is read
// and returned, and none of the line-ending chars
c = peek();
- while( c == '\n' || c == 13 ) {
+ while (c == '\n' || c == 13) {
c = read();
c = peek();
}
public void close() {
nativeClose(fd);
}
-
- public int available(){
+
+ public int available() {
return nativeAvailable(fd);
}
}
protected FilterInputStream(@LOC("IN") InputStream in)
{
this.in = in;
- in = null;
}
/**
//package java.io;
/**
- * This subclass of <code>FilterInputStream</code> provides the ability to
- * unread data from a stream. It maintains an internal buffer of unread
- * data that is supplied to the next read operation. This is conceptually
- * similar to mark/reset functionality, except that in this case the
- * position to reset the stream to does not need to be known in advance.
- * <p>
- * The default pushback buffer size one byte, but this can be overridden
- * by the creator of the stream.
- * <p>
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- * @author Warren Levy (warrenl@cygnus.com)
- */
+ * This subclass of <code>FilterInputStream</code> provides the ability to
+ * unread data from a stream. It maintains an internal buffer of unread data
+ * that is supplied to the next read operation. This is conceptually similar to
+ * mark/reset functionality, except that in this case the position to reset the
+ * stream to does not need to be known in advance.
+ * <p>
+ * The default pushback buffer size one byte, but this can be overridden by the
+ * creator of the stream.
+ * <p>
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
@LATTICE("IN<T,IN<POS,POS<SH,SH<F,SH*,POS*")
@METHODDEFAULT("OUT<SH,SH<IN,SH*,THISLOC=OUT,GLOBALLOC=OUT")
-public class PushbackInputStream extends FilterInputStream
-{
+public class PushbackInputStream extends FilterInputStream {
/**
* This is the default buffer size
*/
- @LOC("F") private static final int DEFAULT_BUFFER_SIZE = 1;
+ @LOC("F")
+ private static final int DEFAULT_BUFFER_SIZE = 1;
/**
* This is the buffer that is used to store the pushed back data
*/
- @LOC("SH") protected byte[] buf;
+ @LOC("SH")
+ protected byte[] buf;
/**
- * This is the position in the buffer from which the next byte will be
- * read. Bytes are stored in reverse order in the buffer, starting from
- * <code>buf[buf.length - 1]</code> to <code>buf[0]</code>. Thus when
- * <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when
+ * This is the position in the buffer from which the next byte will be read.
+ * Bytes are stored in reverse order in the buffer, starting from
+ * <code>buf[buf.length - 1]</code> to <code>buf[0]</code>. Thus when
+ * <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when
* it is empty
*/
- @LOC("POS") protected int pos;
+ @LOC("POS")
+ protected int pos;
/**
- * This method initializes a <code>PushbackInputStream</code> to
- * read from the specified subordinate <code>InputStream</code>
- * with a default pushback buffer size of 1.
- *
- * @param in The subordinate stream to read from
+ * This method initializes a <code>PushbackInputStream</code> to read from the
+ * specified subordinate <code>InputStream</code> with a default pushback
+ * buffer size of 1.
+ *
+ * @param in
+ * The subordinate stream to read from
*/
- public PushbackInputStream(InputStream in)
- {
+ public PushbackInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
/**
- * This method initializes a <code>PushbackInputStream</code> to
- * read from the specified subordinate <code>InputStream</code> with
- * the specified buffer size
- *
- * @param in The subordinate <code>InputStream</code> to read from
- * @param size The pushback buffer size to use
+ * This method initializes a <code>PushbackInputStream</code> to read from the
+ * specified subordinate <code>InputStream</code> with the specified buffer
+ * size
+ *
+ * @param in
+ * The subordinate <code>InputStream</code> to read from
+ * @param size
+ * The pushback buffer size to use
*/
- public PushbackInputStream(@LOC("IN")InputStream in, @LOC("IN")int size)
- {
+ public PushbackInputStream(@LOC("IN") InputStream in, @LOC("IN") int size) {
super(in);
if (size < 0)
throw new IllegalArgumentException();
}
/**
- * This method returns the number of bytes that can be read from this
- * stream before a read can block. A return of 0 indicates that blocking
- * might (or might not) occur on the very next read attempt.
+ * This method returns the number of bytes that can be read from this stream
+ * before a read can block. A return of 0 indicates that blocking might (or
+ * might not) occur on the very next read attempt.
* <p>
- * This method will return the number of bytes available from the
- * pushback buffer plus the number of bytes available from the
- * underlying stream.
- *
+ * This method will return the number of bytes available from the pushback
+ * buffer plus the number of bytes available from the underlying stream.
+ *
* @return The number of bytes that can be read before blocking could occur
- *
- * @exception IOException If an error occurs
+ *
+ * @exception IOException
+ * If an error occurs
*/
- public int available() throws IOException
- {
- try
- {
- return (buf.length - pos) + super.available();
- }
- catch (NullPointerException npe)
- {
- throw new IOException ("Stream closed");
- }
+ public int available() throws IOException {
+ try {
+ return (buf.length - pos) + super.available();
+ } catch (NullPointerException npe) {
+ throw new IOException("Stream closed");
+ }
}
/**
* This method closes the stream and releases any associated resources.
*
- * @exception IOException If an error occurs.
+ * @exception IOException
+ * If an error occurs.
*/
- public synchronized void close() throws IOException
- {
+ public synchronized void close() throws IOException {
buf = null;
super.close();
}
/**
- * This method returns <code>false</code> to indicate that it does
- * not support mark/reset functionality.
- *
- * @return This method returns <code>false</code> to indicate that
- * this class does not support mark/reset functionality
+ * This method returns <code>false</code> to indicate that it does not support
+ * mark/reset functionality.
+ *
+ * @return This method returns <code>false</code> to indicate that this class
+ * does not support mark/reset functionality
*/
- public boolean markSupported()
- {
+ public boolean markSupported() {
return false;
}
/**
- * This method always throws an IOException in this class because
- * mark/reset functionality is not supported.
- *
- * @exception IOException Always thrown for this class
+ * This method always throws an IOException in this class because mark/reset
+ * functionality is not supported.
+ *
+ * @exception IOException
+ * Always thrown for this class
*/
- public void reset() throws IOException
- {
+ public void reset() throws IOException {
throw new IOException("Mark not supported in this class");
}
/**
- * This method reads an unsigned byte from the input stream and returns it
- * as an int in the range of 0-255. This method also will return -1 if
- * the end of the stream has been reached. The byte returned will be read
- * from the pushback buffer, unless the buffer is empty, in which case
- * the byte will be read from the underlying stream.
+ * This method reads an unsigned byte from the input stream and returns it as
+ * an int in the range of 0-255. This method also will return -1 if the end of
+ * the stream has been reached. The byte returned will be read from the
+ * pushback buffer, unless the buffer is empty, in which case the byte will be
+ * read from the underlying stream.
* <p>
* This method will block until the byte can be read.
- *
+ *
* @return The byte read or -1 if end of stream
- *
- * @exception IOException If an error occurs
+ *
+ * @exception IOException
+ * If an error occurs
*/
- public synchronized int read() throws IOException
- {
+ public synchronized int read() throws IOException {
if (pos < buf.length)
return ((int) buf[pos++]) & 0xFF;
}
/**
- * This method read bytes from a stream and stores them into a
- * caller supplied buffer. It starts storing the data at index
- * <code>offset</code> into the buffer and attempts to read
- * <code>len</code> bytes. This method can return before reading the
- * number of bytes requested. The actual number of bytes read is
- * returned as an int. A -1 is returned to indicate the end of the
+ * This method read bytes from a stream and stores them into a caller supplied
+ * buffer. It starts storing the data at index <code>offset</code> into the
+ * buffer and attempts to read <code>len</code> bytes. This method can return
+ * before reading the number of bytes requested. The actual number of bytes
+ * read is returned as an int. A -1 is returned to indicate the end of the
* stream.
- * <p>
+ * <p>
* This method will block until some data can be read.
* <p>
- * This method first reads bytes from the pushback buffer in order to
- * satisfy the read request. If the pushback buffer cannot provide all
- * of the bytes requested, the remaining bytes are read from the
- * underlying stream.
- *
- * @param b The array into which the bytes read should be stored
- * @param off The offset into the array to start storing bytes
- * @param len The requested number of bytes to read
- *
+ * This method first reads bytes from the pushback buffer in order to satisfy
+ * the read request. If the pushback buffer cannot provide all of the bytes
+ * requested, the remaining bytes are read from the underlying stream.
+ *
+ * @param b
+ * The array into which the bytes read should be stored
+ * @param off
+ * The offset into the array to start storing bytes
+ * @param len
+ * The requested number of bytes to read
+ *
* @return The actual number of bytes read, or -1 if end of stream.
- *
- * @exception IOException If an error occurs.
+ *
+ * @exception IOException
+ * If an error occurs.
*/
@LATTICE("OUT<THIS,THISLOC=THIS")
@RETURNLOC("THIS")
- public synchronized int read(@LOC("OUT") byte[] b,
- @LOC("THIS,PushbackInputStream.POS") int off,
- @LOC("THIS,PushbackInputStream.POS") int len) throws IOException
- {
- @LOC("THIS,PushbackInputStream.POS") int numBytes = Math.min(buf.length - pos,len);
+ public synchronized int read(@LOC("OUT") byte[] b, @LOC("THIS,PushbackInputStream.POS") int off,
+ @LOC("THIS,PushbackInputStream.POS") int len) throws IOException {
+ @LOC("THIS,PushbackInputStream.POS") int numBytes = Math.min(buf.length - pos, len);
+System.out.println("numBytes="+numBytes+" buf.length="+buf.length+" pos="+pos);
+ if (numBytes > 0) {
+
+ System.out.println("buf[pos]="+buf[pos]);
+
+ System.arraycopy(buf, pos, b, off, numBytes);
+ pos += numBytes;
+ len -= numBytes;
+ off += numBytes;
+ }
- if (numBytes > 0)
- {
- System.arraycopy (buf, pos, b, off, numBytes);
- pos += numBytes;
- len -= numBytes;
- off += numBytes;
- }
-
- if (len > 0)
- {
- len = super.read(b, off, len);
- if (len == -1) //EOF
- return numBytes > 0 ? numBytes : -1;
- numBytes += len;
- }
+ if (len > 0) {
+ System.out.println("len>0");
+ len = super.read(b, off, len);
+ if (len == -1) // EOF
+ return numBytes > 0 ? numBytes : -1;
+ numBytes += len;
+ }
return numBytes;
}
/**
- * This method pushes a single byte of data into the pushback buffer.
- * The byte pushed back is the one that will be returned as the first byte
- * of the next read.
+ * This method pushes a single byte of data into the pushback buffer. The byte
+ * pushed back is the one that will be returned as the first byte of the next
+ * read.
* <p>
* If the pushback buffer is full, this method throws an exception.
* <p>
- * The argument to this method is an <code>int</code>. Only the low
- * eight bits of this value are pushed back.
- *
- * @param b The byte to be pushed back, passed as an int
- *
- * @exception IOException If the pushback buffer is full.
+ * The argument to this method is an <code>int</code>. Only the low eight bits
+ * of this value are pushed back.
+ *
+ * @param b
+ * The byte to be pushed back, passed as an int
+ *
+ * @exception IOException
+ * If the pushback buffer is full.
*/
- public synchronized void unread(int b) throws IOException
- {
+ public synchronized void unread(int b) throws IOException {
if (pos <= 0)
throw new IOException("Insufficient space in pushback buffer");
}
/**
- * This method pushes all of the bytes in the passed byte array into
- * the pushback bfer. These bytes are pushed in reverse order so that
- * the next byte read from the stream after this operation will be
- * <code>b[0]</code> followed by <code>b[1]</code>, etc.
+ * This method pushes all of the bytes in the passed byte array into the
+ * pushback bfer. These bytes are pushed in reverse order so that the next
+ * byte read from the stream after this operation will be <code>b[0]</code>
+ * followed by <code>b[1]</code>, etc.
* <p>
- * If the pushback buffer cannot hold all of the requested bytes, an
- * exception is thrown.
- *
- * @param b The byte array to be pushed back
- *
- * @exception IOException If the pushback buffer is full
+ * If the pushback buffer cannot hold all of the requested bytes, an exception
+ * is thrown.
+ *
+ * @param b
+ * The byte array to be pushed back
+ *
+ * @exception IOException
+ * If the pushback buffer is full
*/
- public synchronized void unread(byte[] b) throws IOException
- {
+ public synchronized void unread(byte[] b) throws IOException {
unread(b, 0, b.length);
}
/**
- * This method pushed back bytes from the passed in array into the
- * pushback buffer. The bytes from <code>b[offset]</code> to
- * <code>b[offset + len]</code> are pushed in reverse order so that
- * the next byte read from the stream after this operation will be
- * <code>b[offset]</code> followed by <code>b[offset + 1]</code>,
- * etc.
+ * This method pushed back bytes from the passed in array into the pushback
+ * buffer. The bytes from <code>b[offset]</code> to
+ * <code>b[offset + len]</code> are pushed in reverse order so that the next
+ * byte read from the stream after this operation will be
+ * <code>b[offset]</code> followed by <code>b[offset + 1]</code>, etc.
* <p>
- * If the pushback buffer cannot hold all of the requested bytes, an
- * exception is thrown.
- *
- * @param b The byte array to be pushed back
- * @param off The index into the array where the bytes to be push start
- * @param len The number of bytes to be pushed.
- *
- * @exception IOException If the pushback buffer is full
+ * If the pushback buffer cannot hold all of the requested bytes, an exception
+ * is thrown.
+ *
+ * @param b
+ * The byte array to be pushed back
+ * @param off
+ * The index into the array where the bytes to be push start
+ * @param len
+ * The number of bytes to be pushed.
+ *
+ * @exception IOException
+ * If the pushback buffer is full
*/
public synchronized void unread(@LOC("IN") byte[] b, @LOC("IN") int off, @LOC("IN") int len)
- throws IOException
- {
+ throws IOException {
if (pos < len)
throw new IOException("Insufficient space in pushback buffer");
}
/**
- * This method skips the specified number of bytes in the stream. It
- * returns the actual number of bytes skipped, which may be less than the
- * requested amount.
+ * This method skips the specified number of bytes in the stream. It returns
+ * the actual number of bytes skipped, which may be less than the requested
+ * amount.
* <p>
* This method first discards bytes from the buffer, then calls the
- * <code>skip</code> method on the underlying <code>InputStream</code> to
- * skip additional bytes if necessary.
- *
- * @param n The requested number of bytes to skip
- *
+ * <code>skip</code> method on the underlying <code>InputStream</code> to skip
+ * additional bytes if necessary.
+ *
+ * @param n
+ * The requested number of bytes to skip
+ *
* @return The actual number of bytes skipped.
- *
- * @exception IOException If an error occurs
- *
+ *
+ * @exception IOException
+ * If an error occurs
+ *
* @since 1.2
*/
- public synchronized long skip(long n) throws IOException
- {
+ public synchronized long skip(long n) throws IOException {
final long origN = n;
- if (n > 0L)
- {
- int numread = (int) Math.min((long) (buf.length - pos), n);
- pos += numread;
- n -= numread;
- if (n > 0)
- n -= super.skip(n);
- }
+ if (n > 0L) {
+ int numread = (int) Math.min((long) (buf.length - pos), n);
+ pos += numread;
+ n -= numread;
+ if (n > 0)
+ n -= super.skip(n);
+ }
return origN - n;
}
-import Object;
-import String;
-import StringBuffer;
-import System;
+import Vector;
-@LATTICE("V<C, V<O")
-@METHODDEFAULT("O<V,V<C,C<IN,THISLOC=O,C*")
public class String {
-
- @LOC("V") char value[];
- @LOC("C") int count;
- @LOC("O") int offset;
- @LOC("V") private int cachedHashcode;
+ char value[];
+ int count;
+ int offset;
+ private int cachedHashcode;
private String() {
}
-
+
+ public String(char c) {
+ char[] str = new char[1];
+ str[0] = c;
+ String(str);
+ }
+
+ public String(char str[]) {
+ char charstr[]=new char[str.length];
+ for(int i=0; i<str.length; i++)
+ charstr[i]=str[i];
+ this.value=charstr;
+ this.count=str.length;
+ this.offset=0;
+ }
+
public String(byte str[]) {
char charstr[]=new char[str.length];
for(int i=0; i<str.length; i++)
this.count=str.length;
this.offset=0;
}
-
- public String(char str[], int offset, int length) {
+
+ public String(byte str[], int offset, int length) {
if (length>(str.length-offset))
length=str.length-offset;
char charstr[]=new char[length];
for(int i=0; i<length; i++)
- charstr[i]=str[i+offset];
+ charstr[i]=(char)str[i+offset];
this.value=charstr;
this.count=length;
this.offset=0;
}
-
public String(byte str[], String encoding) {
int length = this.count;
this.count=length;
this.offset=0;
}
-
- public String( @DELEGATE @LOC("IN") String str) {
+
+ public String(char str[], int offset, int length) {
+ if (length>(str.length-offset))
+ length=str.length-offset;
+ char charstr[]=new char[length];
+ for(int i=0; i<length; i++)
+ charstr[i]=str[i+offset];
+ this.value=charstr;
+ this.count=length;
+ this.offset=0;
+ }
+
+ public String(String str) {
this.value=str.value;
- str.value=null;
this.count=str.count;
this.offset=str.offset;
}
-
+
public String(StringBuffer strbuf) {
value=new char[strbuf.length()];
count=strbuf.length();
value[i]=strbuf.value[i];
}
- public String(@LOC("IN") char c) {
- @LOC("V") char[] str = new char[1];
- str[0] = c;
- String(str);
+ public boolean endsWith(String suffix) {
+ return regionMatches(count - suffix.count, suffix, 0, suffix.count);
}
- public String(@LOC("IN") char str[]) {
- @LOC("V") char charstr[]=new char[str.length];
- for(@LOC("C") int i=0; i<str.length; i++)
- charstr[i]=str[i];
- this.value=charstr;
- charstr=null;
- this.count=str.length;
- this.offset=0;
+
+ public String substring(int beginIndex) {
+ return substring(beginIndex, this.count);
}
-
- @LATTICE("O<V,V<C,C<IN,THISLOC=IN,C*")
- @RETURNLOC("O")
- public String concat(@LOC("IN") String str) {
- @LOC("O") String newstr=new String(); // create new one, it has OUT location
- @LOC("C") int newCount=this.count+str.count;
- @LOC("V") char charstr[]=new char[newCount];
+ public String subString(int beginIndex, int endIndex) {
+ return substring(beginIndex, endIndex);
+ }
- // here, for loop introduces indirect flow from [C] to [V]
- for(@LOC("C") int i=0; i<count; i++) {
- // value flows from GLB(THISLOC,C,THISLOC.V)=(THISLOC,TOP) to [V]
- charstr[i]=value[i+offset];
- }
- for(@LOC("C") int i=0; i<str.count; i++) {
- charstr[i+count]=str.value[i+str.offset];
+ public String substring(int beginIndex, int endIndex) {
+ String str=new String();
+ if (beginIndex>this.count||endIndex>this.count||beginIndex>endIndex) {
+ // FIXME
+ System.printString("Index error: "+beginIndex+" "+endIndex+" "+count+"\n"+this);
}
+ str.value=this.value;
+ str.count=endIndex-beginIndex;
+ str.offset=this.offset+beginIndex;
+ return str;
+ }
+
+ public String subString(int beginIndex) {
+ return this.subString(beginIndex, this.count);
+ }
+ public int lastindexOf(int ch) {
+ return this.lastindexOf(ch, count - 1);
+ }
+
+ public int lastIndexOf(char ch) {
+ return this.lastindexOf((int)ch, count - 1);
+ }
+
+ public static String concat2(String s1, String s2) {
+ if (s1==null)
+ return "null".concat(s2);
+ else
+ return s1.concat(s2);
+ }
+
+ public String concat(String str) {
+ String newstr=new String();
+ newstr.count=this.count+str.count;
+ char charstr[]=new char[newstr.count];
newstr.value=charstr;
- charstr=null;
- // LOC(newstr.value)=[O,V]
- // LOC(charstr)=[V]
- // [O,V] < [V]
-
+ newstr.offset=0;
+ for(int i=0; i<count; i++) {
+ charstr[i]=value[i+offset];
+ }
+ for(int i=0; i<str.count; i++) {
+ charstr[i+count]=str.value[i+str.offset];
+ }
return newstr;
}
-
- @RETURNLOC("O")
- public boolean equals(@LOC("IN") Object o) {
- if (o.getType()!=getType()) // values are coming from [IN] and [THISLOC]
- return false;
- @LOC("V") String s=(String)o;
- o=null;
- if (s.count!=count)
- return false;
- for(@LOC("C") int i=0; i<count; i++) {
- if (s.value[i+s.offset]!=value[i+offset])
- return false;
+
+ public int lastindexOf(int ch, int fromIndex) {
+ for(int i=fromIndex; i>0; i--)
+ if (this.charAt(i)==ch)
+ return i;
+ return -1;
+ }
+
+ public String replace(char oldch, char newch) {
+ char[] buffer=new char[count];
+ for(int i=0; i<count; i++) {
+ char x=charAt(i);
+ if (x==oldch)
+ x=newch;
+ buffer[i]=x;
}
- return true;
+ return new String(buffer);
}
-
- public void getChars(char dst[], int dstBegin) {
- getChars(0, count, dst, dstBegin);
+
+ public String toUpperCase() {
+ char[] buffer=new char[count];
+ for(int i=0; i<count; i++) {
+ char x=charAt(i);
+ if (x>='a'&&x<='z') {
+ x=(char) ((x-'a')+'A');
+ }
+ buffer[i]=x;
+ }
+ return new String(buffer);
}
- public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
- if((srcBegin < 0) || (srcEnd > count) || (srcBegin > srcEnd)) {
- // FIXME
- System.printString("Index error: "+srcBegin+" "+srcEnd+" "+count+"\n"+this);
- System.exit(-1);
+ public String toLowerCase() {
+ char[] buffer=new char[count];
+ for(int i=0; i<count; i++) {
+ char x=charAt(i);
+ if (x>='A'&&x<='Z') {
+ x=(char) ((x-'A')+'a');
+ }
+ buffer[i]=x;
}
- int len = srcEnd - srcBegin;
- int j = dstBegin;
- for(int i=srcBegin; i<srcEnd; i++)
- dst[j++]=value[i+offset];
- return;
+ return new String(buffer);
+ }
+
+ public int indexOf(int ch) {
+ return this.indexOf(ch, 0);
}
-
+
+ public int indexOf(int ch, int fromIndex) {
+ for(int i=fromIndex; i<count; i++)
+ if (this.charAt(i)==ch)
+ return i;
+ return -1;
+ }
+
+ public int indexOf(String str) {
+ return this.indexOf(str, 0);
+ }
+
public int indexOf(String str, int fromIndex) {
if (fromIndex<0)
fromIndex=0;
return i;
return -1;
}
-
+
+ public int indexOfIgnoreCase(String str, int fromIndex) {
+ if (fromIndex < 0)
+ fromIndex = 0;
+ }
+
+ public int lastIndexOf(String str, int fromIndex) {
+ int k=count-str.count;
+ if (k>fromIndex)
+ k=fromIndex;
+ for(; k>=0; k--) {
+ if (regionMatches(k, str, 0, str.count))
+ return k;
+ }
+ return -1;
+ }
+
+ public int lastIndexOf(String str) {
+ return lastIndexOf(str, count-str.count);
+ }
+
+ public boolean startsWith(String str) {
+ return regionMatches(0, str, 0, str.count);
+ }
+
+ public boolean startsWith(String str, int toffset) {
+ return regionMatches(toffset, str, 0, str.count);
+ }
+
public boolean regionMatches(int toffset, String other, int ooffset, int len) {
if (toffset<0 || ooffset <0 || (toffset+len)>count || (ooffset+len)>other.count)
return false;
return false;
return true;
}
-
- @RETURNLOC("O")
- public static String valueOf(@LOC("IN") Object o) {
+
+ public char[] toCharArray() {
+ char str[]=new char[count];
+ for(int i=0; i<count; i++)
+ str[i]=value[i+offset];
+ return str;
+ }
+
+ public byte[] getBytes() {
+ byte str[]=new byte[count];
+ for(int i=0; i<count; i++)
+ str[i]=(byte)value[i+offset];
+ return str;
+ }
+
+ public void getChars(char dst[], int dstBegin) {
+ getChars(0, count, dst, dstBegin);
+ }
+
+ public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
+ if((srcBegin < 0) || (srcEnd > count) || (srcBegin > srcEnd)) {
+ // FIXME
+ System.printString("Index error: "+srcBegin+" "+srcEnd+" "+count+"\n"+this);
+ System.exit(-1);
+ }
+ int len = srcEnd - srcBegin;
+ int j = dstBegin;
+ for(int i=srcBegin; i<srcEnd; i++)
+ dst[j++]=value[i+offset];
+ return;
+ }
+
+ public int length() {
+ return count;
+ }
+
+ public char charAt(int i) {
+ return value[i+offset];
+ }
+
+ public String toString() {
+ return this;
+ }
+
+ public static String valueOf(Object o) {
if (o==null)
return "null";
else
return o.toString();
}
-
+
public static String valueOf(boolean b) {
if (b)
return new String("true");
else
return new String("false");
}
-
+
public static String valueOf(char c) {
char ar[]=new char[1];
ar[0]=c;
s.value=chararray;
return s;
}
-
- public static native int convertdoubletochar(double val, char [] chararray);
+ public static native int convertdoubletochar(double val, char [] chararray);
public static String valueOf(long x) {
int length=0;
} while (length!=0);
return new String(chararray);
}
-
- @LATTICE("O<V,V<C,C<IN,THISLOC=IN,C*")
- @RETURNLOC("O")
- public byte[] getBytes() {
- @LOC("V") byte str[]=new byte[count];
- for(@LOC("C") int i=0; i<count; i++)
- str[i]=(byte)value[i+offset];
- return str;
+
+ public int compareTo(String s) {
+ int smallerlength=count<s.count?count:s.count;
+
+ for( int i = 0; i < smallerlength; i++ ) {
+ int valDiff = this.charAt(i) - s.charAt(i);
+ if( valDiff != 0 ) {
+ return valDiff;
+ }
+ }
+ return count-s.count;
}
-
-
-
- @RETURNLOC("IN")
- public int length() {
- return count;
+
+ public int hashCode() {
+ if (cachedHashcode!=0)
+ return cachedHashcode;
+ int hashcode=0;
+ for(int i=0; i<count; i++)
+ hashcode=hashcode*31+value[i+offset];
+ cachedHashcode=hashcode;
+ return hashcode;
}
-
- @RETURNLOC("O")
- public char charAt(@LOC("IN") int index){
- return value[index];
+
+ public boolean equals(Object o) {
+ if (o.getType()!=getType())
+ return false;
+ String s=(String)o;
+ if (s.count!=count)
+ return false;
+ for(int i=0; i<count; i++) {
+ if (s.value[i+s.offset]!=value[i+offset])
+ return false;
+ }
+ return true;
}
- //public static native int convertdoubletochar(double val, char [] chararray);
+ public boolean equalsIgnoreCase(String s) {
+ if (s.count!=count)
+ return false;
+ for(int i=0; i<count; i++) {
+ char l=s.value[i+s.offset];
+ char r=value[i+offset];
+ if (l>='a'&&l<='z')
+ l=(char)((l-'a')+'A');
+ if (r>='a'&&r<='z')
+ r=(char)((r-'a')+'A');
+ if (l!=r)
+ return false;
+ }
+ return true;
+ }
+ public Vector split() {
+ Vector splitted = new Vector();
+ int i;
+ int cnt =0;
+
+ // skip first spaces
+ for(i = 0; i< count; i++) {
+ if(value[i+offset] != '\n' && value[i+offset] != '\t' && value[i+offset] != ' ')
+ break;
+ }
+
+ int oldi=i;
+
+ while(i<count) {
+ if(value[i+offset] == '\n' || value[i+offset] == '\t' || value[i+offset] == ' ') {
+ String t=new String();
+ t.value=value;
+ t.offset=oldi;
+ t.count=i-oldi;
+ splitted.addElement(t);
+
+ // skip extra spaces
+ while( i < count && ( value[i+offset] == '\n' || value[i+offset] == '\t' || value[i+offset] == ' ')) {
+ i++;
+ }
+ oldi=i;
+ } else {
+ i++;
+ }
+ }
+
+ if(i!=oldi) {
+ String t=new String();
+ t.value=value;
+ t.offset=oldi;
+ t.count=i-oldi;
+ splitted.addElement(t);
+ }
+
+ return splitted;
+ }
+
+ public boolean contains(String str) {
+ int i,j;
+ char[] strChar = str.toCharArray();
+ int cnt;
+
+ for(i = 0; i < count; i++) {
+ if(value[i] == strChar[0]) {
+ cnt=0;
+ for(j=0; j < str.length() && i+j < count; j++) {
+ if(value[i+j] == strChar[j])
+ cnt++;
+ }
+ if(cnt == str.length())
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+ public String trim() {
+ int len = count;
+ int st = 0;
+ int off = offset; /* avoid getfield opcode */
+ char[] val = value; /* avoid getfield opcode */
+
+ while ((st < len) && (val[off + st] <= ' ')) {
+ st++;
+ }
+ while ((st < len) && (val[off + len - 1] <= ' ')) {
+ len--;
+ }
+ return ((st > 0) || (len < count))?substring(st, len):this;
+ }
+
+ public boolean matches(String regex) {
+ System.println("String.matches() is not fully supported");
+ return this.equals(regex);
+ }
}
public static native void printString(String s);
- public static void println(@LOC("IN") String s) {
+ public static void println(@LOC("IN") String s) {
System.printString(s + "\n");
}
+ public static void println(int o) {
+ System.printString("" + o + "\n");
+ }
+
+ public static void println(double o) {
+ System.printString("" + o + "\n");
+ }
+
+ public static void println(long o) {
+ System.printString("" + o + "\n");
+ }
+
public static void println() {
System.printString("\n");
}
System.printString(s);
}
+ public static void print(Object o) {
+ System.printString("" + o);
+ }
+
+ public static void print(int o) {
+ System.printString("" + o);
+ }
+
+ public static void print(double o) {
+ System.printString("" + o);
+ }
+
+ public static void print(long o) {
+ System.printString("" + o);
+ }
+
public static void error() {
System
.printString("Error (Use Breakpoint on ___System______error method for more information!)\n");
--- /dev/null
+public class Vector {
+ Object[] array;
+ int size;
+ int capacityIncrement;
+
+ public Vector() {
+ capacityIncrement=0;
+ size=0;
+ array=new Object[10];
+ }
+
+ public Vector(int size) {
+ capacityIncrement=0;
+ this.size=0;
+ array=new Object[size];
+ }
+
+ //used for internal cloning
+ private Vector(int size, int capacityIncrement, Object[] array) {
+ this.size = size;
+ this.capacityIncrement = capacityIncrement;
+ this.array = new Object[array.length];
+ System.arraycopy(array, 0, this.array, 0, size);
+ }
+
+ public Vector clone() {
+ return new Vector(size,capacityIncrement, array);
+ }
+
+ public boolean isEmpty() {
+ return size==0;
+ }
+
+ public void clear() {
+ size=0;
+ array=new Object[10];
+ }
+
+ public int indexOf(Object elem) {
+ return indexOf(elem, 0);
+ }
+
+ public int indexOf(Object elem, int index) {
+ for(int i=index; i<size; i++) {
+ if (elem.equals(array[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ public boolean contains(Object e) {
+ return indexOf(e)!=-1;
+ }
+
+ public boolean remove(Object o) {
+ int in=indexOf(o);
+ if (in!=-1) {
+ removeElementAt(in);
+ return true;
+ }
+
+ return false;
+ }
+
+ public Object elementAt(int index) {
+ if (index<0 | index >=size) {
+ System.printString("Illegal Vector.elementAt\n");
+ System.exit(-1);
+ return null;
+ }
+ return array[index];
+ }
+
+ public void setElementAt(Object obj, int index) {
+ if (index <size)
+ array[index]=obj;
+ else {
+ System.printString("Illegal Vector.setElementAt\n");
+ System.exit(-1);
+ }
+ }
+
+ private void ensureCapacity(int minCapacity) {
+ if (minCapacity>array.length) {
+ int newsize;
+ if (capacityIncrement<=0)
+ newsize=array.length*2;
+ else
+ newsize=array.length+capacityIncrement;
+ if (newsize<minCapacity)
+ newsize=minCapacity;
+ Object [] newarray=new Object[newsize];
+ for(int i=0; i<size; i++)
+ newarray[i]=array[i];
+ array=newarray;
+ }
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public Enumeration elements() {
+ System.printString("Vector.elements not implemented\n");
+ System.exit(-1);
+ }
+
+ public void addElement(Object obj) {
+ if (size==array.length) {
+ ensureCapacity(size+1);
+ }
+ array[size++]=obj;
+ }
+
+ public void insertElementAt(Object obj, int index) {
+ if (index<0||index>size) {
+ System.printString("Illegal Vector.insertElementAt\n");
+ System.exit(-1);
+ }
+
+ if (size==array.length) {
+ ensureCapacity(size+1);
+ }
+ size++;
+ for(int i=size-1; i>index; --i) {
+ array[i] = array[i-1];
+ }
+ array[index] = obj;
+ }
+
+ public void removeElementAt(int index) {
+ if (index<0||index>=size) {
+ System.printString("Illegal Vector.removeElementAt\n");
+ System.exit(-1);
+ }
+ removeElement(array, index, size);
+ size--;
+ array[size]=null;
+ }
+
+ public static native void removeElement(Object[] array, int index, int size);
+
+ public void removeAllElements() {
+ int s = size;
+ for(int i = 0; i<s; ++i ) {
+ removeElementAt(0);
+ }
+ }
+}
/*
* 11/19/04 1.0 moved to LGPL.
*
- * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net
+ * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net
*
- * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net
+ * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net
*
- * 12/12/99 Based on Ibitstream. Exceptions thrown on errors,
- * Temporary removed seek functionality. mdm@techie.com
+ * 12/12/99 Based on Ibitstream. Exceptions thrown on errors,
+ * Temporary removed seek functionality. mdm@techie.com
*
* 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net
*
private int header_pos = 0;
/**
- *
- */
+ *
+ */
@LOC("F")
private boolean single_ch_mode;
// private int current_frame_number;
* of the stream has been reached.
*/
public Header readFrame() throws BitstreamException {
+
+ System.out.println("ST");
+
Header result = null;
try {
+ System.out.println("HERE?");
result = readNextFrame();
+ System.out.println("HERE?2");
// E.B, Parse VBR (if any) first frame.
if (firstframe == true) {
result.parseVBR(frame_bytes);
firstframe = false;
}
+
+ int channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2;
+ result.setSideInfoBuf(getSideInfoBuffer(channels));
+ result.setBitReserve(getBitReserve(result.slots()));
+
} catch (BitstreamException ex) {
if ((ex.getErrorCode() == INVALIDFRAME)) {
// Try to skip this frame.
// System.out.println("INVALIDFRAME");
- try {
+ try { System.out.println("ET");
+
closeFrame();
result = readNextFrame();
} catch (BitstreamException e) {
throw newBitstreamException(ex.getErrorCode(), ex);
}
}
+ System.out.println("EN");
+
return result;
}
* @throws BitstreamException
*/
private Header readNextFrame() throws BitstreamException {
+ System.out.println("framesize="+framesize);
if (framesize == -1) {
nextFrame();
}
*/
private void nextFrame() throws BitstreamException {
// entire frame is read by the header class.
+ System.out.println("nextFrame()");
header.read_header(this, crc);
}
*/\r
@LOC("DE")\r
private LayerIIIDecoder l3decoder;\r
- @LOC("DE")\r
- private LayerIIDecoder l2decoder;\r
- @LOC("DE")\r
- private LayerIDecoder l1decoder;\r
+ // @LOC("DE")\r
+ // private LayerIIDecoder l2decoder;\r
+ // @LOC("DE")\r
+ // private LayerIDecoder l1decoder;\r
\r
@LOC("O")\r
private int outputFrequency;\r
@LOC("TH") int layer = header.layer();\r
\r
output.clear_buffer();\r
-\r
+System.out.println("HERE?="+layer);\r
@LOC("DE,Decoder.DE") FrameDecoder decoder = retrieveDecoder(header, stream, layer); // return\r
// ceil=DELTA(TH)\r
decoder.decodeFrame();\r
return l3decoder;\r
// decoder = l3decoder;\r
break;\r
- case 2:\r
- if (l2decoder == null) {\r
- l2decoder = new LayerIIDecoder();\r
- l2decoder.create(stream, header, filter1, filter2, output, OutputChannels.BOTH_CHANNELS);\r
- }\r
- return l2decoder;\r
- // decoder = l2decoder;\r
- break;\r
- case 1:\r
- if (l1decoder == null) {\r
- l1decoder = new LayerIDecoder();\r
- l1decoder.create(stream, header, filter1, filter2, output, OutputChannels.BOTH_CHANNELS);\r
- }\r
- return l1decoder;\r
- // decoder = l1decoder;\r
- break;\r
+ // case 2:\r
+ // if (l2decoder == null) {\r
+ // l2decoder = new LayerIIDecoder();\r
+ // l2decoder.create(stream, header, filter1, filter2, output,\r
+ // OutputChannels.BOTH_CHANNELS);\r
+ // }\r
+ // return l2decoder;\r
+ // // decoder = l2decoder;\r
+ // break;\r
+ // case 1:\r
+ // if (l1decoder == null) {\r
+ // l1decoder = new LayerIDecoder();\r
+ // l1decoder.create(stream, header, filter1, filter2, output,\r
+ // OutputChannels.BOTH_CHANNELS);\r
+ // }\r
+ // return l1decoder;\r
+ // // decoder = l1decoder;\r
+ // break;\r
}\r
//\r
// if (decoder==null)\r
-/*\r
- * 11/19/04 : 1.0 moved to LGPL.\r
- * VBRI header support added, E.B javalayer@javazoom.net\r
- * \r
- * 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net\r
- *\r
- * 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net\r
- *\r
- * Declarations for MPEG header class\r
- * A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay.\r
- * Last modified : 04/19/97\r
- *\r
- * @(#) header.h 1.7, last edit: 6/15/94 16:55:33\r
- * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)\r
- * @(#) Berlin University of Technology\r
- *-----------------------------------------------------------------------\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU Library General Public License as published\r
- * by the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU Library General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Library General Public\r
- * License along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- *----------------------------------------------------------------------\r
- */\r
-\r
-/**\r
- * Class for extracting information from a frame header.\r
- */\r
-@LATTICE("HI<HNS,HNS<H,C<H,NS<FS,FS<H,FS<HV,H<SYNC,HV<SYNC,HV<T,SYNC*,HV*,FS*,HI*")\r
-@METHODDEFAULT("OUT<V,V<THIS,THIS<SH,SH<IN,SH*,THISLOC=THIS,GLOBALLOC=IN")\r
-public final class Header {\r
-\r
- public static final int[][] frequencies = { { 22050, 24000, 16000, 1 },\r
- { 44100, 48000, 32000, 1 }, { 11025, 12000, 8000, 1 } }; // SZD: MPEG25\r
-\r
- /**\r
- * Constant for MPEG-2 LSF version\r
- */\r
- public static final int MPEG2_LSF = 0;\r
- public static final int MPEG25_LSF = 2; // SZD\r
-\r
- /**\r
- * Constant for MPEG-1 version\r
- */\r
- public static final int MPEG1 = 1;\r
-\r
- public static final int STEREO = 0;\r
- public static final int JOINT_STEREO = 1;\r
- public static final int DUAL_CHANNEL = 2;\r
- public static final int SINGLE_CHANNEL = 3;\r
- public static final int FOURTYFOUR_POINT_ONE = 0;\r
- public static final int FOURTYEIGHT = 1;\r
- public static final int THIRTYTWO = 2;\r
-\r
- @LOC("H")\r
- private int h_layer;\r
- @LOC("H")\r
- private int h_protection_bit;\r
- @LOC("H")\r
- private int h_bitrate_index;\r
- @LOC("H")\r
- private int h_padding_bit;\r
- @LOC("H")\r
- private int h_mode_extension;\r
- @LOC("HV")\r
- private int h_version;\r
- @LOC("H")\r
- private int h_mode;\r
- @LOC("H")\r
- private int h_sample_frequency;\r
- @LOC("HNS")\r
- private int h_number_of_subbands;\r
- @LOC("HI")\r
- private int h_intensity_stereo_bound;\r
- @LOC("H")\r
- private boolean h_copyright;\r
- @LOC("H")\r
- private boolean h_original;\r
- // VBR support added by E.B\r
- @LOC("T")\r
- private double[] h_vbr_time_per_frame = { -1.0, 384.0, 1152.0, 1152.0 };\r
- @LOC("T")\r
- private boolean h_vbr;\r
- @LOC("T")\r
- private int h_vbr_frames;\r
- @LOC("T")\r
- private int h_vbr_scale;\r
- @LOC("T")\r
- private int h_vbr_bytes;\r
- @LOC("T")\r
- private byte[] h_vbr_toc;\r
-\r
- @LOC("SYNC")\r
- private byte syncmode = Bitstream.INITIAL_SYNC;\r
- @LOC("C")\r
- private Crc16 crc;\r
-\r
- @LOC("C")\r
- public short checksum;\r
- @LOC("FS")\r
- public int framesize;\r
- @LOC("NS")\r
- public int nSlots;\r
-\r
- @LOC("T")\r
- private int _headerstring = -1; // E.B\r
-\r
- private SideInfoBuffer sib;\r
- private BitReserve br;\r
-\r
- Header() {\r
- }\r
-\r
- public String toString() {\r
- StringBuffer buffer = new StringBuffer(200);\r
- buffer.append("Layer ");\r
- buffer.append(layer_string());\r
- buffer.append(" frame ");\r
- buffer.append(mode_string());\r
- buffer.append(' ');\r
- buffer.append(version_string());\r
- if (!checksums())\r
- buffer.append(" no");\r
- buffer.append(" checksums");\r
- buffer.append(' ');\r
- buffer.append(sample_frequency_string());\r
- buffer.append(',');\r
- buffer.append(' ');\r
- buffer.append(bitrate_string());\r
-\r
- String s = buffer.toString();\r
- return s;\r
- }\r
-\r
- /**\r
- * Read a 32-bit header from the bitstream.\r
- */\r
- void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException {\r
- int headerstring;\r
- int channel_bitrate;\r
- boolean sync = false;\r
- do {\r
- headerstring = stream.syncHeader(syncmode);\r
- _headerstring = headerstring; // E.B\r
- if (syncmode == Bitstream.INITIAL_SYNC) {\r
- h_version = ((headerstring >>> 19) & 1);\r
- if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection\r
- if (h_version == MPEG2_LSF)\r
- h_version = MPEG25_LSF;\r
- else\r
- throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
- if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) {\r
- throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
- }\r
- }\r
- h_layer = 4 - (headerstring >>> 17) & 3;\r
- h_protection_bit = (headerstring >>> 16) & 1;\r
- h_bitrate_index = (headerstring >>> 12) & 0xF;\r
- h_padding_bit = (headerstring >>> 9) & 1;\r
- h_mode = ((headerstring >>> 6) & 3);\r
- h_mode_extension = (headerstring >>> 4) & 3;\r
- if (h_mode == JOINT_STEREO)\r
- h_intensity_stereo_bound = (h_mode_extension << 2) + 4;\r
- else\r
- h_intensity_stereo_bound = 0; // should never be used\r
- if (((headerstring >>> 3) & 1) == 1)\r
- h_copyright = true;\r
- if (((headerstring >>> 2) & 1) == 1)\r
- h_original = true;\r
- // calculate number of subbands:\r
- if (h_layer == 1)\r
- h_number_of_subbands = 32;\r
- else {\r
- channel_bitrate = h_bitrate_index;\r
- // calculate bitrate per channel:\r
- if (h_mode != SINGLE_CHANNEL)\r
- if (channel_bitrate == 4)\r
- channel_bitrate = 1;\r
- else\r
- channel_bitrate -= 4;\r
- if ((channel_bitrate == 1) || (channel_bitrate == 2))\r
- if (h_sample_frequency == THIRTYTWO)\r
- h_number_of_subbands = 12;\r
- else\r
- h_number_of_subbands = 8;\r
- else if ((h_sample_frequency == FOURTYEIGHT)\r
- || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))\r
- h_number_of_subbands = 27;\r
- else\r
- h_number_of_subbands = 30;\r
- }\r
- if (h_intensity_stereo_bound > h_number_of_subbands)\r
- h_intensity_stereo_bound = h_number_of_subbands;\r
- // calculate framesize and nSlots\r
- calculate_framesize();\r
- // read framedata:\r
- int framesizeloaded = stream.read_frame_data(framesize);\r
- if ((framesize >= 0) && (framesizeloaded != framesize)) {\r
- // Data loaded does not match to expected framesize,\r
- // it might be an ID3v1 TAG. (Fix 11/17/04).\r
- throw stream.newBitstreamException(Bitstream.INVALIDFRAME);\r
- }\r
- if (stream.isSyncCurrentPosition(syncmode)) {\r
- if (syncmode == Bitstream.INITIAL_SYNC) {\r
- syncmode = Bitstream.STRICT_SYNC;\r
- stream.set_syncword(headerstring & 0xFFF80CC0);\r
- }\r
- sync = true;\r
- } else {\r
- stream.unreadFrame();\r
- }\r
- } while (!sync);\r
- stream.parse_frame();\r
- if (h_protection_bit == 0) {\r
- // frame contains a crc checksum\r
- checksum = (short) stream.get_bits(16);\r
- if (crc == null)\r
- crc = new Crc16();\r
- crc.add_bits(headerstring, 16);\r
- crcp[0] = crc;\r
- } else\r
- crcp[0] = null;\r
- if (h_sample_frequency == FOURTYFOUR_POINT_ONE) {\r
- /*\r
- * if (offset == null) { int max = max_number_of_frames(stream); offset =\r
- * new int[max]; for(int i=0; i<max; i++) offset[i] = 0; } // E.B :\r
- * Investigate more int cf = stream.current_frame(); int lf =\r
- * stream.last_frame(); if ((cf > 0) && (cf == lf)) { offset[cf] =\r
- * offset[cf-1] + h_padding_bit; } else { offset[0] = h_padding_bit; }\r
- */\r
- }\r
- }\r
-\r
- /**\r
- * Parse frame to extract optionnal VBR frame.\r
- * \r
- * @param firstframe\r
- * @author E.B (javalayer@javazoom.net)\r
- */\r
- void parseVBR(byte[] firstframe) throws BitstreamException {\r
- // Trying Xing header.\r
- String xing = "Xing";\r
- byte tmp[] = new byte[4];\r
- int offset = 0;\r
- // Compute "Xing" offset depending on MPEG version and channels.\r
- if (h_version == MPEG1) {\r
- if (h_mode == SINGLE_CHANNEL)\r
- offset = 21 - 4;\r
- else\r
- offset = 36 - 4;\r
- } else {\r
- if (h_mode == SINGLE_CHANNEL)\r
- offset = 13 - 4;\r
- else\r
- offset = 21 - 4;\r
- }\r
- try {\r
- System.arraycopy(firstframe, offset, tmp, 0, 4);\r
- // Is "Xing" ?\r
- if (xing.equals(new String(tmp))) {\r
- // Yes.\r
- h_vbr = true;\r
- h_vbr_frames = -1;\r
- h_vbr_bytes = -1;\r
- h_vbr_scale = -1;\r
- h_vbr_toc = new byte[100];\r
-\r
- int length = 4;\r
- // Read flags.\r
- byte flags[] = new byte[4];\r
- System.arraycopy(firstframe, offset + length, flags, 0, flags.length);\r
- length += flags.length;\r
- // Read number of frames (if available).\r
- if ((flags[3] & (byte) (1 << 0)) != 0) {\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_frames =\r
- (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
- & 0x0000FF00 | tmp[3] & 0x000000FF;\r
- length += 4;\r
- }\r
- // Read size (if available).\r
- if ((flags[3] & (byte) (1 << 1)) != 0) {\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_bytes =\r
- (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
- & 0x0000FF00 | tmp[3] & 0x000000FF;\r
- length += 4;\r
- }\r
- // Read TOC (if available).\r
- if ((flags[3] & (byte) (1 << 2)) != 0) {\r
- System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);\r
- length += h_vbr_toc.length;\r
- }\r
- // Read scale (if available).\r
- if ((flags[3] & (byte) (1 << 3)) != 0) {\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_scale =\r
- (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
- & 0x0000FF00 | tmp[3] & 0x000000FF;\r
- length += 4;\r
- }\r
- // System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames\r
- // +" Size:"+h_vbr_bytes);\r
- }\r
- } catch (ArrayIndexOutOfBoundsException e) {\r
- throw new BitstreamException("XingVBRHeader Corrupted", e);\r
- }\r
-\r
- // Trying VBRI header.\r
- String vbri = "VBRI";\r
- offset = 36 - 4;\r
- try {\r
- System.arraycopy(firstframe, offset, tmp, 0, 4);\r
- // Is "VBRI" ?\r
- if (vbri.equals(new String(tmp))) {\r
- // Yes.\r
- h_vbr = true;\r
- h_vbr_frames = -1;\r
- h_vbr_bytes = -1;\r
- h_vbr_scale = -1;\r
- h_vbr_toc = new byte[100];\r
- // Bytes.\r
- int length = 4 + 6;\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_bytes =\r
- (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00\r
- | tmp[3] & 0x000000FF;\r
- length += 4;\r
- // Frames.\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_frames =\r
- (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00\r
- | tmp[3] & 0x000000FF;\r
- length += 4;\r
- // System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames\r
- // +" Size:"+h_vbr_bytes);\r
- // TOC\r
- // TODO\r
- }\r
- } catch (ArrayIndexOutOfBoundsException e) {\r
- throw new BitstreamException("VBRIVBRHeader Corrupted", e);\r
- }\r
- }\r
-\r
- // Functions to query header contents:\r
- /**\r
- * Returns version.\r
- */\r
- @RETURNLOC("OUT")\r
- public int version() {\r
- return h_version;\r
- }\r
-\r
- /**\r
- * Returns Layer ID.\r
- */\r
- @RETURNLOC("OUT")\r
- public int layer() {\r
- return h_layer;\r
- }\r
-\r
- /**\r
- * Returns bitrate index.\r
- */\r
- @RETURNLOC("OUT")\r
- public int bitrate_index() {\r
- return h_bitrate_index;\r
- }\r
-\r
- /**\r
- * Returns Sample Frequency.\r
- */\r
- public int sample_frequency() {\r
- return h_sample_frequency;\r
- }\r
-\r
- /**\r
- * Returns Frequency.\r
- */\r
- public int frequency() {\r
- return frequencies[h_version][h_sample_frequency];\r
- }\r
-\r
- /**\r
- * Returns Mode.\r
- */\r
- @RETURNLOC("OUT")\r
- public int mode() {\r
- return h_mode;\r
- }\r
-\r
- /**\r
- * Returns Protection bit.\r
- */\r
- public boolean checksums() {\r
- if (h_protection_bit == 0)\r
- return true;\r
- else\r
- return false;\r
- }\r
-\r
- /**\r
- * Returns Copyright.\r
- */\r
- public boolean copyright() {\r
- return h_copyright;\r
- }\r
-\r
- /**\r
- * Returns Original.\r
- */\r
- public boolean original() {\r
- return h_original;\r
- }\r
-\r
- /**\r
- * Return VBR.\r
- * \r
- * @return true if VBR header is found\r
- */\r
- public boolean vbr() {\r
- return h_vbr;\r
- }\r
-\r
- /**\r
- * Return VBR scale.\r
- * \r
- * @return scale of -1 if not available\r
- */\r
- public int vbr_scale() {\r
- return h_vbr_scale;\r
- }\r
-\r
- /**\r
- * Return VBR TOC.\r
- * \r
- * @return vbr toc ot null if not available\r
- */\r
- public byte[] vbr_toc() {\r
- return h_vbr_toc;\r
- }\r
-\r
- /**\r
- * Returns Checksum flag. Compares computed checksum with stream checksum.\r
- */\r
- @RETURNLOC("OUT")\r
- public boolean checksum_ok() {\r
- return (checksum == crc.checksum());\r
- }\r
-\r
- // Seeking and layer III stuff\r
- /**\r
- * Returns Layer III Padding bit.\r
- */\r
- public boolean padding() {\r
- if (h_padding_bit == 0)\r
- return false;\r
- else\r
- return true;\r
- }\r
-\r
- /**\r
- * Returns Slots.\r
- */\r
- @RETURNLOC("OUT")\r
- public int slots() {\r
- return nSlots;\r
- }\r
-\r
- /**\r
- * Returns Mode Extension.\r
- */\r
- @RETURNLOC("OUT")\r
- public int mode_extension() {\r
- return h_mode_extension;\r
- }\r
-\r
- // E.B -> private to public\r
- @LOC("T")\r
- public static final int bitrates[][][] = {\r
- {\r
- { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,\r
- 160000, 176000, 192000, 224000, 256000, 0 },\r
- { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
- 96000, 112000, 128000, 144000, 160000, 0 },\r
- { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
- 96000, 112000, 128000, 144000, 160000, 0 } },\r
-\r
- {\r
- { 0 /* free format */, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000,\r
- 288000, 320000, 352000, 384000, 416000, 448000, 0 },\r
- { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000,\r
- 192000, 224000, 256000, 320000, 384000, 0 },\r
- { 0 /* free format */, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000,\r
- 160000, 192000, 224000, 256000, 320000, 0 } },\r
- // SZD: MPEG2.5\r
- {\r
- { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,\r
- 160000, 176000, 192000, 224000, 256000, 0 },\r
- { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
- 96000, 112000, 128000, 144000, 160000, 0 },\r
- { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
- 96000, 112000, 128000, 144000, 160000, 0 } },\r
-\r
- };\r
-\r
- // E.B -> private to public\r
- /**\r
- * Calculate Frame size. Calculates framesize in bytes excluding header size.\r
- */\r
- public int calculate_framesize() {\r
-\r
- if (h_layer == 1) {\r
- framesize =\r
- (12 * bitrates[h_version][0][h_bitrate_index])\r
- / frequencies[h_version][h_sample_frequency];\r
- if (h_padding_bit != 0)\r
- framesize++;\r
- framesize <<= 2; // one slot is 4 bytes long\r
- nSlots = 0;\r
- } else {\r
- framesize =\r
- (144 * bitrates[h_version][h_layer - 1][h_bitrate_index])\r
- / frequencies[h_version][h_sample_frequency];\r
- if (h_version == MPEG2_LSF || h_version == MPEG25_LSF)\r
- framesize >>= 1; // SZD\r
- if (h_padding_bit != 0)\r
- framesize++;\r
- // Layer III slots\r
- if (h_layer == 3) {\r
- if (h_version == MPEG1) {\r
- nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side\r
- // info\r
- // size\r
- - ((h_protection_bit != 0) ? 0 : 2) // CRC size\r
- - 4; // header size\r
- } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF\r
- nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side\r
- // info\r
- // size\r
- - ((h_protection_bit != 0) ? 0 : 2) // CRC size\r
- - 4; // header size\r
- }\r
- } else {\r
- nSlots = 0;\r
- }\r
- }\r
- framesize -= 4; // subtract header size\r
- return framesize;\r
- }\r
-\r
- /**\r
- * Returns the maximum number of frames in the stream.\r
- * \r
- * @param streamsize\r
- * @return number of frames\r
- */\r
- public int max_number_of_frames(int streamsize) // E.B\r
- {\r
- if (h_vbr == true)\r
- return h_vbr_frames;\r
- else {\r
- if ((framesize + 4 - h_padding_bit) == 0)\r
- return 0;\r
- else\r
- return (streamsize / (framesize + 4 - h_padding_bit));\r
- }\r
- }\r
-\r
- /**\r
- * Returns the maximum number of frames in the stream.\r
- * \r
- * @param streamsize\r
- * @return number of frames\r
- */\r
- public int min_number_of_frames(int streamsize) // E.B\r
- {\r
- if (h_vbr == true)\r
- return h_vbr_frames;\r
- else {\r
- if ((framesize + 5 - h_padding_bit) == 0)\r
- return 0;\r
- else\r
- return (streamsize / (framesize + 5 - h_padding_bit));\r
- }\r
- }\r
-\r
- /**\r
- * Returns ms/frame.\r
- * \r
- * @return milliseconds per frame\r
- */\r
- public float ms_per_frame() // E.B\r
- {\r
- if (h_vbr == true) {\r
- double tpf = h_vbr_time_per_frame[layer()] / frequency();\r
- if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF))\r
- tpf /= 2;\r
- return ((float) (tpf * 1000));\r
- } else {\r
- float ms_per_frame_array[][] =\r
- { { 8.707483f, 8.0f, 12.0f }, { 26.12245f, 24.0f, 36.0f }, { 26.12245f, 24.0f, 36.0f } };\r
- return (ms_per_frame_array[h_layer - 1][h_sample_frequency]);\r
- }\r
- }\r
-\r
- /**\r
- * Returns total ms.\r
- * \r
- * @param streamsize\r
- * @return total milliseconds\r
- */\r
- public float total_ms(int streamsize) // E.B\r
- {\r
- return (max_number_of_frames(streamsize) * ms_per_frame());\r
- }\r
-\r
- /**\r
- * Returns synchronized header.\r
- */\r
- public int getSyncHeader() // E.B\r
- {\r
- return _headerstring;\r
- }\r
-\r
- // functions which return header informations as strings:\r
- /**\r
- * Return Layer version.\r
- */\r
- public String layer_string() {\r
- switch (h_layer) {\r
- case 1:\r
- return "I";\r
- case 2:\r
- return "II";\r
- case 3:\r
- return "III";\r
- }\r
- return null;\r
- }\r
-\r
- // E.B -> private to public\r
- @LOC("T")\r
- public static final String bitrate_str[][][] = {\r
- {\r
- { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",\r
- "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },\r
- { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
- "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
- "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },\r
- { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
- "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
- "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } },\r
-\r
- {\r
- { "free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", "160 kbit/s",\r
- "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", "320 kbit/s", "352 kbit/s",\r
- "384 kbit/s", "416 kbit/s", "448 kbit/s", "forbidden" },\r
- { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s",\r
- "256 kbit/s", "320 kbit/s", "384 kbit/s", "forbidden" },\r
- { "free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
- "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s",\r
- "224 kbit/s", "256 kbit/s", "320 kbit/s", "forbidden" } },\r
- // SZD: MPEG2.5\r
- {\r
- { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",\r
- "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },\r
- { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
- "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
- "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },\r
- { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
- "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
- "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } }, };\r
-\r
- /**\r
- * Return Bitrate.\r
- * \r
- * @return bitrate in bps\r
- */\r
- public String bitrate_string() {\r
- if (h_vbr == true) {\r
- return Integer.toString(bitrate() / 1000) + " kb/s";\r
- } else\r
- return bitrate_str[h_version][h_layer - 1][h_bitrate_index];\r
- }\r
-\r
- /**\r
- * Return Bitrate.\r
- * \r
- * @return bitrate in bps and average bitrate for VBR header\r
- */\r
- public int bitrate() {\r
- if (h_vbr == true) {\r
- return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames))) * 1000;\r
- } else\r
- return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
- }\r
-\r
- /**\r
- * Return Instant Bitrate. Bitrate for VBR is not constant.\r
- * \r
- * @return bitrate in bps\r
- */\r
- public int bitrate_instant() {\r
- return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
- }\r
-\r
- /**\r
- * Returns Frequency\r
- * \r
- * @return frequency string in kHz\r
- */\r
- public String sample_frequency_string() {\r
- switch (h_sample_frequency) {\r
- case THIRTYTWO:\r
- if (h_version == MPEG1)\r
- return "32 kHz";\r
- else if (h_version == MPEG2_LSF)\r
- return "16 kHz";\r
- else\r
- // SZD\r
- return "8 kHz";\r
- case FOURTYFOUR_POINT_ONE:\r
- if (h_version == MPEG1)\r
- return "44.1 kHz";\r
- else if (h_version == MPEG2_LSF)\r
- return "22.05 kHz";\r
- else\r
- // SZD\r
- return "11.025 kHz";\r
- case FOURTYEIGHT:\r
- if (h_version == MPEG1)\r
- return "48 kHz";\r
- else if (h_version == MPEG2_LSF)\r
- return "24 kHz";\r
- else\r
- // SZD\r
- return "12 kHz";\r
- }\r
- return (null);\r
- }\r
-\r
- /**\r
- * Returns Mode.\r
- */\r
- public String mode_string() {\r
- switch (h_mode) {\r
- case STEREO:\r
- return "Stereo";\r
- case JOINT_STEREO:\r
- return "Joint stereo";\r
- case DUAL_CHANNEL:\r
- return "Dual channel";\r
- case SINGLE_CHANNEL:\r
- return "Single channel";\r
- }\r
- return null;\r
- }\r
-\r
- /**\r
- * Returns Version.\r
- * \r
- * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF\r
- */\r
- public String version_string() {\r
- switch (h_version) {\r
- case MPEG1:\r
- return "MPEG-1";\r
- case MPEG2_LSF:\r
- return "MPEG-2 LSF";\r
- case MPEG25_LSF: // SZD\r
- return "MPEG-2.5 LSF";\r
- }\r
- return (null);\r
- }\r
-\r
- /**\r
- * Returns the number of subbands in the current frame.\r
- * \r
- * @return number of subbands\r
- */\r
- @RETURNLOC("OUT")\r
- public int number_of_subbands() {\r
- return h_number_of_subbands;\r
- }\r
-\r
- /**\r
- * Returns Intensity Stereo. (Layer II joint stereo only). Returns the number\r
- * of subbands which are in stereo mode, subbands above that limit are in\r
- * intensity stereo mode.\r
- * \r
- * @return intensity\r
- */\r
- @RETURNLOC("OUT")\r
- public int intensity_stereo_bound() {\r
- return h_intensity_stereo_bound;\r
- }\r
-\r
- public void setSideInfoBuf(SideInfoBuffer sib) {\r
- this.sib = sib;\r
- }\r
-\r
- public void setBitReserve(BitReserve br) {\r
- this.br = br;\r
- }\r
-\r
- public SideInfoBuffer getSideInfoBuffer() {\r
- return sib;\r
- }\r
-\r
- public BitReserve getBitReserve() {\r
- return br;\r
- }\r
-\r
-}\r
+/*
+ * 11/19/04 : 1.0 moved to LGPL.
+ * VBRI header support added, E.B javalayer@javazoom.net
+ *
+ * 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net
+ *
+ * 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net
+ *
+ * Declarations for MPEG header class
+ * A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay.
+ * Last modified : 04/19/97
+ *
+ * @(#) header.h 1.7, last edit: 6/15/94 16:55:33
+ * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
+ * @(#) Berlin University of Technology
+ *-----------------------------------------------------------------------
+ * 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.
+ *----------------------------------------------------------------------
+ */
+
+/**
+ * Class for extracting information from a frame header.
+ */
+@LATTICE("HI<HNS,HNS<H,C<H,NS<FS,FS<H,FS<HV,H<SYNC,HV<SYNC,HV<T,SYNC*,HV*,FS*,HI*")
+@METHODDEFAULT("OUT<V,V<THIS,THIS<SH,SH<IN,SH*,THISLOC=THIS,GLOBALLOC=IN")
+public final class Header {
+
+ public static final int[][] frequencies = { { 22050, 24000, 16000, 1 },
+ { 44100, 48000, 32000, 1 }, { 11025, 12000, 8000, 1 } }; // SZD: MPEG25
+
+ /**
+ * Constant for MPEG-2 LSF version
+ */
+ public static final int MPEG2_LSF = 0;
+ public static final int MPEG25_LSF = 2; // SZD
+
+ /**
+ * Constant for MPEG-1 version
+ */
+ public static final int MPEG1 = 1;
+
+ public static final int STEREO = 0;
+ public static final int JOINT_STEREO = 1;
+ public static final int DUAL_CHANNEL = 2;
+ public static final int SINGLE_CHANNEL = 3;
+ public static final int FOURTYFOUR_POINT_ONE = 0;
+ public static final int FOURTYEIGHT = 1;
+ public static final int THIRTYTWO = 2;
+
+ @LOC("H")
+ private int h_layer;
+ @LOC("H")
+ private int h_protection_bit;
+ @LOC("H")
+ private int h_bitrate_index;
+ @LOC("H")
+ private int h_padding_bit;
+ @LOC("H")
+ private int h_mode_extension;
+ @LOC("HV")
+ private int h_version;
+ @LOC("H")
+ private int h_mode;
+ @LOC("H")
+ private int h_sample_frequency;
+ @LOC("HNS")
+ private int h_number_of_subbands;
+ @LOC("HI")
+ private int h_intensity_stereo_bound;
+ @LOC("H")
+ private boolean h_copyright;
+ @LOC("H")
+ private boolean h_original;
+ // VBR support added by E.B
+ @LOC("T")
+ private double[] h_vbr_time_per_frame = { -1.0, 384.0, 1152.0, 1152.0 };
+ @LOC("T")
+ private boolean h_vbr;
+ @LOC("T")
+ private int h_vbr_frames;
+ @LOC("T")
+ private int h_vbr_scale;
+ @LOC("T")
+ private int h_vbr_bytes;
+ @LOC("T")
+ private byte[] h_vbr_toc;
+
+ @LOC("SYNC")
+ private byte syncmode = Bitstream.INITIAL_SYNC;
+ @LOC("C")
+ private Crc16 crc;
+
+ @LOC("C")
+ public short checksum;
+ @LOC("FS")
+ public int framesize;
+ @LOC("NS")
+ public int nSlots;
+
+ @LOC("T")
+ private int _headerstring = -1; // E.B
+
+ private SideInfoBuffer sib;
+ private BitReserve br;
+
+ Header() {
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(200);
+ buffer.append("Layer ");
+ buffer.append(layer_string());
+ buffer.append(" frame ");
+ buffer.append(mode_string());
+ buffer.append(' ');
+ buffer.append(version_string());
+ if (!checksums())
+ buffer.append(" no");
+ buffer.append(" checksums");
+ buffer.append(' ');
+ buffer.append(sample_frequency_string());
+ buffer.append(',');
+ buffer.append(' ');
+ buffer.append(bitrate_string());
+
+ String s = buffer.toString();
+ return s;
+ }
+
+ /**
+ * Read a 32-bit header from the bitstream.
+ */
+ void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException {
+ System.out.print("READ_HEADER_ST");
+ int headerstring;
+ int channel_bitrate;
+ boolean sync = false;
+ do {
+ System.out.println("DO!");
+ headerstring = stream.syncHeader(syncmode);
+ _headerstring = headerstring; // E.B
+ if (syncmode == Bitstream.INITIAL_SYNC) {
+ h_version = ((headerstring >>> 19) & 1);
+ if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection
+ if (h_version == MPEG2_LSF)
+ h_version = MPEG25_LSF;
+ else
+ throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
+ if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) {
+ throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
+ }
+ }
+ h_layer = 4 - (headerstring >>> 17) & 3;
+ h_protection_bit = (headerstring >>> 16) & 1;
+ h_bitrate_index = (headerstring >>> 12) & 0xF;
+ h_padding_bit = (headerstring >>> 9) & 1;
+ h_mode = ((headerstring >>> 6) & 3);
+ h_mode_extension = (headerstring >>> 4) & 3;
+ if (h_mode == JOINT_STEREO)
+ h_intensity_stereo_bound = (h_mode_extension << 2) + 4;
+ else
+ h_intensity_stereo_bound = 0; // should never be used
+ if (((headerstring >>> 3) & 1) == 1)
+ h_copyright = true;
+ if (((headerstring >>> 2) & 1) == 1)
+ h_original = true;
+ // calculate number of subbands:
+ if (h_layer == 1)
+ h_number_of_subbands = 32;
+ else {
+ channel_bitrate = h_bitrate_index;
+ // calculate bitrate per channel:
+ if (h_mode != SINGLE_CHANNEL)
+ if (channel_bitrate == 4)
+ channel_bitrate = 1;
+ else
+ channel_bitrate -= 4;
+ if ((channel_bitrate == 1) || (channel_bitrate == 2))
+ if (h_sample_frequency == THIRTYTWO)
+ h_number_of_subbands = 12;
+ else
+ h_number_of_subbands = 8;
+ else if ((h_sample_frequency == FOURTYEIGHT)
+ || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))
+ h_number_of_subbands = 27;
+ else
+ h_number_of_subbands = 30;
+ }
+ if (h_intensity_stereo_bound > h_number_of_subbands)
+ h_intensity_stereo_bound = h_number_of_subbands;
+ // calculate framesize and nSlots
+ calculate_framesize();
+ // read framedata:
+ int framesizeloaded = stream.read_frame_data(framesize);
+ if ((framesize >= 0) && (framesizeloaded != framesize)) {
+ // Data loaded does not match to expected framesize,
+ // it might be an ID3v1 TAG. (Fix 11/17/04).
+ throw stream.newBitstreamException(Bitstream.INVALIDFRAME);
+ }
+ if (stream.isSyncCurrentPosition(syncmode)) {
+ if (syncmode == Bitstream.INITIAL_SYNC) {
+ syncmode = Bitstream.STRICT_SYNC;
+ stream.set_syncword(headerstring & 0xFFF80CC0);
+ }
+ sync = true;
+ } else {
+ stream.unreadFrame();
+ }
+ System.out.println("do");
+ } while (!sync);
+ stream.parse_frame();
+ if (h_protection_bit == 0) {
+ // frame contains a crc checksum
+ checksum = (short) stream.get_bits(16);
+ if (crc == null)
+ crc = new Crc16();
+ crc.add_bits(headerstring, 16);
+ crcp[0] = crc;
+ } else
+ crcp[0] = null;
+ if (h_sample_frequency == FOURTYFOUR_POINT_ONE) {
+ /*
+ * if (offset == null) { int max = max_number_of_frames(stream); offset =
+ * new int[max]; for(int i=0; i<max; i++) offset[i] = 0; } // E.B :
+ * Investigate more int cf = stream.current_frame(); int lf =
+ * stream.last_frame(); if ((cf > 0) && (cf == lf)) { offset[cf] =
+ * offset[cf-1] + h_padding_bit; } else { offset[0] = h_padding_bit; }
+ */
+ }
+ System.out.print("READ_HEADER_ED");
+ }
+
+ /**
+ * Parse frame to extract optionnal VBR frame.
+ *
+ * @param firstframe
+ * @author E.B (javalayer@javazoom.net)
+ */
+ void parseVBR(byte[] firstframe) throws BitstreamException {
+ // Trying Xing header.
+ String xing = "Xing";
+ byte tmp[] = new byte[4];
+ int offset = 0;
+ // Compute "Xing" offset depending on MPEG version and channels.
+ if (h_version == MPEG1) {
+ if (h_mode == SINGLE_CHANNEL)
+ offset = 21 - 4;
+ else
+ offset = 36 - 4;
+ } else {
+ if (h_mode == SINGLE_CHANNEL)
+ offset = 13 - 4;
+ else
+ offset = 21 - 4;
+ }
+ try {
+ System.arraycopy(firstframe, offset, tmp, 0, 4);
+ // Is "Xing" ?
+ if (xing.equals(new String(tmp))) {
+ // Yes.
+ h_vbr = true;
+ h_vbr_frames = -1;
+ h_vbr_bytes = -1;
+ h_vbr_scale = -1;
+ h_vbr_toc = new byte[100];
+
+ int length = 4;
+ // Read flags.
+ byte flags[] = new byte[4];
+ System.arraycopy(firstframe, offset + length, flags, 0, flags.length);
+ length += flags.length;
+ // Read number of frames (if available).
+ if ((flags[3] & (byte) (1 << 0)) != 0) {
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+ h_vbr_frames =
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)
+ & 0x0000FF00 | tmp[3] & 0x000000FF;
+ length += 4;
+ }
+ // Read size (if available).
+ if ((flags[3] & (byte) (1 << 1)) != 0) {
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+ h_vbr_bytes =
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)
+ & 0x0000FF00 | tmp[3] & 0x000000FF;
+ length += 4;
+ }
+ // Read TOC (if available).
+ if ((flags[3] & (byte) (1 << 2)) != 0) {
+ System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);
+ length += h_vbr_toc.length;
+ }
+ // Read scale (if available).
+ if ((flags[3] & (byte) (1 << 3)) != 0) {
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+ h_vbr_scale =
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)
+ & 0x0000FF00 | tmp[3] & 0x000000FF;
+ length += 4;
+ }
+ // System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames
+ // +" Size:"+h_vbr_bytes);
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new BitstreamException("XingVBRHeader Corrupted", e);
+ }
+
+ // Trying VBRI header.
+ String vbri = "VBRI";
+ offset = 36 - 4;
+ try {
+ System.arraycopy(firstframe, offset, tmp, 0, 4);
+ // Is "VBRI" ?
+ if (vbri.equals(new String(tmp))) {
+ // Yes.
+ h_vbr = true;
+ h_vbr_frames = -1;
+ h_vbr_bytes = -1;
+ h_vbr_scale = -1;
+ h_vbr_toc = new byte[100];
+ // Bytes.
+ int length = 4 + 6;
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+ h_vbr_bytes =
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00
+ | tmp[3] & 0x000000FF;
+ length += 4;
+ // Frames.
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+ h_vbr_frames =
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00
+ | tmp[3] & 0x000000FF;
+ length += 4;
+ // System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames
+ // +" Size:"+h_vbr_bytes);
+ // TOC
+ // TODO
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new BitstreamException("VBRIVBRHeader Corrupted", e);
+ }
+ }
+
+ // Functions to query header contents:
+ /**
+ * Returns version.
+ */
+ @RETURNLOC("OUT")
+ public int version() {
+ return h_version;
+ }
+
+ /**
+ * Returns Layer ID.
+ */
+ @RETURNLOC("OUT")
+ public int layer() {
+ return h_layer;
+ }
+
+ /**
+ * Returns bitrate index.
+ */
+ @RETURNLOC("OUT")
+ public int bitrate_index() {
+ return h_bitrate_index;
+ }
+
+ /**
+ * Returns Sample Frequency.
+ */
+ public int sample_frequency() {
+ return h_sample_frequency;
+ }
+
+ /**
+ * Returns Frequency.
+ */
+ public int frequency() {
+ return frequencies[h_version][h_sample_frequency];
+ }
+
+ /**
+ * Returns Mode.
+ */
+ @RETURNLOC("OUT")
+ public int mode() {
+ return h_mode;
+ }
+
+ /**
+ * Returns Protection bit.
+ */
+ public boolean checksums() {
+ if (h_protection_bit == 0)
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Returns Copyright.
+ */
+ public boolean copyright() {
+ return h_copyright;
+ }
+
+ /**
+ * Returns Original.
+ */
+ public boolean original() {
+ return h_original;
+ }
+
+ /**
+ * Return VBR.
+ *
+ * @return true if VBR header is found
+ */
+ public boolean vbr() {
+ return h_vbr;
+ }
+
+ /**
+ * Return VBR scale.
+ *
+ * @return scale of -1 if not available
+ */
+ public int vbr_scale() {
+ return h_vbr_scale;
+ }
+
+ /**
+ * Return VBR TOC.
+ *
+ * @return vbr toc ot null if not available
+ */
+ public byte[] vbr_toc() {
+ return h_vbr_toc;
+ }
+
+ /**
+ * Returns Checksum flag. Compares computed checksum with stream checksum.
+ */
+ @RETURNLOC("OUT")
+ public boolean checksum_ok() {
+ return (checksum == crc.checksum());
+ }
+
+ // Seeking and layer III stuff
+ /**
+ * Returns Layer III Padding bit.
+ */
+ public boolean padding() {
+ if (h_padding_bit == 0)
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ * Returns Slots.
+ */
+ @RETURNLOC("OUT")
+ public int slots() {
+ return nSlots;
+ }
+
+ /**
+ * Returns Mode Extension.
+ */
+ @RETURNLOC("OUT")
+ public int mode_extension() {
+ return h_mode_extension;
+ }
+
+ // E.B -> private to public
+ @LOC("T")
+ public static final int bitrates[][][] = {
+ {
+ { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,
+ 160000, 176000, 192000, 224000, 256000, 0 },
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+ 96000, 112000, 128000, 144000, 160000, 0 },
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+ 96000, 112000, 128000, 144000, 160000, 0 } },
+
+ {
+ { 0 /* free format */, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000,
+ 288000, 320000, 352000, 384000, 416000, 448000, 0 },
+ { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000,
+ 192000, 224000, 256000, 320000, 384000, 0 },
+ { 0 /* free format */, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000,
+ 160000, 192000, 224000, 256000, 320000, 0 } },
+ // SZD: MPEG2.5
+ {
+ { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,
+ 160000, 176000, 192000, 224000, 256000, 0 },
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+ 96000, 112000, 128000, 144000, 160000, 0 },
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+ 96000, 112000, 128000, 144000, 160000, 0 } },
+
+ };
+
+ // E.B -> private to public
+ /**
+ * Calculate Frame size. Calculates framesize in bytes excluding header size.
+ */
+ public int calculate_framesize() {
+
+ if (h_layer == 1) {
+ framesize =
+ (12 * bitrates[h_version][0][h_bitrate_index])
+ / frequencies[h_version][h_sample_frequency];
+ if (h_padding_bit != 0)
+ framesize++;
+ framesize <<= 2; // one slot is 4 bytes long
+ nSlots = 0;
+ } else {
+ framesize =
+ (144 * bitrates[h_version][h_layer - 1][h_bitrate_index])
+ / frequencies[h_version][h_sample_frequency];
+ if (h_version == MPEG2_LSF || h_version == MPEG25_LSF)
+ framesize >>= 1; // SZD
+ if (h_padding_bit != 0)
+ framesize++;
+ // Layer III slots
+ if (h_layer == 3) {
+ if (h_version == MPEG1) {
+ nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side
+ // info
+ // size
+ - ((h_protection_bit != 0) ? 0 : 2) // CRC size
+ - 4; // header size
+ } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF
+ nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side
+ // info
+ // size
+ - ((h_protection_bit != 0) ? 0 : 2) // CRC size
+ - 4; // header size
+ }
+ } else {
+ nSlots = 0;
+ }
+ }
+ framesize -= 4; // subtract header size
+ return framesize;
+ }
+
+ /**
+ * Returns the maximum number of frames in the stream.
+ *
+ * @param streamsize
+ * @return number of frames
+ */
+ public int max_number_of_frames(int streamsize) // E.B
+ {
+ if (h_vbr == true)
+ return h_vbr_frames;
+ else {
+ if ((framesize + 4 - h_padding_bit) == 0)
+ return 0;
+ else
+ return (streamsize / (framesize + 4 - h_padding_bit));
+ }
+ }
+
+ /**
+ * Returns the maximum number of frames in the stream.
+ *
+ * @param streamsize
+ * @return number of frames
+ */
+ public int min_number_of_frames(int streamsize) // E.B
+ {
+ if (h_vbr == true)
+ return h_vbr_frames;
+ else {
+ if ((framesize + 5 - h_padding_bit) == 0)
+ return 0;
+ else
+ return (streamsize / (framesize + 5 - h_padding_bit));
+ }
+ }
+
+ /**
+ * Returns ms/frame.
+ *
+ * @return milliseconds per frame
+ */
+ public float ms_per_frame() // E.B
+ {
+ if (h_vbr == true) {
+ double tpf = h_vbr_time_per_frame[layer()] / frequency();
+ if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF))
+ tpf /= 2;
+ return ((float) (tpf * 1000));
+ } else {
+ float ms_per_frame_array[][] =
+ { { 8.707483f, 8.0f, 12.0f }, { 26.12245f, 24.0f, 36.0f }, { 26.12245f, 24.0f, 36.0f } };
+ return (ms_per_frame_array[h_layer - 1][h_sample_frequency]);
+ }
+ }
+
+ /**
+ * Returns total ms.
+ *
+ * @param streamsize
+ * @return total milliseconds
+ */
+ public float total_ms(int streamsize) // E.B
+ {
+ return (max_number_of_frames(streamsize) * ms_per_frame());
+ }
+
+ /**
+ * Returns synchronized header.
+ */
+ public int getSyncHeader() // E.B
+ {
+ return _headerstring;
+ }
+
+ // functions which return header informations as strings:
+ /**
+ * Return Layer version.
+ */
+ public String layer_string() {
+ switch (h_layer) {
+ case 1:
+ return "I";
+ case 2:
+ return "II";
+ case 3:
+ return "III";
+ }
+ return null;
+ }
+
+ // E.B -> private to public
+ @LOC("T")
+ public static final String bitrate_str[][][] = {
+ {
+ { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
+ "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",
+ "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } },
+
+ {
+ { "free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", "160 kbit/s",
+ "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", "320 kbit/s", "352 kbit/s",
+ "384 kbit/s", "416 kbit/s", "448 kbit/s", "forbidden" },
+ { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
+ "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s",
+ "256 kbit/s", "320 kbit/s", "384 kbit/s", "forbidden" },
+ { "free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
+ "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s",
+ "224 kbit/s", "256 kbit/s", "320 kbit/s", "forbidden" } },
+ // SZD: MPEG2.5
+ {
+ { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
+ "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",
+ "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } }, };
+
+ /**
+ * Return Bitrate.
+ *
+ * @return bitrate in bps
+ */
+ public String bitrate_string() {
+ if (h_vbr == true) {
+ return Integer.toString(bitrate() / 1000) + " kb/s";
+ } else
+ return bitrate_str[h_version][h_layer - 1][h_bitrate_index];
+ }
+
+ /**
+ * Return Bitrate.
+ *
+ * @return bitrate in bps and average bitrate for VBR header
+ */
+ public int bitrate() {
+ if (h_vbr == true) {
+ return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames))) * 1000;
+ } else
+ return bitrates[h_version][h_layer - 1][h_bitrate_index];
+ }
+
+ /**
+ * Return Instant Bitrate. Bitrate for VBR is not constant.
+ *
+ * @return bitrate in bps
+ */
+ public int bitrate_instant() {
+ return bitrates[h_version][h_layer - 1][h_bitrate_index];
+ }
+
+ /**
+ * Returns Frequency
+ *
+ * @return frequency string in kHz
+ */
+ public String sample_frequency_string() {
+ switch (h_sample_frequency) {
+ case THIRTYTWO:
+ if (h_version == MPEG1)
+ return "32 kHz";
+ else if (h_version == MPEG2_LSF)
+ return "16 kHz";
+ else
+ // SZD
+ return "8 kHz";
+ case FOURTYFOUR_POINT_ONE:
+ if (h_version == MPEG1)
+ return "44.1 kHz";
+ else if (h_version == MPEG2_LSF)
+ return "22.05 kHz";
+ else
+ // SZD
+ return "11.025 kHz";
+ case FOURTYEIGHT:
+ if (h_version == MPEG1)
+ return "48 kHz";
+ else if (h_version == MPEG2_LSF)
+ return "24 kHz";
+ else
+ // SZD
+ return "12 kHz";
+ }
+ return (null);
+ }
+
+ /**
+ * Returns Mode.
+ */
+ public String mode_string() {
+ switch (h_mode) {
+ case STEREO:
+ return "Stereo";
+ case JOINT_STEREO:
+ return "Joint stereo";
+ case DUAL_CHANNEL:
+ return "Dual channel";
+ case SINGLE_CHANNEL:
+ return "Single channel";
+ }
+ return null;
+ }
+
+ /**
+ * Returns Version.
+ *
+ * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF
+ */
+ public String version_string() {
+ switch (h_version) {
+ case MPEG1:
+ return "MPEG-1";
+ case MPEG2_LSF:
+ return "MPEG-2 LSF";
+ case MPEG25_LSF: // SZD
+ return "MPEG-2.5 LSF";
+ }
+ return (null);
+ }
+
+ /**
+ * Returns the number of subbands in the current frame.
+ *
+ * @return number of subbands
+ */
+ @RETURNLOC("OUT")
+ public int number_of_subbands() {
+ return h_number_of_subbands;
+ }
+
+ /**
+ * Returns Intensity Stereo. (Layer II joint stereo only). Returns the number
+ * of subbands which are in stereo mode, subbands above that limit are in
+ * intensity stereo mode.
+ *
+ * @return intensity
+ */
+ @RETURNLOC("OUT")
+ public int intensity_stereo_bound() {
+ return h_intensity_stereo_bound;
+ }
+
+ public void setSideInfoBuf(SideInfoBuffer sib) {
+ this.sib = sib;
+ }
+
+ public void setBitReserve(BitReserve br) {
+ this.br = br;
+ }
+
+ public SideInfoBuffer getSideInfoBuffer() {
+ return sib;
+ }
+
+ public BitReserve getBitReserve() {
+ return br;
+ }
+
+}
@LOC("SBI")
private int sfreq;
+ private int part2_start;
+
+
/**
* Constructor.
*/
get_LSF_scale_factors(ch, gr); // no need to care from this side
// here, decoding the compressed audio data
- huffman_decode(part2_start, ch, gr); // no need to care from this side
+ huffman_decode(ch, gr); // no need to care from this side
// System.out.println("CheckSum HuffMan = " + CheckSumHuff);
dequantize_sample(/* ro[ch], */ch, gr); // no need to care from this
// side
// @LOC("SI1")
// int[] w = { 0 };
@LOC("SI1")
- int x = 0;
+ int x[] = { 0 };
@LOC("SI1")
- int y = 0;
+ int y[] = { 0 };
@LOC("SI1")
- int v = 0;
+ int v[] = { 0 };
@LOC("SI1")
- int w = 0;
-
- // @LATTICE("H<I,I<R,R<B1,B1<B,B<THIS,THIS<IN,I*,THISLOC=THIS,GLOBALLOC=IN")
- @LATTICE("BUF<THIS,BUF*,R,B,B1,H,I,THIS<IN,I*,THISLOC=THIS,GLOBALLOC=THIS")
- private void huffman_decode(@LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int part2_start,
- @LOC("THIS,LayerIIIDecoder.CH0") int ch, @LOC("THIS,LayerIIIDecoder.CH0") int gr) {
+ int w[] = { 0 };
- // @LOC("THIS,LayerIIIDecoder.IS1D") int x;
- // @LOC("THIS,LayerIIIDecoder.IS1D") int y;
- // @LOC("THIS,LayerIIIDecoder.IS1D") int v;
- // @LOC("THIS,LayerIIIDecoder.IS1D") int w;
+ private void huffman_decode(int ch, int gr) {
+ x[0] = 0;
+ y[0] = 0;
+ v[0] = 0;
+ w[0] = 0;
- x = 0;
- y = 0;
- v = 0;
- w = 0;
+ int part2_3_end = part2_start + si.ch[ch].gr[gr].part2_3_length;
+ int num_bits;
+ int region1Start;
+ int region2Start;
+ int index;
- @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int part2_3_end =
- part2_start + si.ch[ch].gr[gr].part2_3_length;
+ int buf, buf1;
- @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int num_bits;
- @LOC("THIS,LayerIIIDecoder.SI1") int region1Start;
- @LOC("THIS,LayerIIIDecoder.SI1") int region2Start;
- @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int index;
-
- @LOC("THIS,LayerIIIDecoder.SI1") int buf;
- @LOC("THIS,LayerIIIDecoder.SI1") int buf1;
+ huffcodetab h;
// Find region boundary for short block case
// Region2.
// MS: Extrahandling for 8KHZ
- region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case 8KHZ =
- // 72
+ region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case
+ // 8KHZ = 72
region2Start = 576; // No Region2 for short block case
} else { // Find region boundary for long block case
buf = si.ch[ch].gr[gr].region0_count + 1;
buf1 = buf + si.ch[ch].gr[gr].region1_count + 1;
- if (buf1 > sfBandIndex[sfreq].l.length - 1) {
+ if (buf1 > sfBandIndex[sfreq].l.length - 1)
buf1 = sfBandIndex[sfreq].l.length - 1;
- }
region1Start = sfBandIndex[sfreq].l[buf];
region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */
}
index = 0;
- @LOC("THIS,LayerIIIDecoder.SI1") int h;
// Read bigvalues area
- for (@LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int i = 0; i < (si.ch[ch].gr[gr].big_values << 1); i +=
- 2) {
- if (i < region1Start) {
- // huffcodetab.huffman_decoder(h, x, y, v, w, br);
- h = si.ch[ch].gr[gr].table_select[0];
- } else if (i < region2Start) {
- h = si.ch[ch].gr[gr].table_select[1];
- // h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[1]];
- } else {
- h = si.ch[ch].gr[gr].table_select[2];
- // h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[2]];
- }
-
- // @LOC("THIS,LayerIIIDecoder.SI2") HuffData huffData =
- // huffcodetab.huffman_decoder(h, new HuffData(x, y, v, w, br));
- // x = huffData.x;
- // y = huffData.y;
- // v = huffData.v;
- // w = huffData.w;
- // br = huffData.br;
- huffcodetab_huffman_decoder(h);
+ for (int i = 0; i < (si.ch[ch].gr[gr].big_values << 1); i += 2) {
+ if (i < region1Start)
+ h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[0]];
+ else if (i < region2Start)
+ h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[1]];
+ else
+ h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[2]];
+ huffcodetab.huffman_decoder(h, x, y, v, w, br);
// if (index >= is_1d.length)
// System.out.println("i0="+i+"/"+(si.ch[ch].gr[gr].big_values<<1)+" Index="+index+" is_1d="+is_1d.length);
- is_1d[index++] = x;
- is_1d[index++] = y;
+ is_1d[index++] = x[0];
+ is_1d[index++] = y[0];
- CheckSumHuff = CheckSumHuff + x + y;
+ CheckSumHuff = CheckSumHuff + x[0] + y[0];
// System.out.println("x = "+x[0]+" y = "+y[0]);
}
// Read count1 area
- // h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select + 32];
+ h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select + 32];
num_bits = br.hsstell();
while ((num_bits < part2_3_end) && (index < 576)) {
- // huffcodetab.huffman_decoder(h, x, y, v, w, br);
- // @LOC("I") HuffData huffData2 =
- // huffcodetab.huffman_decoder(si.ch[ch].gr[gr].count1table_select + 32,
- // new HuffData(x, y,
- // v, w, br));
- // x = huffData2.x;
- // y = huffData2.y;
- // v = huffData2.v;
- // w = huffData2.w;
- // br = huffData2.br;
- huffcodetab_huffman_decoder(h);
-
- is_1d[index++] = v;
- is_1d[index++] = w;
- is_1d[index++] = x;
- is_1d[index++] = y;
- CheckSumHuff = CheckSumHuff + v + w + x + y;
+ huffcodetab.huffman_decoder(h, x, y, v, w, br);
+
+ is_1d[index++] = v[0];
+ is_1d[index++] = w[0];
+ is_1d[index++] = x[0];
+ is_1d[index++] = y[0];
+ CheckSumHuff = CheckSumHuff + v[0] + w[0] + x[0] + y[0];
// System.out.println("v = "+v[0]+" w = "+w[0]);
// System.out.println("x = "+x[0]+" y = "+y[0]);
num_bits = br.hsstell();
if (args.length == 1) {
filename = args[0];
}
+ play();
}
/**
player.play();
} catch (IOException ex) {
throw new JavaLayerException("Problem playing file " + filename, ex);
- } catch (Exception ex) {
- throw new JavaLayerException("Problem playing file " + filename, ex);
- }
+ }
}
}
\ No newline at end of file
+\r
/*\r
* 11/19/04 1.0 moved to LGPL.\r
* 29/01/00 Initial version. mdm@techie.com\r
*/\r
\r
\r
-//import java.io.InputStream;\r
-\r
\r
/**\r
* The <code>Player</code> class implements a simple player for playback\r
public boolean play(@LOC("IN") int frames) throws JavaLayerException\r
{\r
@LOC("IN") boolean ret = true;\r
- \r
- SSJAVA:\r
+ \r
+ \r
+ SSJAVA:\r
while (frames-- > 0 && ret)\r
{\r
- ret = decodeFrame();\r
+ System.out.println("DECODE");\r
+ ret = decodeFrame();\r
}\r
/*\r
if (!ret)\r
\r
// sample buffer set when decoder constructed\r
@LOC("O") SampleBuffer output = (SampleBuffer)decoder.decodeFrame(h, bitstream);\r
- \r
+ \r
+ // eom debug\r
+ short[] outbuf = output.getBuffer();\r
+ for (int i = 0; i < outbuf.length; i++) {\r
+// bw.write(outbuf[i]);\r
+ System.out.println(outbuf[i]);\r
+ }\r
+ //\r
+ \r
//synchronized (this)\r
//{\r
// out = audio;\r
VAL = null;\r
treelen = TREELEN;\r
}\r
+ \r
+ /**\r
+ * Do the huffman-decoding.\r
+ * note! for counta,countb -the 4 bit value is returned in y,\r
+ * discard x.\r
+ */\r
+ public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br)\r
+ {\r
+ // array of all huffcodtable headers\r
+ // 0..31 Huffman code table 0..31\r
+ // 32,33 count1-tables\r
+\r
+ int dmask = 1 << ((4 * 8) - 1);\r
+ int hs = 4 * 8;\r
+ int level;\r
+ int point = 0;\r
+ int error = 1;\r
+ level = dmask;\r
+\r
+ if (h.val == null) return 2;\r
+\r
+ /* table 0 needs no bits */\r
+ if ( h.treelen == 0)\r
+ { \r
+ x[0] = y[0] = 0;\r
+ return 0;\r
+ }\r
+\r
+ /* Lookup in Huffman table. */\r
+\r
+ /*int bitsAvailable = 0; \r
+ int bitIndex = 0;\r
+ \r
+ int bits[] = bitbuf;*/\r
+ do \r
+ {\r
+ if (h.val[point][0]==0)\r
+ { /*end of tree*/\r
+ x[0] = h.val[point][1] >>> 4;\r
+ y[0] = h.val[point][1] & 0xf;\r
+ error = 0;\r
+ break;\r
+ }\r
+ \r
+ // hget1bit() is called thousands of times, and so needs to be\r
+ // ultra fast. \r
+ /*\r
+ if (bitIndex==bitsAvailable)\r
+ {\r
+ bitsAvailable = br.readBits(bits, 32); \r
+ bitIndex = 0;\r
+ }\r
+ */\r
+ //if (bits[bitIndex++]!=0)\r
+ if (br.hget1bit()!=0)\r
+ {\r
+ while (h.val[point][1] >= MXOFF) point += h.val[point][1];\r
+ point += h.val[point][1];\r
+ }\r
+ else\r
+ {\r
+ while (h.val[point][0] >= MXOFF) point += h.val[point][0];\r
+ point += h.val[point][0];\r
+ }\r
+ level >>>= 1;\r
+ // MDM: ht[0] is always 0;\r
+ } while ((level !=0 ) || (point < 0 /*ht[0].treelen*/) );\r
+ \r
+ // put back any bits not consumed\r
+ /* \r
+ int unread = (bitsAvailable-bitIndex);\r
+ if (unread>0)\r
+ br.rewindNbits(unread);\r
+ */\r
+ /* Process sign encodings for quadruples tables. */\r
+ // System.out.println(h.tablename);\r
+ if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3'))\r
+ {\r
+ v[0] = (y[0]>>3) & 1;\r
+ w[0] = (y[0]>>2) & 1;\r
+ x[0] = (y[0]>>1) & 1;\r
+ y[0] = y[0] & 1;\r
+\r
+ /* v, w, x and y are reversed in the bitstream.\r
+ switch them around to make test bistream work. */\r
+\r
+ if (v[0]!=0)\r
+ if (br.hget1bit() != 0) v[0] = -v[0];\r
+ if (w[0]!=0)\r
+ if (br.hget1bit() != 0) w[0] = -w[0];\r
+ if (x[0]!=0)\r
+ if (br.hget1bit() != 0) x[0] = -x[0];\r
+ if (y[0]!=0)\r
+ if (br.hget1bit() != 0) y[0] = -y[0];\r
+ }\r
+ else\r
+ {\r
+ // Process sign and escape encodings for dual tables.\r
+ // x and y are reversed in the test bitstream.\r
+ // Reverse x and y here to make test bitstream work.\r
+\r
+ if (h.linbits != 0)\r
+ if ((h.xlen-1) == x[0])\r
+ x[0] += br.hgetbits(h.linbits);\r
+ if (x[0] != 0)\r
+ if (br.hget1bit() != 0) x[0] = -x[0];\r
+ if (h.linbits != 0)\r
+ if ((h.ylen-1) == y[0])\r
+ y[0] += br.hgetbits(h.linbits);\r
+ if (y[0] != 0)\r
+ if (br.hget1bit() != 0) y[0] = -y[0];\r
+ }\r
+ return error;\r
+ }\r
+ \r
\r
/**\r
* Do the huffman-decoding. note! for counta,countb -the 4 bit value is\r
return data;\r
// return error;\r
}\r
-\r
+ \r
public static void inithuff() {\r
\r
if (ht != null)\r