From 2e81b2a94da8ddf8aa31e6ed8109f3e78f6f7728 Mon Sep 17 00:00:00 2001 From: david Date: Wed, 13 Jul 2011 18:54:28 +0000 Subject: [PATCH] updated annotation --- .../Tests/ssJava/mp3decoder/Bitstream.java | 1304 +++++++++-------- 1 file changed, 657 insertions(+), 647 deletions(-) diff --git a/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java b/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java index 26923935..a9750458 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java +++ b/Robust/src/Tests/ssJava/mp3decoder/Bitstream.java @@ -1,647 +1,657 @@ -/* - * 11/19/04 1.0 moved to LGPL. - * - * 11/17/04 Uncomplete frames discarded. 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 - * - * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net - * - * 04/14/97 : Added function prototypes for new syncing and seeking - * mechanisms. Also made this file portable. Changes made by Jeff Tsay - * - * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34 - * @(#) 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. - *---------------------------------------------------------------------- - */ - - -/** - * The Bistream class is responsible for parsing - * an MPEG audio bitstream. - * - * REVIEW: much of the parsing currently occurs in the - * various decoders. This should be moved into this class and associated - * inner classes. - */ -public final class Bitstream implements BitstreamErrors -{ - /** - * Synchronization control constant for the initial - * synchronization to the start of a frame. - */ - static final byte INITIAL_SYNC = 0; - - /** - * Synchronization control constant for non-initial frame - * synchronizations. - */ - static final byte STRICT_SYNC = 1; - - // max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC - /** - * Maximum size of the frame buffer. - */ - private static final int BUFFER_INT_SIZE = 433; - - /** - * The frame buffer that holds the data for the current frame. - */ - private final int[] framebuffer = new int[BUFFER_INT_SIZE]; - - /** - * Number of valid bytes in the frame buffer. - */ - private int framesize; - - /** - * The bytes read from the stream. - */ - private byte[] frame_bytes = new byte[BUFFER_INT_SIZE*4]; - - /** - * Index into framebuffer where the next bits are - * retrieved. - */ - private int wordpointer; - - /** - * Number (0-31, from MSB to LSB) of next bit for get_bits() - */ - private int bitindex; - - /** - * The current specified syncword - */ - private int syncword; - - /** - * Audio header position in stream. - */ - private int header_pos = 0; - - /** - * - */ - private boolean single_ch_mode; - //private int current_frame_number; - //private int last_frame_number; - - private final int bitmask[] = {0, // dummy - 0x00000001, 0x00000003, 0x00000007, 0x0000000F, - 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, - 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, - 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, - 0x0001FFFF }; - - private final PushbackInputStream source; - - private final Header header = new Header(); - - private final byte syncbuf[] = new byte[4]; - - private Crc16[] crc = new Crc16[1]; - - private byte[] rawid3v2 = null; - - private boolean firstframe = true; - - - /** - * Construct a IBitstream that reads data from a - * given InputStream. - * - * @param in The InputStream to read from. - */ - public Bitstream(InputStream in) - { - if (in==null) throw new NullPointerException("in"); - in = new BufferedInputStream(in); - loadID3v2(in); - firstframe = true; - //source = new PushbackInputStream(in, 1024); - source = new PushbackInputStream(in, BUFFER_INT_SIZE*4); - - closeFrame(); - //current_frame_number = -1; - //last_frame_number = -1; - } - - /** - * Return position of the first audio header. - * @return size of ID3v2 tag frames. - */ - public int header_pos() - { - return header_pos; - } - - /** - * Load ID3v2 frames. - * @param in MP3 InputStream. - * @author JavaZOOM - */ - private void loadID3v2(InputStream in) - { - int size = -1; - try - { - // Read ID3v2 header (10 bytes). - in.mark(10); - size = readID3v2Header(in); - header_pos = size; - } - catch (IOException e) - {} - finally - { - try - { - // Unread ID3v2 header (10 bytes). - in.reset(); - } - catch (IOException e) - {} - } - // Load ID3v2 tags. - try - { - if (size > 0) - { - rawid3v2 = new byte[size]; - in.read(rawid3v2,0,rawid3v2.length); - } - } - catch (IOException e) - {} - } - - /** - * Parse ID3v2 tag header to find out size of ID3v2 frames. - * @param in MP3 InputStream - * @return size of ID3v2 frames + header - * @throws IOException - * @author JavaZOOM - */ - private int readID3v2Header(InputStream in) throws IOException - { - byte[] id3header = new byte[4]; - int size = -10; - in.read(id3header,0,3); - // Look for ID3v2 - if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3')) - { - in.read(id3header,0,3); - int majorVersion = id3header[0]; - int revision = id3header[1]; - in.read(id3header,0,4); - size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]); - } - return (size+10); - } - - /** - * Return raw ID3v2 frames + header. - * @return ID3v2 InputStream or null if ID3v2 frames are not available. - */ - public InputStream getRawID3v2() - { - if (rawid3v2 == null) return null; - else - { - ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2); - return bain; - } - } - - /** - * Close the Bitstream. - * @throws BitstreamException - */ - public void close() throws BitstreamException - { - try - { - source.close(); - } - catch (IOException ex) - { - throw newBitstreamException(STREAM_ERROR, ex); - } - } - - /** - * Reads and parses the next frame from the input source. - * @return the Header describing details of the frame read, - * or null if the end of the stream has been reached. - */ - public Header readFrame() throws BitstreamException - { - Header result = null; - try - { - result = readNextFrame(); - // E.B, Parse VBR (if any) first frame. - if (firstframe == true) - { - result.parseVBR(frame_bytes); - firstframe = false; - } - } - catch (BitstreamException ex) - { - if ((ex.getErrorCode()==INVALIDFRAME)) - { - // Try to skip this frame. - //System.out.println("INVALIDFRAME"); - try - { - closeFrame(); - result = readNextFrame(); - } - catch (BitstreamException e) - { - if ((e.getErrorCode()!=STREAM_EOF)) - { - // wrap original exception so stack trace is maintained. - throw newBitstreamException(e.getErrorCode(), e); - } - } - } - else if ((ex.getErrorCode()!=STREAM_EOF)) - { - // wrap original exception so stack trace is maintained. - throw newBitstreamException(ex.getErrorCode(), ex); - } - } - return result; - } - - /** - * Read next MP3 frame. - * @return MP3 frame header. - * @throws BitstreamException - */ - private Header readNextFrame() throws BitstreamException - { - if (framesize == -1) - { - nextFrame(); - } - return header; - } - - - /** - * Read next MP3 frame. - * @throws BitstreamException - */ - private void nextFrame() throws BitstreamException - { - // entire frame is read by the header class. - header.read_header(this, crc); - } - - /** - * Unreads the bytes read from the frame. - * @throws BitstreamException - */ - // REVIEW: add new error codes for this. - public void unreadFrame() throws BitstreamException - { - if (wordpointer==-1 && bitindex==-1 && (framesize>0)) - { - try - { - source.unread(frame_bytes, 0, framesize); - } - catch (IOException ex) - { - throw newBitstreamException(STREAM_ERROR); - } - } - } - - /** - * Close MP3 frame. - */ - public void closeFrame() - { - framesize = -1; - wordpointer = -1; - bitindex = -1; - } - - /** - * Determines if the next 4 bytes of the stream represent a - * frame header. - */ - public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException - { - int read = readBytes(syncbuf, 0, 4); - int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF); - - try - { - source.unread(syncbuf, 0, read); - } - catch (IOException ex) - { - } - - boolean sync = false; - switch (read) - { - case 0: - sync = true; - break; - case 4: - sync = isSyncMark(headerstring, syncmode, syncword); - break; - } - - return sync; - } - - - // REVIEW: this class should provide inner classes to - // parse the frame contents. Eventually, readBits will - // be removed. - public int readBits(int n) - { - return get_bits(n); - } - - public int readCheckedBits(int n) - { - // REVIEW: implement CRC check. - return get_bits(n); - } - - protected BitstreamException newBitstreamException(int errorcode) - { - return new BitstreamException(errorcode, null); - } - protected BitstreamException newBitstreamException(int errorcode, Throwable throwable) - { - return new BitstreamException(errorcode, throwable); - } - - /** - * Get next 32 bits from bitstream. - * They are stored in the headerstring. - * syncmod allows Synchro flag ID - * The returned value is False at the end of stream. - */ - - int syncHeader(byte syncmode) throws BitstreamException - { - boolean sync; - int headerstring; - // read additional 2 bytes - int bytesRead = readBytes(syncbuf, 0, 3); - - if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null); - - headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF); - - do - { - headerstring <<= 8; - - if (readBytes(syncbuf, 3, 1)!=1) - throw newBitstreamException(STREAM_EOF, null); - - headerstring |= (syncbuf[3] & 0x000000FF); - - sync = isSyncMark(headerstring, syncmode, syncword); - } - while (!sync); - - //current_frame_number++; - //if (last_frame_number < current_frame_number) last_frame_number = current_frame_number; - - return headerstring; - } - - public boolean isSyncMark(int headerstring, int syncmode, int word) - { - boolean sync = false; - - if (syncmode == INITIAL_SYNC) - { - //sync = ((headerstring & 0xFFF00000) == 0xFFF00000); - sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5 - } - else - { - sync = ((headerstring & 0xFFF80C00) == word) && - (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode); - } - - // filter out invalid sample rate - if (sync) - sync = (((headerstring >>> 10) & 3)!=3); - // filter out invalid layer - if (sync) - sync = (((headerstring >>> 17) & 3)!=0); - // filter out invalid version - if (sync) - sync = (((headerstring >>> 19) & 3)!=1); - - return sync; - } - - /** - * Reads the data for the next frame. The frame is not parsed - * until parse frame is called. - */ - int read_frame_data(int bytesize) throws BitstreamException - { - int numread = 0; - numread = readFully(frame_bytes, 0, bytesize); - framesize = bytesize; - wordpointer = -1; - bitindex = -1; - return numread; - } - - /** - * Parses the data previously read with read_frame_data(). - */ - void parse_frame() throws BitstreamException - { - // Convert Bytes read to int - int b=0; - byte[] byteread = frame_bytes; - int bytesize = framesize; - - // Check ID3v1 TAG (True only if last frame). - //for (int t=0;t<(byteread.length)-2;t++) - //{ - // if ((byteread[t]=='T') && (byteread[t+1]=='A') && (byteread[t+2]=='G')) - // { - // System.out.println("ID3v1 detected at offset "+t); - // throw newBitstreamException(INVALIDFRAME, null); - // } - //} - - for (int k=0;k>> (32 - sum)) & bitmask[number_of_bits]; - // returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits]; - if ((bitindex += number_of_bits) == 32) - { - bitindex = 0; - wordpointer++; // added by me! - } - return returnvalue; - } - - // E.B : Check that ? - //((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0]; - //wordpointer++; // Added by me! - //((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0]; - int Right = (framebuffer[wordpointer] & 0x0000FFFF); - wordpointer++; - int Left = (framebuffer[wordpointer] & 0xFFFF0000); - returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF); - - returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 - bitindex)) - returnvalue &= bitmask[number_of_bits]; - bitindex = sum - 32; - return returnvalue; -} - - /** - * Set the word we want to sync the header to. - * In Big-Endian byte order - */ - void set_syncword(int syncword0) - { - syncword = syncword0 & 0xFFFFFF3F; - single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0); - } - /** - * Reads the exact number of bytes from the source - * input stream into a byte array. - * - * @param b The byte array to read the specified number - * of bytes into. - * @param offs The index in the array where the first byte - * read should be stored. - * @param len the number of bytes to read. - * - * @exception BitstreamException is thrown if the specified - * number of bytes could not be read from the stream. - */ - private int readFully(byte[] b, int offs, int len) - throws BitstreamException - { - int nRead = 0; - try - { - while (len > 0) - { - int bytesread = source.read(b, offs, len); - if (bytesread == -1) - { - while (len-->0) - { - b[offs++] = 0; - } - break; - //throw newBitstreamException(UNEXPECTED_EOF, new EOFException()); - } - nRead = nRead + bytesread; - offs += bytesread; - len -= bytesread; - } - } - catch (IOException ex) - { - throw newBitstreamException(STREAM_ERROR, ex); - } - return nRead; - } - - /** - * Simlar to readFully, but doesn't throw exception when - * EOF is reached. - */ - private int readBytes(byte[] b, int offs, int len) - throws BitstreamException - { - int totalBytesRead = 0; - try - { - while (len > 0) - { - int bytesread = source.read(b, offs, len); - if (bytesread == -1) - { - break; - } - totalBytesRead += bytesread; - offs += bytesread; - len -= bytesread; - } - } - catch (IOException ex) - { - throw newBitstreamException(STREAM_ERROR, ex); - } - return totalBytesRead; - } -} +/* + * 11/19/04 1.0 moved to LGPL. + * + * 11/17/04 Uncomplete frames discarded. 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 + * + * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net + * + * 04/14/97 : Added function prototypes for new syncing and seeking + * mechanisms. Also made this file portable. Changes made by Jeff Tsay + * + * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34 + * @(#) 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. + *---------------------------------------------------------------------- + */ + + +/** + * The Bistream class is responsible for parsing + * an MPEG audio bitstream. + * + * REVIEW: much of the parsing currently occurs in the + * various decoders. This should be moved into this class and associated + * inner classes. + */ +@LATTICE("FBframebuffer where the next bits are + * retrieved. + */ + @LOC("WP") private int wordpointer; + + /** + * Number (0-31, from MSB to LSB) of next bit for get_bits() + */ + @LOC("BI") private int bitindex; + + /** + * The current specified syncword + */ + @LOC("F") private int syncword; + + /** + * Audio header position in stream. + */ + @LOC("F")private int header_pos = 0; + + /** + * + */ + @LOC("F") private boolean single_ch_mode; + //private int current_frame_number; + //private int last_frame_number; + + @LOC("F") private final int bitmask[] = {0, // dummy + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, + 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, + 0x0001FFFF }; + + @LOC("F") private final PushbackInputStream source; + + @LOC("F") private final Header header = new Header(); + + @LOC("F") private final byte syncbuf[] = new byte[4]; + + @LOC("F") private Crc16[] crc = new Crc16[1]; + + @LOC("F") private byte[] rawid3v2 = null; + + @LOC("FF") private boolean firstframe = true; + + + /** + * Construct a IBitstream that reads data from a + * given InputStream. + * + * @param in The InputStream to read from. + */ + public Bitstream(InputStream in) + { + if (in==null) throw new NullPointerException("in"); + in = new BufferedInputStream(in); + loadID3v2(in); + firstframe = true; + //source = new PushbackInputStream(in, 1024); + source = new PushbackInputStream(in, BUFFER_INT_SIZE*4); + + closeFrame(); + //current_frame_number = -1; + //last_frame_number = -1; + } + + /** + * Return position of the first audio header. + * @return size of ID3v2 tag frames. + */ + public int header_pos() + { + return header_pos; + } + + /** + * Load ID3v2 frames. + * @param in MP3 InputStream. + * @author JavaZOOM + */ + private void loadID3v2(InputStream in) + { + int size = -1; + try + { + // Read ID3v2 header (10 bytes). + in.mark(10); + size = readID3v2Header(in); + header_pos = size; + } + catch (IOException e) + {} + finally + { + try + { + // Unread ID3v2 header (10 bytes). + in.reset(); + } + catch (IOException e) + {} + } + // Load ID3v2 tags. + try + { + if (size > 0) + { + rawid3v2 = new byte[size]; + in.read(rawid3v2,0,rawid3v2.length); + } + } + catch (IOException e) + {} + } + + /** + * Parse ID3v2 tag header to find out size of ID3v2 frames. + * @param in MP3 InputStream + * @return size of ID3v2 frames + header + * @throws IOException + * @author JavaZOOM + */ + private int readID3v2Header(InputStream in) throws IOException + { + byte[] id3header = new byte[4]; + int size = -10; + in.read(id3header,0,3); + // Look for ID3v2 + if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3')) + { + in.read(id3header,0,3); + int majorVersion = id3header[0]; + int revision = id3header[1]; + in.read(id3header,0,4); + size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]); + } + return (size+10); + } + + /** + * Return raw ID3v2 frames + header. + * @return ID3v2 InputStream or null if ID3v2 frames are not available. + */ + public InputStream getRawID3v2() + { + if (rawid3v2 == null) return null; + else + { + ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2); + return bain; + } + } + + /** + * Close the Bitstream. + * @throws BitstreamException + */ + public void close() throws BitstreamException + { + try + { + source.close(); + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + } + + /** + * Reads and parses the next frame from the input source. + * @return the Header describing details of the frame read, + * or null if the end of the stream has been reached. + */ + public Header readFrame() throws BitstreamException + { + Header result = null; + try + { + result = readNextFrame(); + // E.B, Parse VBR (if any) first frame. + if (firstframe == true) + { + result.parseVBR(frame_bytes); + firstframe = false; + } + } + catch (BitstreamException ex) + { + if ((ex.getErrorCode()==INVALIDFRAME)) + { + // Try to skip this frame. + //System.out.println("INVALIDFRAME"); + try + { + closeFrame(); + result = readNextFrame(); + } + catch (BitstreamException e) + { + if ((e.getErrorCode()!=STREAM_EOF)) + { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(e.getErrorCode(), e); + } + } + } + else if ((ex.getErrorCode()!=STREAM_EOF)) + { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(ex.getErrorCode(), ex); + } + } + return result; + } + + /** + * Read next MP3 frame. + * @return MP3 frame header. + * @throws BitstreamException + */ + private Header readNextFrame() throws BitstreamException + { + if (framesize == -1) + { + nextFrame(); + } + return header; + } + + + /** + * Read next MP3 frame. + * @throws BitstreamException + */ + private void nextFrame() throws BitstreamException + { + // entire frame is read by the header class. + header.read_header(this, crc); + } + + /** + * Unreads the bytes read from the frame. + * @throws BitstreamException + */ + // REVIEW: add new error codes for this. + public void unreadFrame() throws BitstreamException + { + if (wordpointer==-1 && bitindex==-1 && (framesize>0)) + { + try + { + source.unread(frame_bytes, 0, framesize); + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR); + } + } + } + + /** + * Close MP3 frame. + */ + public void closeFrame() + { + framesize = -1; + wordpointer = -1; + bitindex = -1; + } + + /** + * Determines if the next 4 bytes of the stream represent a + * frame header. + */ + public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException + { + int read = readBytes(syncbuf, 0, 4); + int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF); + + try + { + source.unread(syncbuf, 0, read); + } + catch (IOException ex) + { + } + + boolean sync = false; + switch (read) + { + case 0: + sync = true; + break; + case 4: + sync = isSyncMark(headerstring, syncmode, syncword); + break; + } + + return sync; + } + + + // REVIEW: this class should provide inner classes to + // parse the frame contents. Eventually, readBits will + // be removed. + public int readBits(int n) + { + return get_bits(n); + } + + public int readCheckedBits(int n) + { + // REVIEW: implement CRC check. + return get_bits(n); + } + + protected BitstreamException newBitstreamException(int errorcode) + { + return new BitstreamException(errorcode, null); + } + protected BitstreamException newBitstreamException(int errorcode, Throwable throwable) + { + return new BitstreamException(errorcode, throwable); + } + + /** + * Get next 32 bits from bitstream. + * They are stored in the headerstring. + * syncmod allows Synchro flag ID + * The returned value is False at the end of stream. + */ + + int syncHeader(byte syncmode) throws BitstreamException + { + boolean sync; + int headerstring; + // read additional 2 bytes + int bytesRead = readBytes(syncbuf, 0, 3); + + if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null); + + headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF); + + do + { + headerstring <<= 8; + + if (readBytes(syncbuf, 3, 1)!=1) + throw newBitstreamException(STREAM_EOF, null); + + headerstring |= (syncbuf[3] & 0x000000FF); + + sync = isSyncMark(headerstring, syncmode, syncword); + } + while (!sync); + + //current_frame_number++; + //if (last_frame_number < current_frame_number) last_frame_number = current_frame_number; + + return headerstring; + } + + public boolean isSyncMark(int headerstring, int syncmode, int word) + { + boolean sync = false; + + if (syncmode == INITIAL_SYNC) + { + //sync = ((headerstring & 0xFFF00000) == 0xFFF00000); + sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5 + } + else + { + sync = ((headerstring & 0xFFF80C00) == word) && + (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode); + } + + // filter out invalid sample rate + if (sync) + sync = (((headerstring >>> 10) & 3)!=3); + // filter out invalid layer + if (sync) + sync = (((headerstring >>> 17) & 3)!=0); + // filter out invalid version + if (sync) + sync = (((headerstring >>> 19) & 3)!=1); + + return sync; + } + + /** + * Reads the data for the next frame. The frame is not parsed + * until parse frame is called. + */ + int read_frame_data(int bytesize) throws BitstreamException + { + int numread = 0; + numread = readFully(frame_bytes, 0, bytesize); + framesize = bytesize; + wordpointer = -1; + bitindex = -1; + return numread; + } + + /** + * Parses the data previously read with read_frame_data(). + */ + @LATTICE("GLOBAL>> (32 - sum)) & bitmask[number_of_bits]; + // returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits]; + if ((bitindex += number_of_bits) == 32) + { + bitindex = 0; + wordpointer++; // added by me! + } + return returnvalue; + } + + // E.B : Check that ? + //((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0]; + //wordpointer++; // Added by me! + //((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0]; + @LOC("RL") int Right = (framebuffer[wordpointer] & 0x0000FFFF); + wordpointer++; + @LOC("RL") int Left = (framebuffer[wordpointer] & 0xFFFF0000); + returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF); + + returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 - bitindex)) + returnvalue &= bitmask[number_of_bits]; + bitindex = sum - 32; + return returnvalue; +} + + /** + * Set the word we want to sync the header to. + * In Big-Endian byte order + */ + void set_syncword(@LOC("IN") int syncword0) + { + syncword = syncword0 & 0xFFFFFF3F; + single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0); + } + /** + * Reads the exact number of bytes from the source + * input stream into a byte array. + * + * @param b The byte array to read the specified number + * of bytes into. + * @param offs The index in the array where the first byte + * read should be stored. + * @param len the number of bytes to read. + * + * @exception BitstreamException is thrown if the specified + * number of bytes could not be read from the stream. + */ + @LATTICE("OUT 0) + { + @LOC("IN") int bytesread = source.read(b, offs, len); + if (bytesread == -1) + { + while (len-->0) + { + b[offs++] = 0; + } + break; + //throw newBitstreamException(UNEXPECTED_EOF, new EOFException()); + } + nRead = nRead + bytesread; + offs += bytesread; + len -= bytesread; + } + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + return nRead; + } + + /** + * Simlar to readFully, but doesn't throw exception when + * EOF is reached. + */ + @LATTICE("OUT 0) + { + @LOC("IN") int bytesread = source.read(b, offs, len); + if (bytesread == -1) + { + break; + } + totalBytesRead += bytesread; + offs += bytesread; + len -= bytesread; + } + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + return totalBytesRead; + } +} -- 2.34.1