/* * $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:31 jarnbjo * no message * * Revision 1.2 2003/03/16 01:11:39 jarnbjo * no message * * Revision 1.1 2003/03/03 21:02:20 jarnbjo * no message * */ package de.jarnbjo.util.io; import java.io.IOException; /** * Implementation of the BitInputStream interface, * using a byte array as data source. */ public class ByteArrayBitInputStream implements BitInputStream { private byte[] source; private byte currentByte; private int endian; private int byteIndex=0; private int bitIndex=0; public ByteArrayBitInputStream(byte[] source) { this(source, LITTLE_ENDIAN); } public ByteArrayBitInputStream(byte[] source, int endian) { this.endian=endian; this.source=source; currentByte=source[0]; bitIndex=(endian==LITTLE_ENDIAN)?0:7; } public boolean getBit() throws IOException { if(endian==LITTLE_ENDIAN) { if(bitIndex>7) { bitIndex=0; currentByte=source[++byteIndex]; } return (currentByte&(1<<(bitIndex++)))!=0; } else { if(bitIndex<0) { bitIndex=7; currentByte=source[++byteIndex]; } return (currentByte&(1<<(bitIndex--)))!=0; } } public int getInt(int bits) throws IOException { if(bits>32) { throw new IllegalArgumentException("Argument \"bits\" must be <= 32"); } int res=0; if(endian==LITTLE_ENDIAN) { for(int i=0; i>offset; bitIndex-=bits; } else { res=(((int)currentByte)&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1); bits-=bitIndex+1; currentByte=source[++byteIndex]; while(bits>=8) { bits-=8; res|=(((int)source[byteIndex])&0xff)<0) { int ci=((int)source[byteIndex])&0xff; res|=(ci>>(8-bits))&((1<=1<<(bits-1)) { raw-=1<7) { bitIndex=0; currentByte=source[++byteIndex]; } root=(currentByte&(1<<(bitIndex++)))!=0?root.o1:root.o0; } return root.value.intValue(); } public long getLong(int bits) throws IOException { if(bits>64) { throw new IllegalArgumentException("Argument \"bits\" must be <= 64"); } long res=0; if(endian==LITTLE_ENDIAN) { for(int i=0; i=0; i--) { if(getBit()) { res|=(1L<reads an integer encoded as "signed rice" as described in * the FLAC audio format specification

* *

not supported for little endian

* * @param order * @return the decoded integer value read from the stream * * @throws IOException if an I/O error occurs * @throws UnsupportedOperationException if the method is not supported by the implementation */ public int readSignedRice(int order) throws IOException { int msbs=-1, lsbs=0, res=0; if(endian==LITTLE_ENDIAN) { // little endian throw new UnsupportedOperationException("ByteArrayBitInputStream.readSignedRice() is only supported in big endian mode"); } else { // big endian byte cb=source[byteIndex]; do { msbs++; if(bitIndex<0) { bitIndex=7; byteIndex++; cb=source[byteIndex]; } } while((cb&(1<>offset; bitIndex-=bits; } else { lsbs=(((int)source[byteIndex])&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1); bits-=bitIndex+1; byteIndex++; while(bits>=8) { bits-=8; lsbs|=(((int)source[byteIndex])&0xff)<0) { int ci=((int)source[byteIndex])&0xff; lsbs|=(ci>>(8-bits))&((1<>1)-1:(res>>1); } /** *

fills the array from offset with len * integers encoded as "signed rice" as described in * the FLAC audio format specification

* *

not supported for little endian

* * @param order * @param buffer * @param offset * @param len * @return the decoded integer value read from the stream * * @throws IOException if an I/O error occurs * @throws UnsupportedOperationException if the method is not supported by the implementation */ public void readSignedRice(int order, int[] buffer, int off, int len) throws IOException { if(endian==LITTLE_ENDIAN) { // little endian throw new UnsupportedOperationException("ByteArrayBitInputStream.readSignedRice() is only supported in big endian mode"); } else { // big endian for(int i=off; i>offset; bitIndex-=bits; } else { lsbs=(((int)source[byteIndex])&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1); bits-=bitIndex+1; byteIndex++; while(bits>=8) { bits-=8; lsbs|=(((int)source[byteIndex])&0xff)<0) { int ci=((int)source[byteIndex])&0xff; lsbs|=(ci>>(8-bits))&((1<>1)-1:(res>>1); } } } public void align() { if(endian==BIG_ENDIAN && bitIndex>=0) { bitIndex=7; byteIndex++; } else if(endian==LITTLE_ENDIAN && bitIndex<=7) { bitIndex=0; byteIndex++; } } public void setEndian(int endian) { if(this.endian==BIG_ENDIAN && endian==LITTLE_ENDIAN) { bitIndex=0; byteIndex++; } else if(this.endian==LITTLE_ENDIAN && endian==BIG_ENDIAN) { bitIndex=7; byteIndex++; } this.endian=endian; } /** * @return the byte array used as a source for this instance */ public byte[] getSource() { return source; } }