From 9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e Mon Sep 17 00:00:00 2001 From: Michiel Van Der Kolk Date: Mon, 11 Jul 2005 15:42:37 +0000 Subject: Songdb java version, source. only 1.5 compatible git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7101 a1c6a512-1295-4272-9138-f99709370657 --- songdbj/de/jarnbjo/ogg/OggPage.java | 431 ++++++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 songdbj/de/jarnbjo/ogg/OggPage.java (limited to 'songdbj/de/jarnbjo/ogg/OggPage.java') diff --git a/songdbj/de/jarnbjo/ogg/OggPage.java b/songdbj/de/jarnbjo/ogg/OggPage.java new file mode 100644 index 0000000000..cc965cc7a9 --- /dev/null +++ b/songdbj/de/jarnbjo/ogg/OggPage.java @@ -0,0 +1,431 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id$ + * ----------------------------------------------------------- + * + * $Author$ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log$ + * Revision 1.1 2005/07/11 15:42:36 hcl + * Songdb java version, source. only 1.5 compatible + * + * Revision 1.1.1.1 2004/04/04 22:09:12 shred + * First Import + * + * Revision 1.3 2003/04/10 19:48:22 jarnbjo + * no message + * + * Revision 1.2 2003/03/31 00:23:04 jarnbjo + * no message + * + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; + +import de.jarnbjo.util.io.*; + +/** + *

An instance of this class represents an ogg page read from an ogg file + * or network stream. It has no public constructor, but instances can be + * created by the create methods, supplying a JMF stream or + * a RandomAccessFile + * which is positioned at the beginning of an Ogg page.

+ * + *

Furtheron, the class provides methods for accessing the raw page data, + * as well as data attributes like segmenting information, sequence number, + * stream serial number, chechsum and wether this page is the beginning or + * end of a logical bitstream (BOS, EOS) and if the page data starts with a + * continued packet or a fresh data packet.

+ */ + +public class OggPage { + + private int version; + private boolean continued, bos, eos; + private long absoluteGranulePosition; + private int streamSerialNumber, pageSequenceNumber, pageCheckSum; + private int[] segmentOffsets; + private int[] segmentLengths; + private int totalLength; + private byte[] header, segmentTable, data; + + protected OggPage() { + } + + private OggPage( + int version, + boolean continued, + boolean bos, + boolean eos, + long absoluteGranulePosition, + int streamSerialNumber, + int pageSequenceNumber, + int pageCheckSum, + int[] segmentOffsets, + int[] segmentLengths, + int totalLength, + byte[] header, + byte[] segmentTable, + byte[] data) { + + this.version=version; + this.continued=continued; + this.bos=bos; + this.eos=eos; + this.absoluteGranulePosition=absoluteGranulePosition; + this.streamSerialNumber=streamSerialNumber; + this.pageSequenceNumber=pageSequenceNumber; + this.pageCheckSum=pageCheckSum; + this.segmentOffsets=segmentOffsets; + this.segmentLengths=segmentLengths; + this.totalLength=totalLength; + this.header=header; + this.segmentTable=segmentTable; + this.data=data; + } + + /** + * this method equals to create(RandomAccessFile source, false) + * + * @see #create(RandomAccessFile, boolean) + */ + + public static OggPage create(RandomAccessFile source) throws IOException, EndOfOggStreamException, OggFormatException { + return create(source, false); + } + + /** + * This method is called to read data from the current position in the + * specified RandomAccessFile and create a new OggPage instance based on the data + * read. If the parameter skipData is set to true, + * the actual page segments (page data) is skipped and not read into + * memory. This mode is useful when scanning through an ogg file to build + * a seek table. + * + * @param source the source from which the ogg page is generated + * @param skipData if set to true, the actual page data is not read into memory + * @return an ogg page created by reading data from the specified source, starting at the current position + * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page + * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source + * @throws IOException if some other I/O error is detected when reading from the source + * + * @see #create(RandomAccessFile) + */ + + public static OggPage create(RandomAccessFile source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + return create((Object)source, skipData); + } + + /** + * this method equals to create(InputStream source, false) + * + * @see #create(InputStream, boolean) + */ + + public static OggPage create(InputStream source) throws IOException, EndOfOggStreamException, OggFormatException { + return create(source, false); + } + + /** + * This method is called to read data from the current position in the + * specified InpuStream and create a new OggPage instance based on the data + * read. If the parameter skipData is set to true, + * the actual page segments (page data) is skipped and not read into + * memory. This mode is useful when scanning through an ogg file to build + * a seek table. + * + * @param source the source from which the ogg page is generated + * @param skipData if set to true, the actual page data is not read into memory + * @return an ogg page created by reading data from the specified source, starting at the current position + * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page + * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source + * @throws IOException if some other I/O error is detected when reading from the source + * + * @see #create(InputStream) + */ + + public static OggPage create(InputStream source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + return create((Object)source, skipData); + } + + /** + * this method equals to create(byte[] source, false) + * + * @see #create(byte[], boolean) + */ + + public static OggPage create(byte[] source) throws IOException, EndOfOggStreamException, OggFormatException { + return create(source, false); + } + + /** + * This method is called to + * create a new OggPage instance based on the specified byte array. + * + * @param source the source from which the ogg page is generated + * @param skipData if set to true, the actual page data is not read into memory + * @return an ogg page created by reading data from the specified source, starting at the current position + * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page + * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source + * @throws IOException if some other I/O error is detected when reading from the source + * + * @see #create(byte[]) + */ + + public static OggPage create(byte[] source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + return create((Object)source, skipData); + } + + private static OggPage create(Object source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + + try { + int sourceOffset=27; + + byte[] header=new byte[27]; + if(source instanceof RandomAccessFile) { + RandomAccessFile raf=(RandomAccessFile)source; + if(raf.getFilePointer()==raf.length()) { + return null; + } + raf.readFully(header); + } + else if(source instanceof InputStream) { + readFully((InputStream)source, header); + } + else if(source instanceof byte[]) { + System.arraycopy((byte[])source, 0, header, 0, 27); + } + + BitInputStream bdSource=new ByteArrayBitInputStream(header); + + int capture=bdSource.getInt(32); + + if(capture!=0x5367674f) { + //throw new FormatException("Ogg page does not start with 'OggS' (0x4f676753)"); + + /* + ** This condition is IMHO an error, but older Ogg files often contain + ** pages with a different capture than OggS. I am not sure how to + ** manage these pages, but the decoder seems to work properly, if + ** the incorrect capture is simply ignored. + */ + + String cs=Integer.toHexString(capture); + while(cs.length()<8) { + cs="0"+cs; + } + cs=cs.substring(6, 8)+cs.substring(4, 6)+cs.substring(2, 4)+cs.substring(0, 2); + char c1=(char)(Integer.valueOf(cs.substring(0, 2), 16).intValue()); + char c2=(char)(Integer.valueOf(cs.substring(2, 4), 16).intValue()); + char c3=(char)(Integer.valueOf(cs.substring(4, 6), 16).intValue()); + char c4=(char)(Integer.valueOf(cs.substring(6, 8), 16).intValue()); + System.out.println("Ogg packet header is 0x"+cs+" ("+c1+c2+c3+c4+"), should be 0x4f676753 (OggS)"); + } + + int version=bdSource.getInt(8); + byte tmp=(byte)bdSource.getInt(8); + boolean bf1=(tmp&1)!=0; + boolean bos=(tmp&2)!=0; + boolean eos=(tmp&4)!=0; + long absoluteGranulePosition=bdSource.getLong(64); + int streamSerialNumber=bdSource.getInt(32); + int pageSequenceNumber=bdSource.getInt(32); + int pageCheckSum=bdSource.getInt(32); + int pageSegments=bdSource.getInt(8); + + //System.out.println("OggPage: "+streamSerialNumber+" / "+absoluteGranulePosition+" / "+pageSequenceNumber); + + int[] segmentOffsets=new int[pageSegments]; + int[] segmentLengths=new int[pageSegments]; + int totalLength=0; + + byte[] segmentTable=new byte[pageSegments]; + byte[] tmpBuf=new byte[1]; + + for(int i=0; itrue if this page begins with a continued packet + */ + + public boolean isContinued() { + return continued; + } + + /** + * @return true if this page begins with a fresh packet + */ + + public boolean isFresh() { + return !continued; + } + + /** + * @return true if this page is the beginning of a logical stream + */ + + public boolean isBos() { + return bos; + } + + /** + * @return true if this page is the end of a logical stream + */ + + public boolean isEos() { + return eos; + } + +} \ No newline at end of file -- cgit v1.2.3